mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 11:46:42 +01:00
75 lines
2.1 KiB
Rust
75 lines
2.1 KiB
Rust
use crate::*;
|
|
|
|
/// Implement the [Dsl] trait, which boils down to
|
|
/// specifying two types and providing an expression.
|
|
#[macro_export] macro_rules! dsl {
|
|
($T:ty: |$self:ident:$S:ty, $iter:ident|$expr:expr) => {
|
|
impl ::tengri::dsl::Dsl<$T> for $S {
|
|
fn take <'state, 'source> (
|
|
&'state $self, $iter: &mut ::tengri::dsl::TokenIter<'source>,
|
|
) -> ::tengri::Perhaps<$T> {
|
|
$expr
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Maps a sequencer of EDN tokens to parameters of supported types
|
|
/// for a given context.
|
|
pub trait Dsl<U>: Sized {
|
|
fn take <'state, 'source> (
|
|
&'state self,
|
|
_: &mut TokenIter<'source>
|
|
) -> Perhaps<U> {
|
|
unimplemented!()
|
|
}
|
|
fn take_or_fail <'state, 'source> (
|
|
&'state self,
|
|
token: &mut TokenIter<'source>,
|
|
error: impl Into<Box<dyn std::error::Error>>
|
|
) -> Usually<U> {
|
|
if let Some(value) = Dsl::<U>::take(self, token)? {
|
|
Ok(value)
|
|
} else {
|
|
Result::Err(error.into())
|
|
}
|
|
}
|
|
}
|
|
|
|
//impl<T: Dsl<U>, U> Dsl<U> for &T {
|
|
//fn take <'state, 'source> (&'state self, iter: &mut TokenIter<'source>) -> Perhaps<U> {
|
|
//(*self).take(iter)
|
|
//}
|
|
//}
|
|
|
|
//impl<T: Dsl<U>, U> Dsl<U> for Option<T> {
|
|
//fn take <'state, 'source> (&'state self, iter: &mut TokenIter<'source>) -> Perhaps<U> {
|
|
//Ok(self.as_ref().map(|s|s.take(iter)).transpose()?.flatten())
|
|
//}
|
|
//}
|
|
|
|
impl<'state, X, Y> Dsl<X> for Y where Y: FromDsl<'state, X> {
|
|
}
|
|
|
|
//impl<T, U: FromDsl<T>> Dsl<U> for T {
|
|
//}
|
|
|
|
pub trait FromDsl<'state, T>: Sized {
|
|
fn take_from <'source: 'state> (
|
|
state: &'state T,
|
|
_token: &mut TokenIter<'source>
|
|
) -> Perhaps<Self> {
|
|
unimplemented!()
|
|
}
|
|
fn take_from_or_fail <'source: 'state> (
|
|
state: &'state T,
|
|
token: &mut TokenIter<'source>,
|
|
error: impl Into<Box<dyn std::error::Error>>
|
|
) -> Usually<Self> {
|
|
if let Some(value) = FromDsl::<T>::take_from(state, token)? {
|
|
Ok(value)
|
|
} else {
|
|
Result::Err(error.into())
|
|
}
|
|
}
|
|
}
|