pub mod balance;
pub mod create;
pub mod deliver;
pub mod parse;
pub mod pay;
pub mod prelude;
use std::fmt;
pub use balance::Balance;
pub use create::{CreateConcept, CreateEntity, CreateObject};
pub use deliver::Deliver;
pub use pay::Pay;
use prelude::*;
pub type Error = error::Construction;
pub type Output = Option<Box<dyn fmt::Display>>;
pub trait Command: Run + Emerge<Self::Args, Error> + Sized {
type Args: for<'code> Emerge<ast::Stmt<'code>, Error>;
fn boxed(self) -> Box<dyn Run>
where
Self: 'static,
{
Box::new(self)
}
}
impl<T: Run, E> Resolve<T, E> for T {
fn resolve(self, _: &State) -> Result<Self, E> {
Ok(self)
}
}
pub trait Run {
fn run(self: Box<Self>, ctx: &mut State) -> Output;
}
pub fn construct(src: ast::Stmt<'_>, ctx: &State) -> Result<Box<dyn Run>, error::Construction> {
use ast::Command as C;
macro_rules! forward {
($cmd:ty, $src:expr, $ctx:expr) => {{
let args = <$cmd as Command>::Args::emerge($src, $ctx)?;
<$cmd>::emerge(args, $ctx).map(|c| Box::new(c) as Box<dyn Run>)
}};
}
match src.cmd {
C::Create(Actor::Entity) => forward!(CreateEntity, src, ctx),
C::Create(Actor::Concept) => forward!(CreateConcept, src, ctx),
C::Create(Actor::Object) => forward!(CreateObject, src, ctx),
C::Pay => forward!(Pay, src, ctx),
C::Balance => forward!(Balance, src, ctx),
C::Deliver => forward!(Deliver, src, ctx),
}
}