nom
nom copied to clipboard
Add combinator "erasing" output type
Recently I wanted to write something like this:
fn parser(input: &str) -> IResult<&str, Vec<&str>> {
map(
many_till(
terminated(not_line_ending, line_ending),
peek(alt((eof, header, modifier))),
),
|(lines, _)| lines,
)(input)
}
where eof
, header
and modifier
are parsers having different output types.
Unfortunately that doesn't work, because alt
only takes parsers having the same output type.
I propose a parser, which returns the unit type if the child parser was succesful. Otherwise just the error.
Let's call it ok
here,
then I could rewrite the line in question like this:
peek(alt((ok(eof), ok(header), ok(modifier))))
I found a similar combinator in the docs: recognize
although it does have an overhead because it returns what the child parser consumed.
Also, please let me know if I missed something 😉
I could've sworn there was a void
combinator for this, but apparently not. It can be emulated with value((), p)
, but I agree it'd be a good addition to the library.
It can be emulated with
value((), p)
Oh, I didn't even think of that.
You could use the toilet closure eof.map(|_| ())
You could use the toilet closure
eof.map(|_| ())
Yes, but it will be a little longer:
peek(alt((
eof.map(|_| ()),
page_header_num.map(|_| ()),
choice.map(|_| ()),
)))
vs
peek(alt((void(eof), void(page_header_num), void(choice))))
I think the second looks more concise
A more Rust centric name for this would be unit
since ()
is the unit type.