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: Sized { fn take <'state, 'source> ( &'state self, _: &mut TokenIter<'source> ) -> Perhaps { unimplemented!() } fn take_or_fail <'state, 'source> ( &'state self, token: &mut TokenIter<'source>, error: impl Into> ) -> Usually { if let Some(value) = Dsl::::take(self, token)? { Ok(value) } else { Result::Err(error.into()) } } } //impl, U> Dsl for &T { //fn take <'state, 'source> (&'state self, iter: &mut TokenIter<'source>) -> Perhaps { //(*self).take(iter) //} //} //impl, U> Dsl for Option { //fn take <'state, 'source> (&'state self, iter: &mut TokenIter<'source>) -> Perhaps { //Ok(self.as_ref().map(|s|s.take(iter)).transpose()?.flatten()) //} //} impl<'state, X, Y> Dsl for Y where Y: FromDsl<'state, X> { } //impl> Dsl for T { //} pub trait FromDsl<'state, T>: Sized { fn take_from <'source: 'state> ( state: &'state T, _token: &mut TokenIter<'source> ) -> Perhaps { unimplemented!() } fn take_from_or_fail <'source: 'state> ( state: &'state T, token: &mut TokenIter<'source>, error: impl Into> ) -> Usually { if let Some(value) = FromDsl::::take_from(state, token)? { Ok(value) } else { Result::Err(error.into()) } } }