Reorganize DeriveInput
diff --git a/src/data.rs b/src/data.rs
index f1e0c76..6777767 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -10,25 +10,32 @@
/// Name of the variant.
pub ident: Ident,
- /// Type of variant.
- pub data: VariantData,
+ /// Content stored in the variant.
+ pub fields: Fields,
/// Explicit discriminant, e.g. `Foo = 1`
pub discriminant: Option<(Token![=], Expr)>,
}
}
-ast_enum! {
+ast_enum_of_structs! {
/// Data stored within an enum variant or struct.
- pub enum VariantData {
- /// Struct variant, e.g. `Point { x: f64, y: f64 }`.
- Struct(token::Brace, Delimited<Field, Token![,]>),
+ pub enum Fields {
+ /// Named fields of a struct or struct variant such as `Point { x: f64,
+ /// y: f64 }`.
+ pub Named(FieldsNamed {
+ pub brace_token: token::Brace,
+ pub fields: Delimited<Field, Token![,]>,
+ }),
- /// Tuple variant, e.g. `Some(T)`.
- Tuple(token::Paren, Delimited<Field, Token![,]>),
+ /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
+ pub Unnamed(FieldsUnnamed {
+ pub paren_token: token::Paren,
+ pub fields: Delimited<Field, Token![,]>,
+ }),
- /// Unit variant, e.g. `None`.
- Unit,
+ /// Unit struct or unit variant such as `None`.
+ pub Unit,
}
}
@@ -87,8 +94,53 @@
use synom::Synom;
+ impl Synom for Variant {
+ named!(parse -> Self, do_parse!(
+ attrs: many0!(Attribute::parse_outer) >>
+ id: syn!(Ident) >>
+ fields: alt!(
+ syn!(FieldsNamed) => { Fields::Named }
+ |
+ syn!(FieldsUnnamed) => { Fields::Unnamed }
+ |
+ epsilon!() => { |_| Fields::Unit }
+ ) >>
+ disr: option!(tuple!(punct!(=), syn!(Expr))) >>
+ (Variant {
+ ident: id,
+ attrs: attrs,
+ fields: fields,
+ discriminant: disr,
+ })
+ ));
+
+ fn description() -> Option<&'static str> {
+ Some("enum variant")
+ }
+ }
+
+ impl Synom for FieldsNamed {
+ named!(parse -> Self, map!(
+ braces!(call!(Delimited::parse_terminated_with, Field::parse_named)),
+ |(brace, fields)| FieldsNamed {
+ brace_token: brace,
+ fields: fields,
+ }
+ ));
+ }
+
+ impl Synom for FieldsUnnamed {
+ named!(parse -> Self, map!(
+ parens!(call!(Delimited::parse_terminated_with, Field::parse_unnamed)),
+ |(paren, fields)| FieldsUnnamed {
+ paren_token: paren,
+ fields: fields,
+ }
+ ));
+ }
+
impl Field {
- named!(pub parse_struct -> Self, do_parse!(
+ named!(pub parse_named -> Self, do_parse!(
attrs: many0!(Attribute::parse_outer) >>
vis: syn!(Visibility) >>
id: syn!(Ident) >>
@@ -103,7 +155,7 @@
})
));
- named!(pub parse_tuple -> Self, do_parse!(
+ named!(pub parse_unnamed -> Self, do_parse!(
attrs: many0!(Attribute::parse_outer) >>
vis: syn!(Visibility) >>
ty: syn!(Type) >>
@@ -190,7 +242,7 @@
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(&self.attrs);
self.ident.to_tokens(tokens);
- self.data.to_tokens(tokens);
+ self.fields.to_tokens(tokens);
if let Some((ref eq_token, ref disc)) = self.discriminant {
eq_token.to_tokens(tokens);
disc.to_tokens(tokens);
@@ -198,21 +250,19 @@
}
}
- impl ToTokens for VariantData {
+ impl ToTokens for FieldsNamed {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- VariantData::Struct(ref brace, ref fields) => {
- brace.surround(tokens, |tokens| {
- fields.to_tokens(tokens);
- });
- }
- VariantData::Tuple(ref paren, ref fields) => {
- paren.surround(tokens, |tokens| {
- fields.to_tokens(tokens);
- });
- }
- VariantData::Unit => {}
- }
+ self.brace_token.surround(tokens, |tokens| {
+ self.fields.to_tokens(tokens);
+ });
+ }
+ }
+
+ impl ToTokens for FieldsUnnamed {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.paren_token.surround(tokens, |tokens| {
+ self.fields.to_tokens(tokens);
+ });
}
}