use crate::*; #[macro_export] macro_rules! defcom { ([$self:ident, $app:ident:$App:ty] $(($Command:ident $(( $Variant:ident [$($($param:ident: $Param:ty),+)?] $expr:expr ))*))*) => { $(#[derive(Clone, Debug)] pub enum $Command { $($Variant $(($($Param),+))?),* })* $(command!(|$self: $Command, $app: $App|match $self { $($Command::$Variant $(($($param),+))? => $expr),* });)* }; (|$self:ident, $app:ident:$App:ty| $($Command:ident { $( $Variant:ident $(($($param:ident: $Param:ty),+))? => $expr:expr )* $(,)? })*) => { $(#[derive(Clone, Debug)] pub enum $Command { $($Variant $(($($Param),+))?),* })* $(command!(|$self: $Command, $app: $App|match $self { $($Command::$Variant $(($($param),+))? => $expr),* });)* }; } #[macro_export] macro_rules! command { ($(<$($l:lifetime),+>)?|$self:ident:$Command:ty,$state:ident:$State:ty|$handler:expr) => { impl$(<$($l),+>)? Command<$State> for $Command { fn execute ($self, $state: &mut $State) -> Perhaps { Ok($handler) } } }; } pub trait Command: Send + Sync + Sized { fn execute (self, state: &mut S) -> Perhaps; fn delegate (self, state: &mut S, wrap: impl Fn(Self)->T) -> Perhaps where Self: Sized { Ok(self.execute(state)?.map(wrap)) } } impl> Command for Option { fn execute (self, _: &mut S) -> Perhaps { Ok(None) } fn delegate (self, _: &mut S, _: impl Fn(Self)->U) -> Perhaps where Self: Sized { Ok(None) } }