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