diff --git a/edn/src/token.rs b/edn/src/token.rs index 7a841ae4..93515d22 100644 --- a/edn/src/token.rs +++ b/edn/src/token.rs @@ -124,7 +124,7 @@ impl<'a> Token<'a> { d => Ok(Self { length: self.length + 1, depth: d - 1, ..self }) } } - pub const fn to_ref_atom (&'a self) -> Result, ParseError> { + pub const fn to_ref_atom (&'a self) -> Result { Ok(match self.kind { Nil => return Err(ParseError::Empty), Num => match to_number(self.slice()) { @@ -152,10 +152,9 @@ const fn to_digit (c: char) -> Result { _ => return Err(Unexpected(c)) }) } -pub trait Atom<'a>: Sized { +pub trait Atom: Sized { fn kind (&self) -> TokenKind; fn text (&self) -> &str; - fn read_all (source: &'a str) -> impl Iterator>; } #[derive(Clone, PartialEq)] pub enum RefAtom<'a> { Num(usize), @@ -191,25 +190,10 @@ impl<'a> RefAtom<'a> { pub fn to_arc_atom (&self) -> ArcAtom { todo!() } -} -impl<'a> Atom<'a> for RefAtom<'a> { - fn kind (&self) -> TokenKind { - match self { - Self::Num(_) => TokenKind::Num, - Self::Sym(_) => TokenKind::Sym, - Self::Key(_) => TokenKind::Key, - Self::Exp(_) => TokenKind::Exp, - } - } - fn text (&self) -> &str { - match self { - Self::Num(_)|Self::Exp(_) => "", - Self::Sym(s) => s, - Self::Key(k) => k, - } - } - fn read_all (source: &'a str) -> impl Iterator> { - TokenIterator::new(source).map(move |result: TokenResult<'a>|match result{ + pub fn read_all <'b: 'a> (source: &'b str) + -> impl Iterator, ParseError>> + 'b + { + TokenIterator::new(source).map(move |result|match result{ Err(e) => Err(e), Ok(token) => match token.kind { Nil => Err(ParseError::Empty), @@ -226,6 +210,23 @@ impl<'a> Atom<'a> for RefAtom<'a> { }) } } +impl<'a> Atom for RefAtom<'a> { + fn kind (&self) -> TokenKind { + match self { + Self::Num(_) => TokenKind::Num, + Self::Sym(_) => TokenKind::Sym, + Self::Key(_) => TokenKind::Key, + Self::Exp(_) => TokenKind::Exp, + } + } + fn text (&self) -> &str { + match self { + Self::Num(_)|Self::Exp(_) => "", + Self::Sym(s) => s, + Self::Key(k) => k, + } + } +} impl<'a> Debug for RefAtom<'a> { fn fmt (&self, f: &mut Formatter<'_>) -> Result<(), FormatError> { match self { @@ -242,23 +243,8 @@ impl<'a> Debug for RefAtom<'a> { Key(Arc), Exp(Vec), } -impl<'a> Atom<'a> for ArcAtom { - fn kind (&self) -> TokenKind { - match self { - Self::Num(_) => TokenKind::Num, - Self::Sym(_) => TokenKind::Sym, - Self::Key(_) => TokenKind::Key, - Self::Exp(_) => TokenKind::Exp, - } - } - fn text (&self) -> &str { - match self { - Self::Num(_)|Self::Exp(_) => "", - Self::Sym(s) => s.as_ref(), - Self::Key(k) => k.as_ref(), - } - } - fn read_all (source: &'a str) -> impl Iterator> { +impl ArcAtom { + pub fn read_all <'a> (source: &'a str) -> impl Iterator> + 'a { TokenIterator::new(source).map(move |result: TokenResult<'a>|match result{ Err(e) => Err(e), Ok(token) => match token.kind { @@ -281,6 +267,23 @@ impl<'a> Atom<'a> for ArcAtom { }) } } +impl<'a> Atom for ArcAtom { + fn kind (&self) -> TokenKind { + match self { + Self::Num(_) => TokenKind::Num, + Self::Sym(_) => TokenKind::Sym, + Self::Key(_) => TokenKind::Key, + Self::Exp(_) => TokenKind::Exp, + } + } + fn text (&self) -> &str { + match self { + Self::Num(_)|Self::Exp(_) => "", + Self::Sym(s) => s.as_ref(), + Self::Key(k) => k.as_ref(), + } + } +} impl<'a> Debug for ArcAtom { fn fmt (&self, f: &mut Formatter<'_>) -> Result<(), FormatError> { match self { @@ -303,26 +306,26 @@ impl<'a> Display for ArcAtom { } /// Map EDN tokens to parameters of a given type for a given context pub trait Context<'a, U>: Sized { - fn get (&'a self, _edn: &'a impl Atom<'a>) -> Option { + fn get (&'a self, _edn: &'a impl Atom) -> Option { None } - fn get_or_fail (&'a self, edn: &'a impl Atom<'a>) -> U { + fn get_or_fail (&'a self, edn: &'a impl Atom) -> U { self.get(edn).expect("no value") } } impl<'a, T: Context<'a, U>, U> Context<'a, U> for &T { - fn get (&'a self, edn: &'a impl Atom<'a>) -> Option { + fn get (&'a self, edn: &'a impl Atom) -> Option { (*self).get(edn) } - fn get_or_fail (&'a self, edn: &'a impl Atom<'a>) -> U { + fn get_or_fail (&'a self, edn: &'a impl Atom) -> U { (*self).get_or_fail(edn) } } impl<'a, T: Context<'a, U>, U> Context<'a, U> for Option { - fn get (&'a self, edn: &'a impl Atom<'a>) -> Option { + fn get (&'a self, edn: &'a impl Atom) -> Option { self.as_ref().map(|s|s.get(edn)).flatten() } - fn get_or_fail (&'a self, edn: &'a impl Atom<'a>) -> U { + fn get_or_fail (&'a self, edn: &'a impl Atom) -> U { self.as_ref().map(|s|s.get_or_fail(edn)).expect("no provider") } } @@ -331,7 +334,7 @@ impl<'a, T: Context<'a, U>, U> Context<'a, U> for Option { // Provide a value to the EDN template ($type:ty:|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { impl<'a> Context<'a, $type> for $State { - fn get (&'a $self, edn: &'a impl Atom<'a>) -> Option<$type> { + fn get (&'a $self, edn: &'a impl Atom) -> Option<$type> { use RefAtom::*; Some(match edn.to_ref() { $(Sym($pat) => $expr,)* _ => return None }) } @@ -340,7 +343,7 @@ impl<'a, T: Context<'a, U>, U> Context<'a, U> for Option { // Provide a value more generically ($lt:lifetime: $type:ty:|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { impl<$lt> Context<$lt, $type> for $State { - fn get (&$lt $self, edn: &$lt impl Atom<'a>) -> Option<$type> { + fn get (&$lt $self, edn: &$lt impl Atom) -> Option<$type> { use RefAtom::*; Some(match edn.to_ref() { $(Sym($pat) => $expr,)* _ => return None }) } @@ -354,7 +357,7 @@ impl<'a, T: Context<'a, U>, U> Context<'a, U> for Option { // Provide a value that may also be a numeric literal in the EDN, to a generic implementation. ($type:ty:|$self:ident:<$T:ident:$Trait:path>|{ $($pat:pat => $expr:expr),* $(,)? }) => { impl<'a, $T: $Trait> Context<'a, $type> for $T { - fn get (&'a $self, edn: &'a impl Atom<'a>) -> Option<$type> { + fn get (&'a $self, edn: &'a impl Atom) -> Option<$type> { use RefAtom::*; Some(match edn.to_ref() { $(Sym($pat) => $expr,)* Num(n) => n as $type, _ => return None }) } @@ -363,7 +366,7 @@ impl<'a, T: Context<'a, U>, U> Context<'a, U> for Option { // Provide a value that may also be a numeric literal in the EDN, to a concrete implementation. ($type:ty:|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { impl<'a> Context<'a, $type> for $State { - fn get (&'a $self, edn: &'a impl Atom<'a>) -> Option<$type> { + fn get (&'a $self, edn: &'a impl Atom) -> Option<$type> { use RefAtom::*; Some(match edn.to_ref() { $(Sym($pat) => $expr,)* Num(n) => n as $type, _ => return None }) } @@ -376,7 +379,7 @@ impl<'a, T: Context<'a, U>, U> Context<'a, U> for Option { #[macro_export] macro_rules! provide_content { (|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { impl<'a, E: Output> Context<'a, Box + 'a>> for $State { - fn get (&'a $self, edn: &'a impl Atom<'a>) -> Option + 'a>> { + fn get (&'a $self, edn: &'a impl Atom) -> Option + 'a>> { use RefAtom::*; Some(match edn.to_ref() { $(RefAtom::Sym($pat) => $expr),*, _ => return None }) } @@ -384,7 +387,7 @@ impl<'a, T: Context<'a, U>, U> Context<'a, U> for Option { }; ($Output:ty: |$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { impl<'a> Context<'a, Box + 'a>> for $State { - fn get (&'a $self, edn: &'a impl Atom<'a>) -> Option + 'a>> { + fn get (&'a $self, edn: &'a impl Atom) -> Option + 'a>> { use RefAtom::*; Some(match edn.to_ref() { $(Sym($pat) => $expr),*, _ => return None }) } @@ -392,11 +395,11 @@ impl<'a, T: Context<'a, U>, U> Context<'a, U> for Option { } } pub trait TryFromEdn<'a, T>: Sized { - fn try_from_edn (state: &'a T, head: &impl Atom<'a>, tail: &'a [impl Atom<'a>]) -> + fn try_from_edn (state: &'a T, head: &impl Atom, tail: &'a [impl Atom]) -> Option; } pub trait TryIntoEdn<'a, T>: Sized { - fn try_from_edn (state: &'a T, head: &impl Atom<'a>, tail: &'a [impl Atom<'a>]) -> + fn try_from_edn (state: &'a T, head: &impl Atom, tail: &'a [impl Atom]) -> Option; } diff --git a/input/src/keymap.rs b/input/src/keymap.rs index 260dfded..1bfdfd43 100644 --- a/input/src/keymap.rs +++ b/input/src/keymap.rs @@ -71,7 +71,7 @@ impl<'a> KeyMap for ArcKeyMap { /// [Input] state that can be matched against an [Atom]. pub trait EdnInput: Input { fn matches_edn (&self, token: &str) -> bool; - fn get_event <'a> (_: &impl Atom<'a>) -> Option { + fn get_event <'a> (_: &impl Atom) -> Option { None } } @@ -79,8 +79,8 @@ pub trait EdnInput: Input { pub trait EdnCommand: Command { fn from_edn <'a> ( state: &C, - head: &impl Atom<'a>, - tail: &'a [impl Atom<'a>] + head: &impl Atom, + tail: &'a [impl Atom] ) -> Option; } /** Implement `EdnCommand` for given `State` and `Command` */ diff --git a/output/src/view.rs b/output/src/view.rs index fd9c8a0e..809702e8 100644 --- a/output/src/view.rs +++ b/output/src/view.rs @@ -14,7 +14,7 @@ use std::{sync::Arc, marker::PhantomData}; } $( impl<'a> Context<'a, $type> for $App { - fn get (&'a $self, edn: &'a impl Atom<'a>) -> Option<$type> { + fn get (&'a $self, edn: &'a impl Atom) -> Option<$type> { Some(match edn.to_ref() { $(Atom::Sym($sym) => $value,)* _ => return None }) } } @@ -25,7 +25,7 @@ use std::{sync::Arc, marker::PhantomData}; #[macro_export] macro_rules! provide_content { (|$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { impl<'a, E: Output> Context<'a, Box + 'a>> for $State { - fn get (&'a $self, edn: &'a impl Atom<'a>) -> Option + 'a>> { + fn get (&'a $self, edn: &'a impl Atom) -> Option + 'a>> { Some(match edn.to_ref() { $(Atom::Sym($pat) => $expr),*, _ => return None @@ -35,7 +35,7 @@ use std::{sync::Arc, marker::PhantomData}; }; ($Output:ty: |$self:ident:$State:ty|{ $($pat:pat => $expr:expr),* $(,)? }) => { impl<'a> Context<'a, Box + 'a>> for $State { - fn get (&'a $self, edn: &'a impl Atom<'a>) -> Option + 'a>> { + fn get (&'a $self, edn: &'a impl Atom) -> Option + 'a>> { Some(match edn.to_ref() { $(Atom::Sym($pat) => $expr),*, _ => return None @@ -78,7 +78,7 @@ impl<'a, E: Output, T: ViewContext<'a, E> + std::fmt::Debug> EdnView<'a, E, T> { Err(error) => Self::Err(format!("{error} in {source}")) } } - pub fn from_items (state: T, items: Vec>) -> Self { + pub fn from_items (state: T, items: Vec) -> Self { Self::Ok(state, Atom::Exp(items).to_arc()) } } @@ -112,7 +112,7 @@ pub trait ViewContext<'a, E: Output>: Context<'a, E::Unit> + Context<'a, Box + 'a>> { - fn get_bool (&'a self, item: &'a impl Atom<'a>) -> Option { + fn get_bool (&'a self, item: &'a impl Atom) -> Option { Some(match &item { Sym(s) => match s.as_ref() { ":false" | ":f" => false, @@ -124,13 +124,13 @@ pub trait ViewContext<'a, E: Output>: _ => return Context::get(self, item) }) } - fn get_usize (&'a self, item: &'a impl Atom<'a>) -> Option { + fn get_usize (&'a self, item: &'a impl Atom) -> Option { Some(match &item { Num(n) => *n, _ => return Context::get(self, item) }) } - fn get_unit (&'a self, item: &'a impl Atom<'a>) -> Option { + fn get_unit (&'a self, item: &'a impl Atom) -> Option { Some(match &item { Num(n) => (*n as u16).into(), _ => return Context::get(self, item) }) } - fn get_content (&'a self, item: &'a impl Atom<'a>) -> Option + 'a>> where E: 'a { + fn get_content (&'a self, item: &'a impl Atom) -> Option + 'a>> where E: 'a { Some(match item { Nil => Box::new(()), Exp(ref e) => {