rustparser-combinatorsnom

Custom Nom parser error without custom ErrorKind


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.)


Solution

  • 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.