parent
9a346f4d0c
commit
9ecb74d896
@ -0,0 +1,139 @@
|
||||
use super::*;
|
||||
|
||||
/// A trait used to validate atoms in the `uv` module to valid ones in this module.
|
||||
trait Validate: Sized
|
||||
{
|
||||
type Valid: Into<Inner>;
|
||||
type Error: Into<eyre::Report> = eyre::Report;
|
||||
|
||||
/// Consume into the strongly validated type.
|
||||
fn valiate(self) -> Result<Self::Valid, Self::Error>;
|
||||
|
||||
/// Weakly validate that this instance itself is correct.
|
||||
fn self_validate(&self) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
/// Non-validated inputs which get mapped to the validated ones in the parent module.
|
||||
mod uv {
|
||||
use crate::*;
|
||||
use super::Validate;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExecTaskAtom
|
||||
{
|
||||
prog: Option<String>,
|
||||
args: Option<Vec<String>>,
|
||||
//TODO: ...
|
||||
|
||||
takes_tail: Option<super::TailKind>,
|
||||
}
|
||||
|
||||
impl Validate for ExecTaskAtom
|
||||
{
|
||||
type Valid = super::ExecTaskAtom;
|
||||
|
||||
fn valiate(self) -> Result<Self::Valid, Self::Error>
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn self_validate(&self) -> Result<(), Self::Error>
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Either
|
||||
{
|
||||
Exec(ExecTaskAtom),
|
||||
Shell(!), //TODO
|
||||
}
|
||||
|
||||
//TODO: impl Validate for Either, or something
|
||||
|
||||
/// Validate an atom from this module into `Inner`.
|
||||
pub(super) fn validate<T>(inv: T) -> eyre::Result<super::Inner>
|
||||
where T: Validate
|
||||
{
|
||||
Ok(inv.valiate().map_err(Into::into)
|
||||
.wrap_err(eyre!("Failed to validate atom"))
|
||||
.with_section(|| std::any::type_name::<T>().header("Type name was"))
|
||||
.with_section(|| std::any::type_name::<T::Valid>().header("Validating for"))?.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for a normal execution atom
|
||||
struct ExecTaskAtom
|
||||
{
|
||||
prog: String,
|
||||
args: Vec<String>,
|
||||
//TODO: ...
|
||||
|
||||
takes_tail: TailKind,
|
||||
}
|
||||
|
||||
enum Inner
|
||||
{
|
||||
Exec(ExecTaskAtom),
|
||||
Shell(!), //TODO
|
||||
}
|
||||
|
||||
impl From<ExecTaskAtom> for Inner
|
||||
{
|
||||
#[inline] fn from(from: ExecTaskAtom) -> Self
|
||||
{
|
||||
Self::Exec(from)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum TailKind
|
||||
{
|
||||
/// No tail parsing
|
||||
Contained,
|
||||
/// Parse rest of arguments
|
||||
Rest(TailField),
|
||||
/// Parse concurrently from stdin
|
||||
Stdin(TailField),
|
||||
}
|
||||
|
||||
impl Default for TailKind
|
||||
{
|
||||
#[inline]
|
||||
fn default() -> Self
|
||||
{
|
||||
Self::Contained
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum TailField
|
||||
{
|
||||
//TODO: All possible tail fields for all exec atom types. Validating they are used for the correct atom type will be done in `uv`'s validate step.
|
||||
}
|
||||
|
||||
/// The defaults specified for execution types
|
||||
pub struct TaskDefault(Box<(uv::ExecTaskAtom, ! /* TODO: ShellTaskAtom */)>);
|
||||
|
||||
/// A task atom is task-specific execution directives.
|
||||
///
|
||||
/// An atom can inherit from a `TaskDefault`.
|
||||
pub struct TaskAtom(Box<Inner>); //TODO: how tf are we going to signal tail feeding? Do we just tag which field it is and let the program figure out how to handle it? I think that might be best, esp. for stdin for which reading happens concurrently.
|
||||
|
||||
impl TaskAtom
|
||||
{
|
||||
fn inherit(default: &TaskDefault, from: uv::Either) -> eyre::Result<Self>
|
||||
{
|
||||
//TODO: Clone default.0.<n>, replacing the *set* (not `None`) fields set in `from` then validate it into `Self`
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Does this atom take tail parsing? And if so, which field?
|
||||
pub fn tail(&self) -> &TailKind
|
||||
{
|
||||
match self.0.as_ref() {
|
||||
Inner::Exec(e) => &e.takes_tail,
|
||||
_ => todo!()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue