2022-12-11 02:07:12 -05:00
|
|
|
use std::rc::Rc;
|
|
|
|
|
2022-11-26 22:36:02 -05:00
|
|
|
use nom::bytes::complete::take;
|
2022-10-15 14:04:24 -04:00
|
|
|
use nom::combinator::not;
|
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-24 14:59:37 -05:00
|
|
|
|
2022-12-15 23:09:40 -05:00
|
|
|
use super::error::CustomError;
|
2022-12-03 22:18:37 -05:00
|
|
|
use super::list::List;
|
2022-12-11 02:07:12 -05:00
|
|
|
use super::list::Node;
|
2022-12-03 23:53:52 -05:00
|
|
|
use super::token::Token;
|
2022-12-15 20:32:00 -05:00
|
|
|
use super::Context;
|
2022-11-24 15:40:07 -05:00
|
|
|
|
2022-12-15 23:09:40 -05:00
|
|
|
type Matcher =
|
|
|
|
dyn for<'r, 's> Fn(Context<'r, 's>, &'s str) -> IResult<&'s str, &'s str, CustomError<&'s str>>;
|
2022-11-24 16:01:52 -05:00
|
|
|
|
2022-12-03 22:18:37 -05:00
|
|
|
#[derive(Debug, Clone)]
|
2022-12-10 23:49:02 -05:00
|
|
|
pub struct ContextTree<'r, 's> {
|
|
|
|
tree: List<ContextElement<'r, 's>>,
|
2022-11-24 15:40:07 -05:00
|
|
|
}
|
|
|
|
|
2022-12-10 23:49:02 -05:00
|
|
|
impl<'r, 's> ContextTree<'r, 's> {
|
2022-11-26 22:03:15 -05:00
|
|
|
pub fn new() -> Self {
|
2022-12-03 22:18:37 -05:00
|
|
|
ContextTree { tree: List::new() }
|
2022-11-24 15:40:07 -05:00
|
|
|
}
|
2022-11-24 16:01:52 -05:00
|
|
|
|
2022-12-10 23:49:02 -05:00
|
|
|
pub fn ptr_eq<'x, 'y>(&self, other: &ContextTree<'x, 'y>) -> bool {
|
2022-12-10 22:04:39 -05:00
|
|
|
self.tree.ptr_eq(&other.tree)
|
|
|
|
}
|
|
|
|
|
2022-12-10 23:49:02 -05:00
|
|
|
pub fn with_additional_node(&self, data: ContextElement<'r, 's>) -> ContextTree<'r, 's> {
|
2022-12-03 22:18:37 -05:00
|
|
|
let new_list = self.tree.push_front(data);
|
|
|
|
ContextTree { tree: new_list }
|
|
|
|
}
|
|
|
|
|
2022-12-10 23:49:02 -05:00
|
|
|
pub fn pop_front(&mut self) -> (Option<ContextElement<'r, 's>>, ContextTree<'r, 's>) {
|
2022-12-11 00:02:13 -05:00
|
|
|
let (popped_element, remaining) = self.tree.pop_front();
|
|
|
|
(popped_element, ContextTree { tree: remaining })
|
2022-12-10 22:20:29 -05:00
|
|
|
}
|
|
|
|
|
2022-12-11 02:07:12 -05:00
|
|
|
pub fn iter(&self) -> impl Iterator<Item = &Rc<Node<ContextElement<'r, 's>>>> {
|
|
|
|
self.tree.iter()
|
|
|
|
}
|
|
|
|
|
2022-12-15 21:24:53 -05:00
|
|
|
pub fn check_exit_matcher(
|
2022-12-03 22:18:37 -05:00
|
|
|
&'r self,
|
2022-12-15 20:32:00 -05:00
|
|
|
i: &'s str,
|
2022-12-15 23:09:40 -05:00
|
|
|
) -> IResult<&'s str, &'s str, CustomError<&'s str>> {
|
2022-12-15 21:30:53 -05:00
|
|
|
for current_node in self.iter() {
|
|
|
|
let context_element = current_node.get_data();
|
2022-12-03 22:18:37 -05:00
|
|
|
match context_element {
|
2022-12-15 21:24:53 -05:00
|
|
|
ContextElement::ExitMatcherNode(exit_matcher) => {
|
|
|
|
match exit_matcher.exit_matcher {
|
2022-12-03 22:18:37 -05:00
|
|
|
ChainBehavior::AndParent(Some(matcher)) => {
|
2022-12-15 20:32:00 -05:00
|
|
|
let local_result = matcher(self, i);
|
2022-12-03 22:18:37 -05:00
|
|
|
if local_result.is_ok() {
|
|
|
|
return local_result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ChainBehavior::AndParent(None) => {}
|
|
|
|
ChainBehavior::IgnoreParent(Some(matcher)) => {
|
2022-12-15 20:32:00 -05:00
|
|
|
let local_result = matcher(self, i);
|
2022-12-03 22:18:37 -05:00
|
|
|
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)?;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2022-12-11 00:02:13 -05:00
|
|
|
ContextElement::PreviousElementNode(_) => {}
|
2022-12-11 00:21:30 -05:00
|
|
|
ContextElement::StartOfParagraph => {}
|
2022-12-15 21:57:21 -05:00
|
|
|
ContextElement::Context(_) => {}
|
2022-12-03 22:18:37 -05:00
|
|
|
};
|
2022-11-26 22:03:15 -05:00
|
|
|
}
|
2022-12-03 22:18:37 -05:00
|
|
|
// TODO: Make this a custom error
|
|
|
|
not(take(0usize))(i)?;
|
|
|
|
unreachable!()
|
2022-11-26 22:03:15 -05:00
|
|
|
}
|
2022-11-26 22:36:02 -05:00
|
|
|
}
|
|
|
|
|
2022-12-03 23:57:39 -05:00
|
|
|
#[derive(Debug)]
|
2022-12-10 23:49:02 -05:00
|
|
|
pub enum ContextElement<'r, 's> {
|
2022-12-15 21:24:53 -05:00
|
|
|
ExitMatcherNode(ExitMatcherNode<'r>),
|
2022-12-10 23:49:02 -05:00
|
|
|
PreviousElementNode(PreviousElementNode<'s>),
|
2022-12-15 21:57:21 -05:00
|
|
|
Context(&'r str),
|
2022-12-11 00:21:30 -05:00
|
|
|
StartOfParagraph,
|
2022-11-26 22:54:54 -05:00
|
|
|
}
|
|
|
|
|
2022-12-03 23:57:39 -05:00
|
|
|
#[derive(Debug)]
|
2022-12-15 21:24:53 -05:00
|
|
|
pub struct ExitMatcherNode<'r> {
|
|
|
|
pub exit_matcher: ChainBehavior<'r>,
|
2022-11-26 22:36:02 -05:00
|
|
|
}
|
|
|
|
|
2022-12-03 23:57:39 -05:00
|
|
|
#[derive(Debug)]
|
2022-11-26 22:36:02 -05:00
|
|
|
pub struct PreviousElementNode<'r> {
|
2022-12-03 23:53:52 -05:00
|
|
|
pub element: Token<'r>,
|
2022-11-26 22:36:02 -05:00
|
|
|
}
|
|
|
|
|
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>),
|
|
|
|
}
|
|
|
|
|
2022-12-03 22:18:37 -05:00
|
|
|
impl<'r> std::fmt::Debug for ChainBehavior<'r> {
|
2022-11-25 18:23:51 -05:00
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
2022-12-03 22:18:37 -05:00
|
|
|
let mut formatter = f.debug_struct("ChainBehavior");
|
|
|
|
// match self {
|
|
|
|
// ChainBehavior::AndParent(_) => {
|
|
|
|
// formatter = formatter.field("type", &"AndParent");
|
|
|
|
// }
|
|
|
|
// ChainBehavior::IgnoreParent(_) => {
|
|
|
|
// formatter = formatter.field("type", &"IgnoreParent");
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
formatter.finish()
|
2022-11-26 22:54:54 -05:00
|
|
|
}
|
|
|
|
}
|