From 6b93e1c007e966f6d79f21a4febe4881df09e6fc Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 15 Oct 2022 00:01:37 -0400 Subject: [PATCH] Lifetime issue. --- src/parser/nom_context.rs | 56 ++++++++++++++++++++++++++++----------- src/parser/text.rs | 5 +++- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/parser/nom_context.rs b/src/parser/nom_context.rs index d62a3c4..01900db 100644 --- a/src/parser/nom_context.rs +++ b/src/parser/nom_context.rs @@ -1,32 +1,58 @@ +use std::cell::RefCell; +use std::rc::Rc; + use nom::branch::alt; use nom::error::VerboseError; use nom::IResult; +use nom::Parser; -pub struct NomContext { - pub fail_matcher: Box IResult<&str, &str, VerboseError<&str>>>, +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 NomContext { - pub fn new( - fail_matcher: Box IResult<&str, &str, VerboseError<&str>>>, - ) -> Self { +impl<'a> NomContext<'a> { + pub fn new(fail_matcher: MatcherInner) -> Self { NomContext { - fail_matcher, + 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: Box IResult<&str, &str, VerboseError<&str>>>) -> NomContext { - // let new_matcher = alt((&self.fail_matcher, other)); - // NomContext { - // fail_matcher: new_matcher, - // can_match_bold: self.can_match_bold, - // can_match_link: self.can_match_link - // } - todo!() + 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) } } diff --git a/src/parser/text.rs b/src/parser/text.rs index 77ec244..a15cccd 100644 --- a/src/parser/text.rs +++ b/src/parser/text.rs @@ -1,3 +1,6 @@ +use std::cell::RefCell; +use std::rc::Rc; + /* hypothetical link: @@ -133,7 +136,7 @@ pub fn paragraph_end(input: &str) -> Res<&str, &str> { } pub fn document(input: &str) -> Res<&str, Vec<(Vec, &str)>> { - let initial_context = NomContext::new(Box::new(paragraph_end)); + let initial_context = NomContext::new(Rc::new(RefCell::new(paragraph_end))); todo!() // many1(parser_with_context!(paragraph)(initial_context))(input) }