Function glue::combinators::finders::find_when
source ยท pub fn find_when<'a, Res, Skip, Pred, Par>(
predicate: Pred,
parser: Par,
) -> impl Parser<'a, Res>Expand description
Run a parser, and if it is successful, run another parser and return its results.
assert_eq!(
find_when(is('-'), find_all((is('-'), is(digit)))).parse("-1"),
Ok((
ParserContext {
input: "-1",
bounds: 0..2,
},
("-", "1")
))
);This is useful for gating off more complicated branches of a parser behind a sanity check, but less useful when applied to everything as that results in more work to parse the same input.
It can also be used to hide branches from error reports as those branches will error
at the find_when parser first, and not at the main parser which might itself produce
a lot more errors if it is allowed to run.
For example:
fn branch_a<'a>() -> impl Parser<'a, &'a str> {
move |ctx| {
map_error(take_all((is("a="), is(digit))), |error| {
error.tag("branch a")
})
.parse(ctx)
}
}
fn branch_b<'a>() -> impl Parser<'a, &'a str> {
move |ctx| {
map_error(take_all((is("b="), is(digit))), |error| {
error.tag("branch b")
})
.parse(ctx)
}
}
assert_eq!(
find_any((branch_a(), branch_b())).parse("b"),
// SourceError message contains a reference to each branch that failed:
Err((
ParserContext {
input: "b",
bounds: 0..0
},
SourceError::Ranges(vec![
SourceError::TaggedRanges(
"branch a".into(),
vec![SourceError::Ranges(vec![SourceError::Range(0..0)])]
),
SourceError::TaggedRanges(
"branch b".into(),
vec![SourceError::Ranges(vec![SourceError::Range(0..0)])]
),
])
))
);The amount of information returned in the error is reduced by using find_when to check which branch is followed:
assert_eq!(
find_any((find_when(is('a'), branch_a()), find_when(is('b'), branch_b()))).parse("b"),
Err((
ParserContext {
input: "b",
bounds: 0..0
},
SourceError::Ranges(vec![
SourceError::Range(0..0),
SourceError::TaggedRanges(
"branch b".into(),
vec![SourceError::Ranges(vec![SourceError::Range(0..0)])]
),
])
))
);