mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-08 04:36:49 +01:00
55 lines
1.6 KiB
Rust
55 lines
1.6 KiB
Rust
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].
|
|
pub trait Dsl<U>: Sized {
|
|
fn take <'state, 'source> (_: &'state Self, _: &mut TokenIter<'source>) -> Perhaps<U> {
|
|
Ok(None)
|
|
}
|
|
fn take_or_fail <'state, 'source> (
|
|
state: &'state Self, iter: &mut TokenIter<'source>
|
|
) -> Usually<U> {
|
|
if let Some(value) = Self::take(state, iter)? {
|
|
Ok(value)
|
|
} else {
|
|
Result::Err("not found".into()) // TODO add info and error type
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 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<'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<'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 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)
|
|
}
|
|
None
|
|
}
|
|
}
|
|
|