diff --git a/src/macros/seq.rs b/src/macros/seq.rs index 0ffe4f9a..a9991c9d 100644 --- a/src/macros/seq.rs +++ b/src/macros/seq.rs @@ -1,5 +1,13 @@ /// 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 +/// - `_: ` fields can exist to run a parser but ignore the result +/// ///# Example /// /// ``` @@ -53,39 +61,6 @@ /// }, /// )), /// ); -/// -/// // Or parse into enum variants -/// #[derive(Debug, PartialEq, Eq)] -/// enum Expr { -/// Add { lhs: u32, rhs: u32 }, -/// Mul(u32, u32), -/// } -/// -/// fn add(input: &mut &[u8]) -> PResult { -/// seq!{Expr::Add { -/// lhs: dec_uint::<_, u32, ContextError>, -/// _: b" + ", -/// rhs: dec_uint::<_, u32, ContextError>, -/// }}.parse_next(input) -/// } -/// -/// fn mul(input: &mut &[u8]) -> PResult { -/// seq!(Expr::Mul( -/// dec_uint::<_, u32, ContextError>, -/// _: b" * ", -/// dec_uint::<_, u32, ContextError>, -/// )).parse_next(input) -/// } -/// -/// assert_eq!( -/// add.parse_peek(&b"1 + 2"[..]), -/// Ok((&b""[..], Expr::Add { lhs: 1, rhs: 2 })), -/// ); -/// -/// assert_eq!( -/// mul.parse_peek(&b"3 * 4"[..]), -/// Ok((&b""[..], Expr::Mul(3, 4))), -/// ); /// ``` #[macro_export] #[doc(alias = "tuple")] @@ -99,7 +74,6 @@ macro_rules! seq { ($($name: ident)::* { $($fields: tt)* }) => { $crate::combinator::trace(stringify!($($name)::*), move |input: &mut _| { - use $crate::Parser; $crate::seq_parse_struct_fields!(input; $($fields)*); #[allow(clippy::redundant_field_names)] Ok($crate::seq_init_struct_fields!( ($($fields)*); $($name)::*;)) @@ -107,7 +81,6 @@ macro_rules! seq { }; ($($name: ident)::* ( $($elements: tt)* )) => { $crate::combinator::trace(stringify!($($name)::*), move |input: &mut _| { - use $crate::Parser; $crate::seq_parse_tuple_fields!( ($($elements)*) ; ).map(|t| { $crate::seq_init_tuple_fields!( ($($elements)*); @@ -141,27 +114,27 @@ macro_rules! seq_parse_struct_fields { $input: ident; _ : $head_parser: expr, $($fields: tt)* ) => { - let _ = $head_parser.parse_next($input)?; + let _ = $crate::Parser::parse_next(&mut $head_parser, $input)?; $crate::seq_parse_struct_fields!($input; $($fields)*) }; ( $input: ident; _ : $head_parser: expr ) => { - let _ = $head_parser.parse_next($input)?; + let _ = $crate::Parser::parse_next(&mut $head_parser, $input)?; }; ( $input: ident; $head_field: ident : $head_parser: expr, $($fields: tt)* ) => { - let $head_field = $head_parser.parse_next($input)?; + let $head_field = $crate::Parser::parse_next(&mut $head_parser, $input)?; $crate::seq_parse_struct_fields!($input; $($fields)*) }; ( $input: ident; $head_field: ident : $head_parser: expr ) => { - let $head_field = $head_parser.parse_next($input)?; + let $head_field = $crate::Parser::parse_next(&mut $head_parser, $input)?; }; ( $input: expr; diff --git a/src/macros/test.rs b/src/macros/test.rs index 17601bc3..ef50133f 100644 --- a/src/macros/test.rs +++ b/src/macros/test.rs @@ -187,6 +187,43 @@ fn seq_struct_no_trailing_comma_elided() { } } +#[test] +fn seq_enum_struct_variant() { + #[derive(Debug, PartialEq, Eq)] + enum Expr { + Add { lhs: u32, rhs: u32 }, + Mul(u32, u32), + } + + fn add(input: &mut &[u8]) -> PResult { + seq! {Expr::Add { + lhs: dec_uint::<_, u32, _>, + _: b" + ", + rhs: dec_uint::<_, u32, _>, + }} + .parse_next(input) + } + + fn mul(input: &mut &[u8]) -> PResult { + seq!(Expr::Mul( + dec_uint::<_, u32, _>, + _: b" * ", + dec_uint::<_, u32, _>, + )) + .parse_next(input) + } + + assert_eq!( + add.parse_peek(&b"1 + 2"[..]), + Ok((&b""[..], Expr::Add { lhs: 1, rhs: 2 })), + ); + + assert_eq!( + mul.parse_peek(&b"3 * 4"[..]), + Ok((&b""[..], Expr::Mul(3, 4))), + ); +} + #[test] fn seq_tuple_struct_basics() { #[derive(Debug, PartialEq)]