I have a small parser that fails if the number it parses is out of bounds,
use nom::IResult;
use nom::bytes::complete::tag;
use nom::character::complete::digit1;
use nom::combinator::fail;
fn dup(s: &str) -> IResult<&str, u64> {
let (s, _) = tag("dup")(s)?;
let (s, n) = digit1(s)?;
let n = match n {
"0" => 0,
"1" => 1,
"2" => 2,
_ => return fail(s), // FIXME: Annotate.
};
Ok((s, n))
}
(See on playground.)
But I'd like for the error to be more meaningful.
How do I annotate this error with the context that n
is out of bounds?
E.g. instead of fail()
, use something that provides an error message.
Or somehow wrap a part of the parser in something that provides this context.
I know that you can create your own custom ErrorKind
, but can it be done without? (When you have an ErrorKind
, error_position!()
and error_node_position!()
macros will work.)
You probably want to read Error Management.
Broadly speaking,
nom::error::Error
is a low-overhead type for parser errors, that's why it only has the parser's errors.If you want to attach more context, nom provides a
nom::error::VerboseError
type, there's also ancillary crates which provide further error wrappers.Finally, if that is still not sufficient nom's error handling is based around the
ParseError
trait so you can have a completely custom error type and implement that. The latter option obviously has the highest overhead, but also the highest level of flexibility.