mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
45 lines
1.6 KiB
Rust
45 lines
1.6 KiB
Rust
use crate::*;
|
|
pub trait Command<S>: Send + Sync + Sized {
|
|
fn execute (self, state: &mut S) -> Perhaps<Self>;
|
|
fn delegate <T> (self, state: &mut S, wrap: impl Fn(Self)->T) -> Perhaps<T> {
|
|
Ok(self.execute(state)?.map(wrap))
|
|
}
|
|
}
|
|
#[macro_export] macro_rules! input_to_command {
|
|
(<$($l:lifetime),+> $Command:ty: |$state:ident:$State:ty, $input:ident:$Input:ty| $handler:expr) => {
|
|
impl<$($l),+> InputToCommand<$Input, $State> for $Command {
|
|
fn input_to_command ($state: &$State, $input: &$Input) -> Option<Self> {
|
|
Some($handler)
|
|
}
|
|
}
|
|
};
|
|
($Command:ty: |$state:ident:$State:ty, $input:ident:$Input:ty| $handler:expr) => {
|
|
impl InputToCommand<$Input, $State> for $Command {
|
|
fn input_to_command ($state: &$State, $input: &$Input) -> Option<Self> {
|
|
Some($handler)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub trait InputToCommand<I, S>: Command<S> + Sized {
|
|
fn input_to_command (state: &S, input: &I) -> Option<Self>;
|
|
fn execute_with_state (state: &mut S, input: &I) -> Perhaps<bool> {
|
|
Ok(if let Some(command) = Self::input_to_command(state, input) {
|
|
let _undo = command.execute(state)?;
|
|
Some(true)
|
|
} else {
|
|
None
|
|
})
|
|
}
|
|
}
|
|
|
|
#[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<Self> {
|
|
Ok($handler)
|
|
}
|
|
}
|
|
};
|
|
}
|