use crate::*; pub trait Dsl { fn take <'source> (&self, words: &mut TokenIter<'source>) -> Perhaps; fn take_or_fail <'source, E: Into>, F: Fn()->E> ( &self, words: &mut TokenIter<'source>, error: F ) -> Usually { if let Some(value) = Dsl::::take(self, words)? { Ok(value) } else { Result::Err(format!("{}: {:?}", error().into(), words.peek().map(|x|x.value)).into()) } } } impl, State> Dsl for State { fn take <'source> (&self, words: &mut TokenIter<'source>) -> Perhaps { Namespace::take_from(self, words) } } pub trait Namespace: Sized { fn take_from <'source> (state: &State, words: &mut TokenIter<'source>) -> Perhaps; fn take_from_or_fail <'source, E: Into>, F: Fn()->E> ( state: &State, words: &mut TokenIter<'source>, error: F ) -> Usually { if let Some(value) = Namespace::::take_from(state, words)? { Ok(value) } else { Result::Err(format!("{}: {:?}", error().into(), words.peek().map(|x|x.value)).into()) } } } //impl, T> Namespace for T { //fn take_from <'state, 'source: 'state> (state: &'state State, token: &mut TokenIter<'source>) //-> Perhaps //{ //Dsl::take(state, token) //} //} /// Implement the [Dsl] trait, which boils down to /// specifying two types and providing an expression. #[macro_export] macro_rules! from_dsl { (@a: $T:ty: |$state:ident, $words:ident|$expr:expr) => { impl, A> Namespace for $T { fn take_from <'source> ( $state: &State, $words: &mut TokenIter<'source>, ) -> Perhaps<$T> { $expr } } }; (@ab: $T:ty: |$state:ident, $words:ident|$expr:expr) => { impl + Dsl, A, B> Namespace for $T { fn take_from <'source> ( $state: &State, $words: &mut TokenIter<'source>, ) -> Perhaps<$T> { $expr } } }; ($T:ty: |$state:ident:$S:ty, $words:ident|$expr:expr) => { impl Namespace<$S> for $T { fn take_from <'source> ( $state: &$S, $words: &mut TokenIter<'source>, ) -> 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: Dsl<'state, X> { //} //impl> Dsl for T { //}