Reorganize DeriveInput
diff --git a/src/derive.rs b/src/derive.rs
index cf4a3d1..7b58523 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -2,7 +2,7 @@
use delimited::Delimited;
ast_struct! {
- /// Struct or enum sent to a `proc_macro_derive` macro.
+ /// Data structure sent to a `proc_macro_derive` macro.
pub struct DeriveInput {
/// Attributes tagged on the whole struct or enum.
pub attrs: Vec<Attribute>,
@@ -17,25 +17,31 @@
pub generics: Generics,
/// Data within the struct or enum.
- pub body: Body,
+ pub data: Data,
}
}
ast_enum_of_structs! {
- /// Body of a derived struct or enum.
- pub enum Body {
+ /// The storage of a struct, enum or union data structure.
+ pub enum Data {
+ /// It's a struct.
+ pub Struct(DataStruct {
+ pub struct_token: Token![struct],
+ pub fields: Fields,
+ pub semi_token: Option<Token![;]>,
+ }),
+
/// It's an enum.
- pub Enum(BodyEnum {
+ pub Enum(DataEnum {
pub enum_token: Token![enum],
pub brace_token: token::Brace,
pub variants: Delimited<Variant, Token![,]>,
}),
- /// It's a struct.
- pub Struct(BodyStruct {
- pub data: VariantData,
- pub struct_token: Token![struct],
- pub semi_token: Option<Token![;]>,
+ /// It's an untagged union.
+ pub Union(DataUnion {
+ pub union_token: Token![union],
+ pub fields: FieldsNamed,
}),
}
@@ -60,7 +66,7 @@
id: syn!(Ident) >>
generics: syn!(Generics) >>
item: switch!(value!(which),
- Ok(s) => map!(struct_body, move |(wh, body, semi)| DeriveInput {
+ Ok(s) => map!(data_struct, move |(wh, fields, semi)| DeriveInput {
ident: id,
vis: vis,
attrs: attrs,
@@ -68,14 +74,14 @@
where_clause: wh,
.. generics
},
- body: Body::Struct(BodyStruct {
+ data: Data::Struct(DataStruct {
struct_token: s,
- data: body,
+ fields: fields,
semi_token: semi,
}),
})
|
- Err(e) => map!(enum_body, move |(wh, brace, body)| DeriveInput {
+ Err(e) => map!(data_enum, move |(wh, brace, variants)| DeriveInput {
ident: id,
vis: vis,
attrs: attrs,
@@ -83,8 +89,8 @@
where_clause: wh,
.. generics
},
- body: Body::Enum(BodyEnum {
- variants: body,
+ data: Data::Enum(DataEnum {
+ variants: variants,
brace_token: brace,
enum_token: e,
}),
@@ -98,70 +104,38 @@
}
}
- named!(struct_body -> (Option<WhereClause>, VariantData, Option<Token![;]>), alt!(
+ named!(data_struct -> (Option<WhereClause>, Fields, Option<Token![;]>), alt!(
do_parse!(
wh: option!(syn!(WhereClause)) >>
- body: struct_like_body >>
- (wh, VariantData::Struct(body.0, body.1), None)
+ fields: syn!(FieldsNamed) >>
+ (wh, Fields::Named(fields), None)
)
|
do_parse!(
- body: tuple_like_body >>
+ fields: syn!(FieldsUnnamed) >>
wh: option!(syn!(WhereClause)) >>
semi: punct!(;) >>
- (wh, VariantData::Tuple(body.0, body.1), Some(semi))
+ (wh, Fields::Unnamed(fields), Some(semi))
)
|
do_parse!(
wh: option!(syn!(WhereClause)) >>
semi: punct!(;) >>
- (wh, VariantData::Unit, Some(semi))
+ (wh, Fields::Unit, Some(semi))
)
));
- named!(enum_body -> (Option<WhereClause>, token::Brace, Delimited<Variant, Token![,]>), do_parse!(
+ named!(data_enum -> (Option<WhereClause>, token::Brace, Delimited<Variant, Token![,]>), do_parse!(
wh: option!(syn!(WhereClause)) >>
data: braces!(Delimited::parse_terminated) >>
(wh, data.0, data.1)
));
-
- impl Synom for Variant {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- id: syn!(Ident) >>
- data: alt!(
- struct_like_body => { |(b, d)| VariantData::Struct(b, d) }
- |
- tuple_like_body => { |(b, d)| VariantData::Tuple(b, d) }
- |
- epsilon!() => { |_| VariantData::Unit }
- ) >>
- disr: option!(tuple!(punct!(=), syn!(Expr))) >>
- (Variant {
- ident: id,
- attrs: attrs,
- data: data,
- discriminant: disr,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("enum variant")
- }
- }
-
- named!(struct_like_body -> (token::Brace, Delimited<Field, Token![,]>),
- braces!(call!(Delimited::parse_terminated_with, Field::parse_struct)));
-
- named!(tuple_like_body -> (token::Paren, Delimited<Field, Token![,]>),
- parens!(call!(Delimited::parse_terminated_with, Field::parse_tuple)));
}
#[cfg(feature = "printing")]
mod printing {
use super::*;
use attr::FilterAttrs;
- use data::VariantData;
use quote::{ToTokens, Tokens};
impl ToTokens for DeriveInput {
@@ -170,34 +144,40 @@
attr.to_tokens(tokens);
}
self.vis.to_tokens(tokens);
- match self.body {
- Body::Enum(ref d) => d.enum_token.to_tokens(tokens),
- Body::Struct(ref d) => d.struct_token.to_tokens(tokens),
+ match self.data {
+ Data::Struct(ref d) => d.struct_token.to_tokens(tokens),
+ Data::Enum(ref d) => d.enum_token.to_tokens(tokens),
+ Data::Union(ref d) => d.union_token.to_tokens(tokens),
}
self.ident.to_tokens(tokens);
self.generics.to_tokens(tokens);
- match self.body {
- Body::Enum(ref data) => {
+ match self.data {
+ Data::Struct(ref data) => {
+ match data.fields {
+ Fields::Named(ref fields) => {
+ self.generics.where_clause.to_tokens(tokens);
+ fields.to_tokens(tokens);
+ }
+ Fields::Unnamed(ref fields) => {
+ fields.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ TokensOrDefault(&data.semi_token).to_tokens(tokens);
+ }
+ Fields::Unit => {
+ self.generics.where_clause.to_tokens(tokens);
+ TokensOrDefault(&data.semi_token).to_tokens(tokens);
+ }
+ }
+ }
+ Data::Enum(ref data) => {
self.generics.where_clause.to_tokens(tokens);
data.brace_token.surround(tokens, |tokens| {
data.variants.to_tokens(tokens);
});
}
- Body::Struct(ref data) => {
- match data.data {
- VariantData::Struct(..) => {
- self.generics.where_clause.to_tokens(tokens);
- data.data.to_tokens(tokens);
- }
- VariantData::Tuple(..) => {
- data.data.to_tokens(tokens);
- self.generics.where_clause.to_tokens(tokens);
- }
- VariantData::Unit => {
- self.generics.where_clause.to_tokens(tokens);
- }
- }
- data.semi_token.to_tokens(tokens);
+ Data::Union(ref data) => {
+ self.generics.where_clause.to_tokens(tokens);
+ data.fields.to_tokens(tokens);
}
}
}