organic/src/parser/nom_context.rs

154 lines
4.2 KiB
Rust
Raw Normal View History

2022-10-15 00:01:37 -04:00
use std::cell::RefCell;
use std::rc::Rc;
2022-07-16 17:27:08 -04:00
use nom::branch::alt;
use nom::combinator::not;
2022-07-15 23:26:49 -04:00
use nom::error::VerboseError;
use nom::IResult;
2022-10-15 00:01:37 -04:00
use nom::Parser;
2022-10-30 05:48:43 -04:00
type ContextReference<T> = Option<Rc<ContextLayer<T>>>;
pub struct ContextLayer<T> {
data: T,
2022-10-30 05:48:43 -04:00
parent: ContextReference<T>,
}
impl<T> ContextLayer<T> {
pub fn with_new_layer(self: Rc<Self>, new_layer: T) -> ContextLayer<T> {
ContextLayer {
data: new_layer,
parent: Some(self),
}
}
}
pub struct TestContext<T> {
head: ContextReference<T>,
}
// type ContextReference<T> = Option<Rc<ContextLayer<T>>>;
// struct ContextLayer<T> {
// data: T,
// parent: ContextReference<T>,
// }
2022-10-30 05:53:18 -04:00
pub struct ContextData<'r> {
fail_matcher: ChainBehavior<'r>,
}
2022-10-30 05:53:18 -04:00
impl<'r> TestContext<ContextData<'r>> {
pub fn new() -> Self {
TestContext { head: None }
}
pub fn with_additional_fail_matcher(
&self,
2022-10-30 05:53:18 -04:00
new_matcher: MatcherRef<'r>,
) -> TestContext<ContextData<'r>> {
TestContext {
head: Some(Rc::new(ContextLayer {
data: ContextData {
fail_matcher: ChainBehavior::AndParent(Some(new_matcher)),
},
parent: self.head.clone(),
})),
}
}
}
/////
///// OLD
/////
2022-10-30 05:53:18 -04:00
type MatcherRef<'r> = Rc<
RefCell<dyn for<'s> FnMut(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>> + 'r>,
>;
2022-10-15 00:01:37 -04:00
2022-10-30 05:53:18 -04:00
// struct FailChecker<'r>(&'r NomContext<'r>);
2022-10-15 00:01:37 -04:00
2022-10-30 05:53:18 -04:00
// impl<'r> FailChecker<'r> {
// fn new(func: &'r NomContext<'r>) -> Self {
// Self(func)
// }
// }
2022-10-15 00:01:37 -04:00
2022-10-30 05:53:18 -04:00
enum ChainBehavior<'r> {
AndParent(Option<MatcherRef<'r>>),
IgnoreParent(Option<MatcherRef<'r>>),
2022-07-15 23:26:49 -04:00
}
2022-10-30 05:53:18 -04:00
// pub struct NomContext<'r> {
// parent: Option<&'r Self>,
// fail_matcher: ChainBehavior<'r>,
// /// You can't have nested bolds or links in org-mode
// match_bold_allowed: bool,
// match_link_allowed: bool,
// }
2022-10-30 05:53:18 -04:00
// impl<'r> NomContext<'r> {
// pub fn new(fail_matcher: MatcherRef) -> Self {
// NomContext {
// parent: None,
// fail_matcher: ChainBehavior::IgnoreParent(Some(fail_matcher)),
// match_bold_allowed: true,
// match_link_allowed: true,
// }
// }
// pub fn with_additional_fail_matcher(&self, other: MatcherRef) -> NomContext {
// NomContext {
// parent: Some(&self),
// fail_matcher: ChainBehavior::AndParent(Some(other)),
// match_bold_allowed: self.match_bold_allowed,
// match_link_allowed: self.match_link_allowed,
// }
// }
// pub fn without_bold(&self, other: MatcherRef) -> NomContext {
// NomContext {
// parent: Some(&self),
// fail_matcher: ChainBehavior::AndParent(Some(other)),
// match_bold_allowed: false,
// match_link_allowed: self.match_link_allowed,
// }
// }
// pub fn not_matching_fail<'s>(&self, i: &'s str) -> IResult<&'s str, (), VerboseError<&'s str>> {
// not(FailChecker::new(self))(i)
// }
// pub fn can_match_bold(&self) -> bool {
// self.match_bold_allowed
// }
// pub fn can_match_link(&self) -> bool {
// self.match_link_allowed
// }
// }
2022-10-15 00:01:37 -04:00
2022-10-30 05:53:18 -04:00
// impl<'r, 's> Parser<&'s str, &'s str, VerboseError<&'s str>> for FailChecker<'r> {
// fn parse(&mut self, i: &'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>> {
// let fail_func = match &self.0.fail_matcher {
// ChainBehavior::AndParent(inner) => inner,
// ChainBehavior::IgnoreParent(inner) => inner,
// };
// if let Some(inner) = fail_func {
// let parsed = (&mut *inner.borrow_mut())(i);
// if parsed.is_ok() {
// return parsed;
// }
// }
// match (self.0.parent, &self.0.fail_matcher) {
// (None, _) | (_, ChainBehavior::IgnoreParent(_)) => Err(nom::Err::Error(
// nom::error::make_error(i, nom::error::ErrorKind::Alt),
// )),
// (Some(parent), ChainBehavior::AndParent(_)) => {
// let mut parent_fail_checker = FailChecker::new(parent);
// parent_fail_checker.parse(i)
// }
// }
// }
// }