use std::cell::RefCell; use std::rc::Rc; use nom::branch::alt; use nom::combinator::not; use nom::error::VerboseError; use nom::IResult; use nom::Parser; type Link<'r, T> = Option<&'r Node<'r, T>>; type Matcher = dyn for<'s> Fn(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>; pub type OrgModeContext<'r> = ContextTree<'r, ContextElement<'r>>; struct Node<'r, T> { elem: T, next: Link<'r, T>, } pub struct ContextTree<'r, T> { head: Option>, } impl<'r, T> ContextTree<'r, T> { pub fn new() -> Self { ContextTree { head: None } } pub fn with_additional_node(&'r self, element: T) -> ContextTree<'r, T> { let new_node = Node { elem: element, next: self.head.as_ref(), }; ContextTree { head: Some(new_node), } } } pub struct ContextElement<'r> { pub fail_matcher: ChainBehavior<'r>, } pub enum ChainBehavior<'r> { AndParent(Option<&'r Matcher>), IgnoreParent(Option<&'r Matcher>), } pub trait OrgModeContextTree<'r> { fn with_additional_fail_matcher(&'r self, fail_matcher: &'r Matcher) -> OrgModeContext<'r>; } impl<'r> OrgModeContextTree<'r> for OrgModeContext<'r> { fn with_additional_fail_matcher( &'r self, fail_matcher: &'r Matcher, ) -> ContextTree<'r, ContextElement<'r>> { self.with_additional_node(ContextElement { fail_matcher: ChainBehavior::AndParent(Some(fail_matcher)), }) } }