| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | use std::cell::RefCell;
 | 
					
						
							|  |  |  | use std::rc::Rc;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use nom::branch::alt;
 | 
					
						
							|  |  |  | use nom::bytes::complete::take;
 | 
					
						
							| 
									
										
										
										
											2022-10-15 14:04:24 -04:00
										 |  |  | use nom::combinator::not;
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | use nom::error::ContextError;
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:24:49 -05:00
										 |  |  | use nom::error::ErrorKind;
 | 
					
						
							|  |  |  | use nom::error::ParseError;
 | 
					
						
							| 
									
										
										
										
											2022-07-15 23:26:49 -04:00
										 |  |  | use nom::error::VerboseError;
 | 
					
						
							| 
									
										
										
										
											2022-07-16 16:31:00 -04:00
										 |  |  | use nom::IResult;
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | use nom::Parser;
 | 
					
						
							|  |  |  | use tracing::trace;
 | 
					
						
							| 
									
										
										
										
											2022-11-24 14:59:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:03:15 -05:00
										 |  |  | type Link<'r, T> = Option<&'r Node<'r, T>>;
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | type Matcher = dyn for<'s> Fn(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>;
 | 
					
						
							|  |  |  | pub type OrgModeContextNode<'r> = ContextTree<'r, ContextElement<'r>>;
 | 
					
						
							| 
									
										
										
										
											2022-11-24 15:40:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | struct Node<'r, T> {
 | 
					
						
							|  |  |  |     elem: T,
 | 
					
						
							|  |  |  |     next: Link<'r, T>,
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:03:15 -05:00
										 |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:01:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | pub struct ContextTree<'r, T> {
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:03:15 -05:00
										 |  |  |     head: Option<Node<'r, T>>,
 | 
					
						
							| 
									
										
										
										
											2022-11-24 15:40:07 -05:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | impl<'r, T> ContextTree<'r, T> {
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:03:15 -05:00
										 |  |  |     pub fn new() -> Self {
 | 
					
						
							|  |  |  |         ContextTree { head: None }
 | 
					
						
							| 
									
										
										
										
											2022-11-24 15:40:07 -05:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:01:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |     pub fn with_additional_node(&'r self, element: T) -> ContextTree<'r, T> {
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:03:15 -05:00
										 |  |  |         let new_node = Node {
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |             elem: element,
 | 
					
						
							|  |  |  |             next: self.head.as_ref(),
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:03:15 -05:00
										 |  |  |         };
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:03:15 -05:00
										 |  |  |         ContextTree {
 | 
					
						
							|  |  |  |             head: Some(new_node),
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:54:54 -05:00
										 |  |  | pub enum ContextElement<'r> {
 | 
					
						
							|  |  |  |     FailMatcherNode(FailMatcherNode<'r>),
 | 
					
						
							|  |  |  |     PreviousElementNode(PreviousElementNode<'r>),
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pub struct FailMatcherNode<'r> {
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |     pub fail_matcher: ChainBehavior<'r>,
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pub struct PreviousElementNode<'r> {
 | 
					
						
							|  |  |  |     pub dummy: &'r str,
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:54:54 -05:00
										 |  |  | #[derive(Clone)]
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | pub enum ChainBehavior<'r> {
 | 
					
						
							|  |  |  |     AndParent(Option<&'r Matcher>),
 | 
					
						
							|  |  |  |     IgnoreParent(Option<&'r Matcher>),
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pub trait OrgModeContextTree<'r> {
 | 
					
						
							|  |  |  |     fn with_additional_fail_matcher(&'r self, fail_matcher: &'r Matcher) -> OrgModeContextNode<'r>;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fn match_fail<'s>(&'r self, i: &'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>;
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-11-26 20:41:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  | impl<'r> OrgModeContextTree<'r> for OrgModeContextNode<'r> {
 | 
					
						
							|  |  |  |     fn with_additional_fail_matcher(
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:03:15 -05:00
										 |  |  |         &'r self,
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |         fail_matcher: &'r Matcher,
 | 
					
						
							|  |  |  |     ) -> ContextTree<'r, ContextElement<'r>> {
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:54:54 -05:00
										 |  |  |         self.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode {
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |             fail_matcher: ChainBehavior::AndParent(Some(fail_matcher)),
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:54:54 -05:00
										 |  |  |         }))
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // fn with_previous_element(&'r self, dummy: &'r str) -> ContextTree<'r, PreviousElementNode<'r>> {
 | 
					
						
							|  |  |  |     //     self.with_additional_node(PreviousElementNode {
 | 
					
						
							|  |  |  |     //         dummy
 | 
					
						
							|  |  |  |     //     })
 | 
					
						
							|  |  |  |     // }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fn match_fail<'s>(&'r self, i: &'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>> {
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:01:52 -05:00
										 |  |  |         let mut current_node = self.head.as_ref();
 | 
					
						
							|  |  |  |         while current_node.is_some() {
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:54:54 -05:00
										 |  |  |             let current_node_unwrapped =
 | 
					
						
							|  |  |  |                 current_node.expect("while loop asserts current_node is some.");
 | 
					
						
							|  |  |  |             match current_node_unwrapped.elem.get_fail_matcher() {
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:01:52 -05:00
										 |  |  |                 ChainBehavior::AndParent(Some(matcher)) => {
 | 
					
						
							|  |  |  |                     let local_result = matcher(i);
 | 
					
						
							|  |  |  |                     if local_result.is_ok() {
 | 
					
						
							|  |  |  |                         return local_result;
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:24:49 -05:00
										 |  |  |                 }
 | 
					
						
							|  |  |  |                 ChainBehavior::AndParent(None) => {}
 | 
					
						
							|  |  |  |                 ChainBehavior::IgnoreParent(Some(matcher)) => {
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |                     let local_result = matcher(i);
 | 
					
						
							|  |  |  |                     if local_result.is_ok() {
 | 
					
						
							|  |  |  |                         return local_result;
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							|  |  |  |                     // TODO: Make this a custom error
 | 
					
						
							|  |  |  |                     not(take(0usize))(i)?;
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:24:49 -05:00
										 |  |  |                 }
 | 
					
						
							|  |  |  |                 ChainBehavior::IgnoreParent(None) => {
 | 
					
						
							|  |  |  |                     // TODO: Make this a custom error
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |                     not(take(0usize))(i)?;
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:24:49 -05:00
										 |  |  |                 }
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:01:52 -05:00
										 |  |  |             };
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |             current_node = current_node.map(|current_head| current_head.next).flatten();
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:01:52 -05:00
										 |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:24:49 -05:00
										 |  |  |         // TODO: Make this a custom error
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:36:02 -05:00
										 |  |  |         not(take(0usize))(i)?;
 | 
					
						
							|  |  |  |         unreachable!()
 | 
					
						
							| 
									
										
										
										
											2022-11-24 16:01:52 -05:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-11-24 15:40:07 -05:00
										 |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-11-25 18:23:51 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | impl<'r, T> std::fmt::Debug for ContextTree<'r, T> {
 | 
					
						
							|  |  |  |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
					
						
							|  |  |  |         write!(f, "ContextTree")
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2022-11-26 22:54:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | impl<'r> ContextElement<'r> {
 | 
					
						
							|  |  |  |     pub fn get_fail_matcher(&self) -> ChainBehavior<'r> {
 | 
					
						
							|  |  |  |         match self {
 | 
					
						
							|  |  |  |             ContextElement::FailMatcherNode(fail_matcher_node) => {
 | 
					
						
							|  |  |  |                 fail_matcher_node.fail_matcher.clone()
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |             ContextElement::PreviousElementNode(previous_element_node) => {
 | 
					
						
							|  |  |  |                 ChainBehavior::AndParent(None)
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 |