well, it compiles. fails on run, though

This commit is contained in:
🪞👃🪞 2025-01-18 16:32:04 +01:00
parent a362028ae7
commit d14d67172c
6 changed files with 96 additions and 185 deletions

View file

@ -3,33 +3,40 @@ use crate::*;
pub trait AtomInput: Input {
fn matches_atom (&self, token: &str) -> bool;
}
pub trait KeyMap {
pub trait KeyMap<'a> {
/// Try to find a command that matches the current input event.
fn command <S, C: AtomCommand<S>, I: AtomInput> (&self, state: &S, input: &I) -> Option<C>;
fn command <S, C: AtomCommand<'a, S>, I: AtomInput> (&'a self, state: &'a S, input: &'a I)
-> Option<C>;
}
impl KeyMap for TokenIter<'_> {
fn command <S, C: AtomCommand<S>, I: AtomInput> (&self, state: &S, input: &I) -> Option<C> {
for token in *self {
if let Value::Exp(0, iter) = token.value() {
if let Some((Token { value: Value::Sym(binding), .. }, _)) = iter.next() {
if input.matches_atom(binding) {
if let Some(command) = C::try_from_expr(state, iter.clone()) {
return Some(command)
}
impl<'a> KeyMap<'a> for TokenIter<'a> {
fn command <S, C: AtomCommand<'a, S>, I: AtomInput> (&'a self, state: &'a S, input: &'a I)
-> Option<C>
{
let iter = self.clone();
while let Some(next) = iter.next() {
match next {
(Token { value: Value::Exp(0, iter), .. }, _) => {
let next = iter.next();
match next {
Some((Token { value: Value::Sym(binding), .. }, _)) => {
if input.matches_atom(binding) {
if let Some(command) = C::try_from_expr(state, iter.clone()) {
return Some(command)
}
}
},
_ => panic!("invalid config (expected symbol)")
}
} else {
panic!("invalid config: {token:?}")
}
} else {
panic!("invalid config: {token:?}")
},
_ => panic!("invalid config (expected expression)")
}
}
None
}
}
/// A [Command] that can be constructed from a [Token].
pub trait AtomCommand<C>: TryFromAtom<C> + Command<C> {}
impl<C, T: TryFromAtom<C> + Command<C>> AtomCommand<C> for T {}
pub trait AtomCommand<'a, C>: TryFromAtom<'a, C> + Command<C> {}
impl<'a, C, T: TryFromAtom<'a, C> + Command<C>> AtomCommand<'a, C> for T {}
/** Implement `AtomCommand` for given `State` and `Command` */
#[macro_export] macro_rules! atom_command {
($Command:ty : |$state:ident:<$State:ident: $Trait:path>| { $((
@ -53,7 +60,7 @@ impl<C, T: TryFromAtom<C> + Command<C>> AtomCommand<C> for T {}
// bound command:
$command:expr
))* }) => {
impl<$State: $Trait> TryFromAtom<$State> for $Command {
impl<'a, $State: $Trait> TryFromAtom<'a, $State> for $Command {
fn try_from_expr ($state: &$State, iter: TokenIter) -> Option<Self> {
match $iter.next() {
$(Some((Token { value: Value::Key($key), .. }, _)) => {
@ -94,7 +101,7 @@ impl<C, T: TryFromAtom<C> + Command<C>> AtomCommand<C> for T {}
// bound command:
$command:expr
))* }) => {
impl TryFromAtom<$State> for $Command {
impl<'a> TryFromAtom<'a, $State> for $Command {
fn try_from_expr ($state: &$State, iter: TokenIter) -> Option<Self> {
match iter.next() {
$(Some((Token { value: Value::Key($key), .. }, _)) => {