Parse

Trait Parse 

Source
pub trait Parse<I, E = Error<I>>
where I: InputSlice, E: ParseError<I>, Self: Sized,
{ // Required method fn parse(i: I) -> IResult<I, Self, E>; // Provided methods fn parse_be(i: I) -> IResult<I, Self, E> { ... } fn parse_le(i: I) -> IResult<I, Self, E> { ... } }
Expand description

Common trait for all parsers in nom-derive

This trait is used to provide parser implementations, usually as generic as possible for the error type. Implementations are provided for common and primitive types. The only required method is parse, but it is advised to implement the parse_be and parse_le methods. Derived code will call one of these methods, depending on the field endianness.

§Example

A possible implementation for the type u32 is:

impl<I, E> Parse<I, E> for u32
where
    E: ParseError<I>,
    I: InputSlice,
{
    fn parse(i: I) -> IResult<I, Self, E> { be_u32(i) } // default to big-endian
    fn parse_be(i: I) -> IResult<I, Self, E> { be_u32(i) }
    fn parse_le(i: I) -> IResult<I, Self, E> { le_u32(i) }
}

§Generic type parameters and input

Note: I is a generic type that is mostly equivalent to &'a [u8]. It is used to “hide” the lifetime of the input slice &'a [u8] and simplify traits implementation and generation of derived code.

It is possible to implement the Parse trait only for &[u8] if the implementation contains non-generic functions.

For example, the implementation for String is:

impl<'a, E> Parse<&'a [u8], E> for String
where
    E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], std::str::Utf8Error>,
{
    fn parse(i: &'a [u8]) -> IResult<&'a [u8], Self, E> {
        let (rem, sz) = <u32>::parse(i)?;
        let (rem, s) = map_res(take(sz as usize), std::str::from_utf8)(rem)?;
        Ok((rem, s.to_owned()))
    }
}

§Implementing primitives or specific types

To implement an existing type differently, or a type where implementation was not provided, a common way is to use a newtype pattern:

use nom_derive::{Parse, nom};

use nom::IResult;
use nom::bytes::complete::take;
use nom::combinator::map_res;
use nom::error::{Error, FromExternalError, ParseError};

pub struct MyString(pub String);
impl<'a, E> Parse<&'a [u8], E> for MyString
where
    E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], std::str::Utf8Error>,
{
    fn parse(i: &'a [u8]) -> IResult<&'a [u8], Self, E> {
        let (rem, sz) = <u32>::parse(i)?;
        let (rem, s) = map_res(take(sz as usize), std::str::from_utf8)(rem)?;
        Ok((rem, MyString(s.to_owned())))
    }
}

// error type cannot be inferred by compiler and must be explicit
let res: IResult<_, _, Error<_>> = MyString::parse(input);

Required Methods§

Source

fn parse(i: I) -> IResult<I, Self, E>

Parse input, not knowing the endianness

Usually, this means choosing between big and little-endian. Default implementations for common types are big-endian.

Provided Methods§

Source

fn parse_be(i: I) -> IResult<I, Self, E>

Parse input as Big-Endian

Source

fn parse_le(i: I) -> IResult<I, Self, E>

Parse input as Little-Endian

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<'a, E> Parse<&'a [u8], E> for String
where E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], Utf8Error>,

Source§

fn parse(i: &'a [u8]) -> IResult<&'a [u8], Self, E>

Source§

impl<I, E> Parse<I, E> for f32
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for f64
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for i8
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for i16
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for i32
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for i64
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for i128
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for u8
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for u16
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for u32
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for u64
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<I, E> Parse<I, E> for u128
where E: ParseError<I>, I: InputSlice,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<T1, T2, I, E> Parse<I, E> for (T1, T2)
where I: Clone + PartialEq + InputSlice, E: ParseError<I>, T1: Parse<I, E>, T2: Parse<I, E>,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<T, I, E> Parse<I, E> for Option<T>
where I: Clone + InputSlice, E: ParseError<I>, T: Parse<I, E>,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<T, I, E> Parse<I, E> for Vec<T>
where I: Clone + PartialEq + InputSlice, E: ParseError<I>, T: Parse<I, E>,

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Source§

impl<T, I, E, const N: usize> Parse<I, E> for [T; N]
where I: Clone + PartialEq + InputSlice, E: ParseError<I> + FromExternalError<I, Vec<T>>, T: Parse<I, E>,

Note: this implementation uses const generics and requires rust >= 1.51

Source§

fn parse(i: I) -> IResult<I, Self, E>

Source§

fn parse_be(i: I) -> IResult<I, Self, E>

Source§

fn parse_le(i: I) -> IResult<I, Self, E>

Implementors§

Source§

impl<L, I, E> Parse<I, E> for LengthData<L, I>
where I: Clone + PartialEq + InputSlice, E: ParseError<I>, L: Parse<I, E> + ToUsize,