wip: start replacing EdnViewData with EdnProvide

This commit is contained in:
🪞👃🪞 2025-01-12 15:26:37 +01:00
parent fc06fb863b
commit 1ff35baea9
8 changed files with 151 additions and 113 deletions

View file

@ -2,21 +2,51 @@ use crate::*;
use EdnItem::*;
#[macro_export] macro_rules! edn_command {
($Command:ty : |$state:ident:$State:ty| {
$(($key:literal [$($arg:ident : $type:ty),*] $command:expr))*
}) => {
($Command:ty : |$state:ident:$State:ty| { $((
// identifier
$key:literal [
// named parameters
$(
// argument name
$arg:ident
// if type is not provided defaults to EdnItem
$(
// type:name separator
:
// argument type
$type:ty
)?
),*
// rest of parameters
$(, ..$rest:ident)?
]
// bound command:
$command:expr
))* }) => {
impl EdnCommand<$State> for $Command {
fn from_edn <'a> ($state: &$State, head: &EdnItem<&str>, tail: &'a [EdnItem<String>]) -> Self {
match (head, tail) {
$((EdnItem::Key($key), [$($arg),*]) => {
$(let $arg: $type = EdnProvide::<$type>::get_or_fail($state, $arg);)*
$command
},)*
_ => panic!("no such command")
}
$(if let (EdnItem::Key($key), [ // if the identifier matches
// bind argument ids
$($arg),*
// bind rest parameters
$(, $rest @ ..)?
]) = (head, tail) {
$(
$(let $arg: Option<$type> = EdnProvide::<$type>::get($state, $arg);)?
)*
//$(edn_command!(@bind $state => $arg $(?)? : $type);)*
return $command
})*
panic!("no such command")
}
}
}
};
(@bind $state:ident =>$arg:ident ? : $type:ty) => {
let $arg: Option<$type> = EdnProvide::<$type>::get($state, $arg);
};
(@bind $state:ident => $arg:ident : $type:ty) => {
let $arg: $type = EdnProvide::<$type>::get_or_fail($state, $arg);
};
}
/// Turns an EDN symbol sequence into a command enum variant.

View file

@ -23,3 +23,12 @@ pub trait EdnProvide<U> {
self.get(edn).expect("no value")
}
}
impl<T: EdnProvide<U>, U> EdnProvide<U> for &T {
fn get <S: AsRef<str>> (&self, edn: &EdnItem<S>) -> Option<U> {
(*self).get(edn)
}
fn get_or_fail <S: AsRef<str>> (&self, edn: &EdnItem<S>) -> U {
(*self).get_or_fail(edn)
}
}