blob: cf44b4d74977d886e6e0057b699746b1de8631ba [file] [log] [blame]
use super::*;
use delimited::Delimited;
ast_struct! {
/// Struct or enum sent to a `proc_macro_derive` macro.
pub struct DeriveInput {
/// Name of the struct or enum.
pub ident: Ident,
/// Visibility of the struct or enum.
pub vis: Visibility,
/// Attributes tagged on the whole struct or enum.
pub attrs: Vec<Attribute>,
/// Generics required to complete the definition.
pub generics: Generics,
/// Data within the struct or enum.
pub body: Body,
}
}
ast_enum_of_structs! {
/// Body of a derived struct or enum.
pub enum Body {
/// It's an enum.
pub Enum(BodyEnum {
pub enum_token: tokens::Enum,
pub brace_token: tokens::Brace,
pub variants: Delimited<Variant, tokens::Comma>,
}),
/// It's a struct.
pub Struct(BodyStruct {
pub data: VariantData,
pub struct_token: tokens::Struct,
pub semi_token: Option<tokens::Semi>,
}),
}
do_not_generate_to_tokens
}
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
use Generics;
use attr::parsing::outer_attr;
use data::parsing::{visibility, struct_body, enum_body};
use generics::parsing::generics;
use ident::parsing::ident;
named!(pub derive_input -> DeriveInput, do_parse!(
attrs: many0!(outer_attr) >>
vis: visibility >>
which: alt!(keyword!("struct") | keyword!("enum")) >>
id: ident >>
generics: generics >>
item: switch!(value!(which),
"struct" => map!(struct_body, move |(wh, body, semi)| DeriveInput {
ident: id,
vis: vis,
attrs: attrs,
generics: Generics {
where_clause: wh,
.. generics
},
body: Body::Struct(BodyStruct {
struct_token: tokens::Struct::default(),
data: body,
semi_token: semi,
}),
})
|
"enum" => map!(enum_body, move |(wh, body, brace)| DeriveInput {
ident: id,
vis: vis,
attrs: attrs,
generics: Generics {
where_clause: wh,
.. generics
},
body: Body::Enum(BodyEnum {
variants: body,
brace_token: brace,
enum_token: tokens::Enum::default(),
}),
})
) >>
(item)
));
}
#[cfg(feature = "printing")]
mod printing {
use super::*;
use attr::FilterAttrs;
use data::VariantData;
use quote::{Tokens, ToTokens};
impl ToTokens for DeriveInput {
fn to_tokens(&self, tokens: &mut Tokens) {
for attr in self.attrs.outer() {
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),
}
self.ident.to_tokens(tokens);
self.generics.to_tokens(tokens);
match self.body {
Body::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);
}
}
}
}
}