macro_rules! seq {
($($name: ident)::* { $($fields: tt)* }) => { ... };
($($name: ident)::* ( $($elements: tt)* )) => { ... };
(( $($elements: tt)* )) => { ... };
($($elements: tt)*) => { ... };
}
Expand description
Initialize a struct or tuple out of a sequences of parsers
Unlike normal struct initialization syntax:
_
fields can exist to run a parser but ignore the result- Parse results for a field can later be referenced using the field name
Unlike normal tuple initialization syntax:
- Struct-style initialization (
{ 0: _, 1: _}
) is not supported _: <parser>
fields can exist to run a parser but ignore the result
ยงExample
use winnow::combinator::seq;
#[derive(Default, Debug, PartialEq)]
struct Field {
namespace: u32,
name: Vec<u8>,
value: Vec<u8>,
point: (u32, u32),
metadata: Vec<u8>,
}
// Parse into structs / tuple-structs
fn field(input: &mut &[u8]) -> PResult<Field> {
seq!{Field {
namespace: empty.value(5),
name: alphanumeric1.map(|s: &[u8]| s.to_owned()),
// `_` fields are ignored when building the struct
_: (space0, b':', space0),
value: alphanumeric1.map(|s: &[u8]| s.to_owned()),
_: (space0, b':', space0),
point: point,
// default initialization also works
..Default::default()
}}.parse_next(input)
}
// Or parse into tuples
fn point(input: &mut &[u8]) -> PResult<(u32, u32)> {
let num = dec_uint::<_, u32, ContextError>;
seq!(num, _: (space0, b',', space0), num).parse_next(input)
}
assert_eq!(
field.parse_peek(&b"test: data: 123 , 4"[..]),
Ok((
&b""[..],
Field {
namespace: 5,
name: b"test"[..].to_owned(),
value: b"data"[..].to_owned(),
point: (123, 4),
metadata: Default::default(),
},
)),
);