diff --git a/src/parser/new_context.rs b/src/parser/new_context.rs index da5c8d91..8fb0f68f 100644 --- a/src/parser/new_context.rs +++ b/src/parser/new_context.rs @@ -1,4 +1,8 @@ +use std::borrow::Cow; + +use nom::combinator::not; use nom::combinator::recognize; +use nom::complete::take; use nom::error::VerboseError; use nom::IResult; @@ -9,7 +13,7 @@ type Matcher = dyn for<'s> Fn(&'s str) -> IResult<&'s str, &'s str, VerboseError type Link<'r, T> = Option<&'r Node<'r, T>>; pub trait OrgModeContext<'r> { - // todo + fn get_fail_matcher(&'r self) -> Cow>; } struct FailMatcherNode<'r> { @@ -20,7 +24,8 @@ struct PreviousElementNode<'r> { dummy: &'r str, } -enum ChainBehavior<'r> { +#[derive(Clone)] +pub enum ChainBehavior<'r> { AndParent(Option<&'r Matcher>), IgnoreParent(Option<&'r Matcher>), } @@ -52,10 +57,56 @@ impl<'r> ContextTree<'r, dyn OrgModeContext<'r>> { head: Some(new_node), } } + + pub fn check_fail_matcher<'s>( + &'r self, + i: &'s str, + ) -> IResult<&'s str, &'s str, VerboseError<&'s str>> { + let mut current_node = self.head.as_ref(); + while current_node.is_some() { + let current_node_unwrapped = + current_node.expect("while loop asserts current_node is some."); + let current_fail_matcher = current_node_unwrapped.elem.get_fail_matcher(); + match current_fail_matcher.as_ref() { + ChainBehavior::AndParent(Some(matcher)) => { + let local_result = matcher(i); + if local_result.is_ok() { + return local_result; + } + } + ChainBehavior::AndParent(None) => {} + ChainBehavior::IgnoreParent(Some(matcher)) => { + let local_result = matcher(i); + if local_result.is_ok() { + return local_result; + } + // TODO: Make this a custom error + not(take(0usize))(i)?; + } + ChainBehavior::IgnoreParent(None) => { + // TODO: Make this a custom error + not(take(0usize))(i)?; + } + }; + current_node = current_node.map(|current_head| current_head.parent).flatten(); + } + // TODO: Make this a custom error + not(take(0usize))(i)?; + unreachable!() + } } -impl<'r> OrgModeContext<'r> for FailMatcherNode<'r> {} -impl<'r> OrgModeContext<'r> for PreviousElementNode<'r> {} +impl<'r> OrgModeContext<'r> for FailMatcherNode<'r> { + fn get_fail_matcher(&'r self) -> Cow> { + Cow::Borrowed(&self.fail_matcher) + } +} + +impl<'r> OrgModeContext<'r> for PreviousElementNode<'r> { + fn get_fail_matcher(&'r self) -> Cow> { + todo!() + } +} fn recognize_bold_end(input: &str) -> Res<&str, &str> { recognize(bold_end)(input)