[][src]Derive Macro nom_derive::Nom

#[derive(Nom)]
{
    // Attributes available to this derive:
    #[Parse]
    #[Verify]
    #[Cond]
}

The Nom derive automatically generates a parse function for the structure using nom parsers. It will try to infer parsers for primitive of known types, but also allows you to specify parsers using custom attributes.

Deriving parsers

For simple structures, the parsers are automatically generated:

use nom_derive::Nom;
use nom::{do_parse,IResult,be_u16,be_u32};

#[derive(Debug,PartialEq)] // for assert_eq!
#[derive(Nom)]
struct S {
  a: u32,
  b: u16,
  c: u16
}

let input = b"\x00\x00\x00\x01\x12\x34\x56\x78";
let res = S::parse(input);
assert_eq!(res, Ok((&input[8..],S{a:1,b:0x1234,c:0x5678})));

This also work for tuple structs:

#[derive(Nom)]
struct S(u32);

By default, integers are parsed are Big Endian.

nom-derive is also able to derive default parsers for some usual types:

Option types

If a field is an Option<T>, the generated parser is opt!(complete!(T::parse))

For ex:

#[derive(Nom)]
struct S {
  a: Option<u32>
}

let input = b"\x00\x00\x00\x01";
let res = S::parse(input);
assert_eq!(res, Ok((&input[4..],S{a:Some(1)})));

Vec types

If a field is an Vec<T>, the generated parser is many0!(complete!(T::parse))

For ex:

#[derive(Nom)]
struct S {
  a: Vec<u16>
}

let input = b"\x00\x00\x00\x01";
let res = S::parse(input);
assert_eq!(res, Ok((&input[4..],S{a:vec![0,1]})));

Default parsing function

If a field with type T is not a primitive or known type, the generated parser is call!(T::parse).

This function can be automatically derived, or specified as a method for the struct. In that case, the function must be a static method with the same API as a nom combinator, returning the wrapped struct when parsing succeeds.

Example (using Nom derive):

#[derive(Nom)]
struct S2 {
  c: u16
}

#[derive(Nom)]
struct S {
  a: u16,
  b: S2
}

Example (defining parse method):

// no Nom derive
struct S2 {
  c: u16
}

impl S2 {
    fn parse(i:&[u8]) -> IResult<&[u8],S2> {
        map!(
            i,
            call!(le_u16), // little-endian
            |c| S2{c} // return a struct S2
            )
    }
}

#[derive(Nom)]
struct S {
  a: u16,
  b: S2
}

Specifying parsers

Sometimes, the default parsers generated automatically are not those you want.

The Parse custom attribute allows for specifying the parser, using code that will be inserted in the do_parse block of the nom parser.

#[derive(Nom)]
struct S{
    #[Parse="le_u16"]
    a: u16
}

The Parse argument can be a complex expression:

#[derive(Nom)]
struct S{
    pub a: u8,
    #[Parse="cond!(a > 0,be_u16)"]
    pub b: Option<u16>,
}

Note that you are responsible from providing correct code.

Adding conditions

The Cond custom attribute allows for specifying a condition. The generated parser will use the cond! combinator, which calls the child parser only if the condition is met. The type with this attribute must be an Option type.

#[derive(Nom)]
struct S{
    pub a: u8,
    #[Cond="a == 1"]
    pub b: Option<u16>,
}

Adding verifications

The Verify custom attribute allows for specifying a verifying function. The generated parser will use the verify! combinator, which calls the child parser only if is verifies a condition (and otherwise raises an error).

#[derive(Nom)]
struct S{
    #[Verify="a == 1"]
    pub a: u8,
}

Known problems

The generated parsers use the nom combinators directly, so they must be visible in the current namespace (i.e imported in a use statement).