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;
|
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-10-15 00:01:37 -04:00
|
|
|
use nom::Parser;
|
|
|
|
|
2022-10-30 04:50:09 -04:00
|
|
|
pub struct TestContext<T> {
|
|
|
|
head: ContextReference<T>,
|
|
|
|
}
|
|
|
|
|
|
|
|
type ContextReference<T> = Option<Box<ContextLayer<T>>>;
|
|
|
|
|
|
|
|
struct ContextLayer<T> {
|
|
|
|
data: T,
|
|
|
|
parent: ContextReference<T>,
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ContextData {
|
|
|
|
fail_matcher: ChainBehavior,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TestContext<ContextData> {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
TestContext { head: None }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_additional_fail_matcher(
|
|
|
|
&self,
|
|
|
|
new_matcher: MatcherRef,
|
|
|
|
) -> TestContext<ContextData> {
|
|
|
|
TestContext {
|
|
|
|
head: Some(Box::new(ContextLayer {
|
|
|
|
data: ContextData {
|
|
|
|
fail_matcher: ChainBehavior::AndParent(Some(new_matcher)),
|
|
|
|
},
|
|
|
|
parent: self.head, // TODO FIX THIS
|
|
|
|
})),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////
|
|
|
|
///// OLD
|
|
|
|
/////
|
|
|
|
|
2022-10-15 00:39:32 -04:00
|
|
|
type MatcherRef = Rc<RefCell<dyn FnMut(&str) -> IResult<&str, &str, VerboseError<&str>>>>;
|
2022-10-15 00:01:37 -04:00
|
|
|
|
2022-10-15 14:16:52 -04:00
|
|
|
struct FailChecker<'r>(&'r NomContext<'r>);
|
2022-10-15 00:01:37 -04:00
|
|
|
|
2022-10-15 14:16:52 -04:00
|
|
|
impl<'r> FailChecker<'r> {
|
|
|
|
fn new(func: &'r NomContext<'r>) -> Self {
|
2022-10-15 00:01:37 -04:00
|
|
|
Self(func)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
enum ChainBehavior {
|
|
|
|
AndParent(Option<MatcherRef>),
|
|
|
|
IgnoreParent(Option<MatcherRef>),
|
|
|
|
}
|
|
|
|
|
2022-10-15 14:16:52 -04:00
|
|
|
pub struct NomContext<'r> {
|
|
|
|
parent: Option<&'r Self>,
|
2022-10-15 00:01:37 -04:00
|
|
|
fail_matcher: ChainBehavior,
|
2022-10-14 20:09:09 -04:00
|
|
|
/// You can't have nested bolds or links in org-mode
|
2022-10-15 14:20:40 -04:00
|
|
|
match_bold_allowed: bool,
|
|
|
|
match_link_allowed: bool,
|
2022-07-15 23:26:49 -04:00
|
|
|
}
|
|
|
|
|
2022-10-15 14:16:52 -04:00
|
|
|
impl<'r> NomContext<'r> {
|
2022-10-15 00:39:32 -04:00
|
|
|
pub fn new(fail_matcher: MatcherRef) -> Self {
|
2022-07-16 21:32:23 -04:00
|
|
|
NomContext {
|
2022-10-15 00:01:37 -04:00
|
|
|
parent: None,
|
2022-10-15 00:39:32 -04:00
|
|
|
fail_matcher: ChainBehavior::IgnoreParent(Some(fail_matcher)),
|
2022-10-15 14:20:40 -04:00
|
|
|
match_bold_allowed: true,
|
|
|
|
match_link_allowed: true,
|
2022-07-16 21:55:33 -04:00
|
|
|
}
|
|
|
|
}
|
2022-10-14 20:50:00 -04:00
|
|
|
|
2022-10-15 00:39:32 -04:00
|
|
|
pub fn with_additional_fail_matcher(&self, other: MatcherRef) -> NomContext {
|
2022-10-15 00:01:37 -04:00
|
|
|
NomContext {
|
|
|
|
parent: Some(&self),
|
2022-10-15 00:39:32 -04:00
|
|
|
fail_matcher: ChainBehavior::AndParent(Some(other)),
|
2022-10-15 14:20:40 -04:00
|
|
|
match_bold_allowed: self.match_bold_allowed,
|
|
|
|
match_link_allowed: self.match_link_allowed,
|
2022-10-15 00:01:37 -04:00
|
|
|
}
|
|
|
|
}
|
2022-10-15 14:04:24 -04:00
|
|
|
|
2022-10-15 14:28:24 -04:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-15 14:04:24 -04:00
|
|
|
pub fn not_matching_fail<'s>(&self, i: &'s str) -> IResult<&'s str, (), VerboseError<&'s str>> {
|
|
|
|
not(FailChecker::new(self))(i)
|
|
|
|
}
|
2022-10-15 14:20:40 -04:00
|
|
|
|
|
|
|
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-15 17:48:27 -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>> {
|
2022-10-15 00:39:32 -04:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
2022-10-14 20:50:00 -04:00
|
|
|
}
|
2022-07-16 21:32:23 -04:00
|
|
|
}
|