How can I give nom's take_while
an upper limit on the number of characters it should match? I want to take characters according to a certain condition, but at most N
.
Since this will be a very performance critical part of the parser, I'd like to avoid using a bunch of individual take(1usize)
. Partly, because it feels awkward having to deal with single element slices one-by-one, but also because the compiler probably cannot know at compile time that they must have a size of 1, i.e., it will likely have to generate bound checks or size assertions, right?
Conceptually, a take_while
with an upper limit would feel more appropriate. I was hoping I can do the counting with a mutable loop variable myself like so:
let mut i = 0;
let (input, _) = take_while(|c| {
i += 1;
c >= 0x80 && i < 9
})(input)?;
In fact, I could even extract the necessary information in the closure, which most like should result in a very efficient code generation. (The goal is to implement a certain kind of VarInt LSB encoding, i.e., I could update a local mutable variable x = x + (if last_byte { c } else { c & 0x7f }) << 7
.)
Unfortunately take_while
seems to allow only Fn
and not FnMut
which probably means this is impossible (why the limitation?). What else could I do to implement that nicely?
Use a
Cell
to make your closure have interior mutability. Then it can have mutable state, but still implementFn
: