53 lines
2.1 KiB
Rust
53 lines
2.1 KiB
Rust
|
macro_rules! failable_sequence {
|
||
|
($name:ident,$inp:ident,$context:ident,$begin_matcher:expr,$element_matcher:expr,$success_matcher:expr) => {
|
||
|
pub fn $name<'b, F>(
|
||
|
$context: &'b NomContext<F>,
|
||
|
) -> impl for<'a> FnMut(
|
||
|
&'a str,
|
||
|
) -> nom::IResult<
|
||
|
&'a str,
|
||
|
crate::parser::text::Sequence<'a>,
|
||
|
VerboseError<&'a str>,
|
||
|
> + 'b
|
||
|
where
|
||
|
F: for<'a> nom::Parser<&'a str, &'a str, VerboseError<&'a str>>,
|
||
|
{
|
||
|
let fail_matcher = $context.fail_matcher.clone();
|
||
|
let new_fail_matcher = alt((
|
||
|
|i| fail_matcher.borrow_mut().parse(i),
|
||
|
recognize($success_matcher),
|
||
|
));
|
||
|
|
||
|
move |$inp: &str| {
|
||
|
let new_context = $context.with_no_bold();
|
||
|
// let other_new_context = NomContext::with_additional_fail_matcher(
|
||
|
// |i: &str| recognize($success_matcher)(i),
|
||
|
// $context,
|
||
|
// );
|
||
|
let other_new_context = super::nom_context::NomContext::new(new_fail_matcher);
|
||
|
let element_matcher = recognize($element_matcher(&new_context));
|
||
|
let local_fail_matcher = $context.fail_matcher.clone();
|
||
|
let ret = map(
|
||
|
recognize(tuple((
|
||
|
$begin_matcher,
|
||
|
nom::multi::many_till(
|
||
|
nom::sequence::preceded(
|
||
|
not(|i| local_fail_matcher.borrow_mut().parse(i)),
|
||
|
element_matcher,
|
||
|
),
|
||
|
nom::sequence::preceded(
|
||
|
not(|i| local_fail_matcher.borrow_mut().parse(i)),
|
||
|
$success_matcher,
|
||
|
),
|
||
|
),
|
||
|
))),
|
||
|
|s: &str| crate::parser::text::Sequence { contents: s },
|
||
|
)($inp)?;
|
||
|
Ok(ret)
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
pub(crate) use failable_sequence;
|