Require exhaustive pattern matching in switch! parser
diff --git a/src/derive.rs b/src/derive.rs
index 9e68d5e..a0c1c8d 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -57,8 +57,7 @@
which: alt!(
syn!(Struct) => { Ok }
|
- // weird hack to get around exhaustiveness check below
- syn!(Enum) => { |e| Err((e, 1)) }
+ syn!(Enum) => { Err }
) >>
id: syn!(Ident) >>
generics: syn!(Generics) >>
@@ -78,7 +77,7 @@
}),
})
|
- Err((e, 1)) => map!(enum_body, move |(wh, body, brace)| DeriveInput {
+ Err(e) => map!(enum_body, move |(wh, body, brace)| DeriveInput {
ident: id,
vis: vis,
attrs: attrs,
diff --git a/synom/src/lib.rs b/synom/src/lib.rs
index f49a59a..9b5fafb 100644
--- a/synom/src/lib.rs
+++ b/synom/src/lib.rs
@@ -488,6 +488,8 @@
/// variant: variant,
/// }
/// )
+/// |
+/// _ => reject!()
/// ) >>
/// (item)
/// ));
@@ -503,7 +505,6 @@
$(
$p => $subrule!(i, $($args2)*),
)*
- _ => $crate::parse_error(),
}
}
};
@@ -520,7 +521,7 @@
/// extern crate syn;
/// #[macro_use] extern crate synom;
///
-/// use syn::{Ident, Ty};
+/// use syn::Ident;
/// use synom::tokens::*;
///
/// #[derive(Debug)]
@@ -536,21 +537,21 @@
///
/// // Parse a unit struct or enum: either `struct S;` or `enum E { V }`.
/// named!(unit_type -> UnitType, do_parse!(
-/// which: alt!(
-/// syn!(Struct) => { |_| 0 }
+/// is_struct: alt!(
+/// syn!(Struct) => { |_| true }
/// |
-/// syn!(Enum) => { |_| 1 }
+/// syn!(Enum) => { |_| false }
/// ) >>
/// id: syn!(Ident) >>
-/// item: switch!(value!(which),
-/// 0 => map!(
+/// item: switch!(value!(is_struct),
+/// true => map!(
/// syn!(Semi),
/// move |_| UnitType::Struct {
/// name: id,
/// }
/// )
/// |
-/// 1 => map!(
+/// false => map!(
/// braces!(syn!(Ident)),
/// move |(variant, _)| UnitType::Enum {
/// name: id,
@@ -570,6 +571,36 @@
};
}
+/// Unconditionally fail to parse anything. This may be useful in ignoring some
+/// arms of a `switch!` parser.
+///
+/// - **Syntax:** `reject!()`
+/// - **Output:** never succeeds
+///
+/// ```rust
+/// extern crate syn;
+/// #[macro_use] extern crate synom;
+///
+/// use syn::Item;
+///
+/// // Parse any item, except for a module.
+/// named!(almost_any_item -> Item,
+/// switch!(syn!(Item),
+/// Item::Mod(_) => reject!()
+/// |
+/// ok => value!(ok)
+/// )
+/// );
+///
+/// # fn main() {}
+/// ```
+#[macro_export]
+macro_rules! reject {
+ ($i:expr,) => {
+ $crate::parse_error()
+ }
+}
+
/// Run a series of parsers and produce all of the results in a tuple.
///
/// - **Syntax:** `tuple!(A, B, C, ...)`