mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: start replacing EdnViewData with EdnProvide
This commit is contained in:
parent
fc06fb863b
commit
1ff35baea9
8 changed files with 151 additions and 113 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue