use std::cell::RefCell; use std::rc::Rc; use nom::branch::alt; use nom::error::VerboseError; use nom::IResult; use nom::Parser; pub type MatcherInner = Rc IResult<&str, &str, VerboseError<&str>>>>; struct MatcherRef(MatcherInner); impl MatcherRef { pub fn new(func: MatcherInner) -> Self { Self(func) } } // type MatcherRef = Rc IResult<&str, &str, VerboseError<&str>>>>; enum ChainBehavior { AndParent(Option), IgnoreParent(Option), } pub struct NomContext<'a> { pub parent: Option<&'a Self>, fail_matcher: ChainBehavior, /// You can't have nested bolds or links in org-mode pub can_match_bold: bool, pub can_match_link: bool, } impl<'a> NomContext<'a> { pub fn new(fail_matcher: MatcherInner) -> Self { NomContext { parent: None, fail_matcher: ChainBehavior::IgnoreParent(Some(MatcherRef::new(fail_matcher))), can_match_bold: true, can_match_link: true, } } pub fn with_additional_fail_matcher(&self, other: MatcherInner) -> NomContext { NomContext { parent: Some(&self), fail_matcher: ChainBehavior::AndParent(Some(MatcherRef::new(other))), can_match_bold: self.can_match_bold, can_match_link: self.can_match_link, } } } impl Parser<&str, &str, VerboseError<&str>> for MatcherRef { fn parse(&mut self, i: &str) -> IResult<&str, &str, VerboseError<&str>> { (&mut *self.0.borrow_mut())(i) } }