mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 19:56:44 +01:00
dsl: use only Dsl trait
This commit is contained in:
parent
3bc739328e
commit
90f5699fff
11 changed files with 430 additions and 406 deletions
|
|
@ -1,55 +1,75 @@
|
|||
use crate::*;
|
||||
|
||||
/// Map EDN tokens to parameters of a given type for a given context
|
||||
/// TODO: Replace both [Context] and [TryFromDsl] with this trait
|
||||
/// which returns a [Result].
|
||||
/// 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> {
|
||||
Ok(None)
|
||||
fn take <'state, 'source> (
|
||||
&'state self,
|
||||
_: &mut TokenIter<'source>
|
||||
) -> Perhaps<U> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn take_or_fail <'state, 'source> (
|
||||
state: &'state Self, iter: &mut TokenIter<'source>
|
||||
&'state self,
|
||||
token: &mut TokenIter<'source>,
|
||||
error: impl Into<Box<dyn std::error::Error>>
|
||||
) -> Usually<U> {
|
||||
if let Some(value) = Self::take(state, iter)? {
|
||||
if let Some(value) = Dsl::<U>::take(self, token)? {
|
||||
Ok(value)
|
||||
} else {
|
||||
Result::Err("not found".into()) // TODO add info and error type
|
||||
Result::Err(error.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Map EDN tokens to parameters of a given type for a given context
|
||||
pub trait Context<'state, U>: Sized {
|
||||
fn get <'source> (&'state self, _iter: &mut TokenIter<'source>) -> Option<U> {
|
||||
None
|
||||
}
|
||||
//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<'state, T: Context<'state, U>, U> Context<'state, U> for &T {
|
||||
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<U> {
|
||||
(*self).get(iter)
|
||||
}
|
||||
}
|
||||
//impl<T, U: FromDsl<T>> Dsl<U> for T {
|
||||
//}
|
||||
|
||||
impl<'state, T: Context<'state, U>, U> Context<'state, U> for Option<T> {
|
||||
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<U> {
|
||||
self.as_ref().map(|s|s.get(iter)).flatten()
|
||||
pub trait FromDsl<'state, T>: Sized {
|
||||
fn take_from <'source: 'state> (
|
||||
state: &'state T,
|
||||
_token: &mut TokenIter<'source>
|
||||
) -> Perhaps<Self> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TryFromDsl<'state, T>: Sized {
|
||||
fn try_from_expr <'source: 'state> (
|
||||
_state: &'state T, _iter: &mut TokenIter<'source>
|
||||
) -> Option<Self> {
|
||||
None
|
||||
}
|
||||
fn try_from_atom <'source: 'state> (
|
||||
state: &'state T, value: Value<'source>
|
||||
) -> Option<Self> {
|
||||
if let Exp(0, mut iter) = value {
|
||||
return Self::try_from_expr(state, &mut iter)
|
||||
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())
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue