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 ContextReference = Option>>; pub struct ContextLayer { data: T, parent: ContextReference, } impl ContextLayer { pub fn with_new_layer(self: Rc, new_layer: T) -> ContextLayer { ContextLayer { data: new_layer, parent: Some(self), } } } pub struct TestContext { head: ContextReference, } // type ContextReference = Option>>; // struct ContextLayer { // data: T, // parent: ContextReference, // } pub struct ContextData<'r> { fail_matcher: ChainBehavior<'r>, } impl<'r> TestContext> { pub fn new() -> Self { TestContext { head: None } } pub fn with_additional_fail_matcher( &self, new_matcher: MatcherRef<'r>, ) -> TestContext> { TestContext { head: Some(Rc::new(ContextLayer { data: ContextData { fail_matcher: ChainBehavior::AndParent(Some(new_matcher)), }, parent: self.head.clone(), })), } } } ///// ///// OLD ///// type MatcherRef<'r> = Rc< RefCell FnMut(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>> + 'r>, >; // struct FailChecker<'r>(&'r NomContext<'r>); // impl<'r> FailChecker<'r> { // fn new(func: &'r NomContext<'r>) -> Self { // Self(func) // } // } enum ChainBehavior<'r> { AndParent(Option>), IgnoreParent(Option>), } // pub struct NomContext<'r> { // parent: Option<&'r Self>, // fail_matcher: ChainBehavior<'r>, // /// You can't have nested bolds or links in org-mode // match_bold_allowed: bool, // match_link_allowed: bool, // } // impl<'r> NomContext<'r> { // pub fn new(fail_matcher: MatcherRef) -> Self { // NomContext { // parent: None, // fail_matcher: ChainBehavior::IgnoreParent(Some(fail_matcher)), // match_bold_allowed: true, // match_link_allowed: true, // } // } // pub fn with_additional_fail_matcher(&self, other: MatcherRef) -> NomContext { // NomContext { // parent: Some(&self), // fail_matcher: ChainBehavior::AndParent(Some(other)), // match_bold_allowed: self.match_bold_allowed, // match_link_allowed: self.match_link_allowed, // } // } // pub fn without_bold(&self, other: MatcherRef) -> NomContext { // NomContext { // parent: Some(&self), // fail_matcher: ChainBehavior::AndParent(Some(other)), // match_bold_allowed: false, // match_link_allowed: self.match_link_allowed, // } // } // pub fn not_matching_fail<'s>(&self, i: &'s str) -> IResult<&'s str, (), VerboseError<&'s str>> { // not(FailChecker::new(self))(i) // } // pub fn can_match_bold(&self) -> bool { // self.match_bold_allowed // } // pub fn can_match_link(&self) -> bool { // self.match_link_allowed // } // } // impl<'r, 's> Parser<&'s str, &'s str, VerboseError<&'s str>> for FailChecker<'r> { // fn parse(&mut self, i: &'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>> { // let fail_func = match &self.0.fail_matcher { // ChainBehavior::AndParent(inner) => inner, // ChainBehavior::IgnoreParent(inner) => inner, // }; // if let Some(inner) = fail_func { // let parsed = (&mut *inner.borrow_mut())(i); // if parsed.is_ok() { // return parsed; // } // } // match (self.0.parent, &self.0.fail_matcher) { // (None, _) | (_, ChainBehavior::IgnoreParent(_)) => Err(nom::Err::Error( // nom::error::make_error(i, nom::error::ErrorKind::Alt), // )), // (Some(parent), ChainBehavior::AndParent(_)) => { // let mut parent_fail_checker = FailChecker::new(parent); // parent_fail_checker.parse(i) // } // } // } // }