From b27be8eab1641b07e764fd9fa20b8cfd5070342b Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Thu, 15 Dec 2022 20:32:00 -0500 Subject: [PATCH] Pass context into fail matchers. --- src/parser/nom_context.rs | 16 ++++++++++------ src/parser/text_element_parser.rs | 17 ++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/parser/nom_context.rs b/src/parser/nom_context.rs index e1bc2be..978e6cf 100644 --- a/src/parser/nom_context.rs +++ b/src/parser/nom_context.rs @@ -8,8 +8,12 @@ use nom::IResult; use super::list::List; use super::list::Node; use super::token::Token; +use super::Context; -type Matcher = dyn for<'s> Fn(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>; +type Matcher = dyn for<'r, 's> Fn( + Context<'r, 's>, + &'s str, +) -> IResult<&'s str, &'s str, VerboseError<&'s str>>; #[derive(Debug, Clone)] pub struct ContextTree<'r, 's> { @@ -39,10 +43,10 @@ impl<'r, 's> ContextTree<'r, 's> { self.tree.iter() } - pub fn check_fail_matcher<'b>( + pub fn check_fail_matcher( &'r self, - i: &'b str, - ) -> IResult<&'b str, &'b str, VerboseError<&'b str>> { + i: &'s str, + ) -> IResult<&'s str, &'s str, VerboseError<&'s str>> { // TODO: Can I do this without incrementing reference counters? Perhaps via implementing an iterator over the list? let mut current_node = self.tree.clone(); while !current_node.is_empty() { @@ -53,14 +57,14 @@ impl<'r, 's> ContextTree<'r, 's> { ContextElement::FailMatcherNode(fail_matcher) => { match fail_matcher.fail_matcher { ChainBehavior::AndParent(Some(matcher)) => { - let local_result = matcher(i); + let local_result = matcher(self, i); if local_result.is_ok() { return local_result; } } ChainBehavior::AndParent(None) => {} ChainBehavior::IgnoreParent(Some(matcher)) => { - let local_result = matcher(i); + let local_result = matcher(self, i); if local_result.is_ok() { return local_result; } diff --git a/src/parser/text_element_parser.rs b/src/parser/text_element_parser.rs index 64d91d0..499a3c2 100644 --- a/src/parser/text_element_parser.rs +++ b/src/parser/text_element_parser.rs @@ -127,7 +127,7 @@ fn can_start_bold<'s, 'r>(context: Context<'r, 's>) -> bool { loop { if let Some((i, ctx)) = context_iterator.next() { match ctx.get_data() { - ContextElement::FailMatcherNode(_) => {}, + ContextElement::FailMatcherNode(_) => {} ContextElement::PreviousElementNode(previous_element_node) => { match &previous_element_node.element { Token::TextElement(text_element) => { @@ -139,12 +139,12 @@ fn can_start_bold<'s, 'r>(context: Context<'r, 's>) -> bool { TextElement::Bold(_) => return false, TextElement::Link(_) => return false, }; - }, + } }; - }, + } ContextElement::StartOfParagraph => { return true; - }, + } } } else { break; @@ -173,7 +173,7 @@ pub fn context_bold_end<'s, 'r>(context: Context<'r, 's>, input: &'s str) -> Res tag(" "), tag("\t"), tag("\n"), - |i| context.check_fail_matcher(i) + |i| context.check_fail_matcher(i), )))(remaining)?; Ok((remaining, actual_match)) @@ -188,7 +188,7 @@ pub fn paragraph<'s, 'r>( let paragraph_context = context .with_additional_node(ContextElement::StartOfParagraph) .with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode { - fail_matcher: ChainBehavior::AndParent(Some(¶graph_end)), + fail_matcher: ChainBehavior::AndParent(Some(&context_paragraph_end)), })); let (remaining, (many, till)) = context_many_till(¶graph_context, flat_text_element, context_paragraph_end)(i)?; @@ -222,13 +222,12 @@ fn flat_text_element<'s, 'r>( ))(i) } -fn recognize_bold_end(input: &str) -> Res<&str, &str> { +fn recognize_bold_end<'s, 'r>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { recognize(bold_end)(input) } fn flat_bold<'s, 'r>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, Bold<'s>> { let bold_start = parser_with_context!(context_bold_start)(&context); - // TODO: I need to make the fail matchers take in context so I can use context_bold_end. Otherwise this is ending bolds early just because it hits an asterisk. let nom_context = context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode { fail_matcher: ChainBehavior::AndParent(Some(&recognize_bold_end)), @@ -240,7 +239,7 @@ fn flat_bold<'s, 'r>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, Bold< Ok((remaining, ret)) } -fn recognize_link_end(input: &str) -> Res<&str, &str> { +fn recognize_link_end<'s, 'r>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { recognize(link_end)(input) }