I'm wondering if it's possible for verify to allow a verification function that can mutate its captured variables?
This would allow verify to do stateful parsing since it can use a captured variable to keep track of state between runs.
Currently, we can parse "blindly" and then validate the result afterwards, perhaps in a map_res. However, this loses error information since the error can't be reported when it happens but only after parsing is done.
From local testing it seems that making the G argument mutable (mut second: G,combinator/mod.rs#L424) and accepting a FnMut (G: FnMut(&O2) -> boolcombinator/mod.rs#L428) compiles, though I don't know if there are any other implications to consider?
Test case
Here's a parser that counts up consecutive integers separated by space, e.g. 1 2 3 4 5.
It fails if it encounters an integer that's not in the right order, e.g. 1 2 9 4 5.
use nom::{
character::complete::{char, digit1},
combinator::map_res,
error::{ErrorKind, ParseError},
multi::separated_list1,
IResult, Parser,
};
use std::borrow::Borrow;
fn validated(input: &str) -> IResult<&str, Vec<u32>> {
let mut current_index = 1;
let index = map_res(digit1, |s: &str| s.parse::<u32>());
let index_verified = verify(index, |digit| {
if digit == ¤t_index {
current_index += 1;
true
} else {
false
}
});
let tmp = separated_list1(char(' '), index_verified)(input);
tmp
}
fn main() {
let input = "1 2 3 4 5";
let o1 = validated(input);
println!("{:?}", o1);
let input = "1 2 9 4 5";
let o2 = validated(input);
println!("{:?}", o2);
}
/// [`verify`] with proposed updated argument `G`
pub fn verify<I: Clone, O1, O2, E: ParseError<I>, F, G>(
mut first: F,
mut second: G,
) -> impl FnMut(I) -> IResult<I, O1, E>
where
F: Parser<I, O1, E>,
G: FnMut(&O2) -> bool,
O1: Borrow<O2>,
O2: ?Sized,
{
move |input: I| {
let i = input.clone();
let (input, o) = first.parse(input)?;
if second(o.borrow()) {
Ok((input, o))
} else {
Err(nom::Err::Error(E::from_error_kind(i, ErrorKind::Verify)))
}
}
}
Version
Rust version : rustc 1.65.0 (897e37553 2022-11-02)
I'm wondering if it's possible for
verify
to allow a verification function that can mutate its captured variables?This would allow verify to do stateful parsing since it can use a captured variable to keep track of state between runs.
Currently, we can parse "blindly" and then validate the result afterwards, perhaps in a
map_res
. However, this loses error information since the error can't be reported when it happens but only after parsing is done.From local testing it seems that making the
G
argument mutable (mut second: G,
combinator/mod.rs#L424) and accepting aFnMut
(G: FnMut(&O2) -> bool
combinator/mod.rs#L428) compiles, though I don't know if there are any other implications to consider?Test case
Here's a parser that counts up consecutive integers separated by space, e.g.
1 2 3 4 5
.It fails if it encounters an integer that's not in the right order, e.g.
1 2 9 4 5
.Version