I am writing a nom parser combinator that consumes bytes and returns an Option<&[u8]>
. The parser combinator should follow the following rules:
- Read a single signed, big endian 16 bit integer (
s
) - If
s
is -1, returnNone
- If
s
is not -1, reads
bits and returnSome
Here is my parser combinator:
fn parse(i: &[u8]) -> nom::IResult<&[u8], Option<&[u8]>> {
nom::combinator::flat_map(be_i16, |s: i16| {
match s {
-1 => nom::combinator::success(None),
_ => nom::combinator::map(take(s as u16), Some)
}
})(i)
}
However I am seeing the following error:
error[E0308]: `match` arms have incompatible types
--> src/main.rs:15:18
|
13 | / match s {
14 | | -1 => nom::combinator::success(None),
| | ------------------------------ this is found to be of type `impl Fn<(_,)>`
15 | | _ => nom::combinator::map(take(s as u16), Some)
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found a different opaque type
16 | | }
| |_________- `match` arms have incompatible types
|
::: /Users/dfarr/.cargo/registry/src/github.com-1ecc6299db9ec823/nom-6.0.1/src/combinator/mod.rs:74:64
|
74 | pub fn map<I, O1, O2, E, F, G>(mut first: F, mut second: G) -> impl FnMut(I) -> IResult<I, O2, E>
| ---------------------------------- the found opaque type
|
= note: expected type `impl Fn<(_,)>`
found opaque type `impl FnMut<(_,)>`
= note: distinct uses of `impl Trait` result in different opaque types
I can see that nom::combinator::success
does indeed have a return type of impl Fn(I) -> ...
, and nom::combinator::map
returns impl FnMut(I) -> ...
. Is there a more idiomatic way of using nom where these combinators can be used together in this manner?