[][src]Macro der_parser::parse_der_struct

macro_rules! parse_der_struct {
    ($i:expr, TAG $tag:expr, $($rest:tt)*) => { ... };
    ($i:expr, $($rest:tt)*) => { ... };
}

Parse a constructed DER element

Read a constructed DER element (sequence or set, typically) using the provided functions. This is generally used to build a struct from a DER sequence.

The returned object is a tuple containing a BerObjectHeader and the object returned by the subparser.

To ensure the subparser consumes all bytes from the constructed object, add the empty!() subparser as the last parsing item.

To verify the tag of the constructed element, use the TAG version, for ex parse_der_struct!(i, TAG DerTag::Sequence, parse_der_integer)

Similar to parse_der_sequence_defined, but using the do_parse macro from nom. This allows declaring variables, and running code at the end.

Examples

Basic struct parsing (ignoring tag):

use der_parser::ber::*;
use nom::{IResult,Err,ErrorKind};

#[derive(Debug, PartialEq)]
struct MyStruct<'a>{
    a: BerObject<'a>,
    b: BerObject<'a>,
}

fn parse_struct01(i: &[u8]) -> IResult<&[u8],(BerObjectHeader,MyStruct)> {
    parse_der_struct!(
        i,
        a: parse_ber_integer >>
        b: parse_ber_integer >>
           empty!() >>
        ( MyStruct{ a: a, b: b } )
    )
}

let bytes = [ 0x30, 0x0a,
              0x02, 0x03, 0x01, 0x00, 0x01,
              0x02, 0x03, 0x01, 0x00, 0x00,
];
let empty = &b""[..];
let expected = (
    BerObjectHeader{
        class: 0,
        structured: 1,
        tag: BerTag::Sequence,
        len: 0xa,
    },
    MyStruct {
        a: BerObject::from_int_slice(b"\x01\x00\x01"),
        b: BerObject::from_int_slice(b"\x01\x00\x00"),
    }
);
let res = parse_struct01(&bytes);
assert_eq!(res, Ok((empty, expected)));

To check the expected tag, use the TAG <tagname> variant:

struct MyStruct<'a>{
    a: BerObject<'a>,
    b: BerObject<'a>,
}

fn parse_struct_with_tag(i: &[u8]) -> IResult<&[u8],(BerObjectHeader,MyStruct)> {
    parse_der_struct!(
        i,
        TAG BerTag::Sequence,
        a: parse_ber_integer >>
        b: parse_ber_integer >>
           empty!() >>
        ( MyStruct{ a: a, b: b } )
    )
}