1 use super::*;
2 
3 /// Struct or enum sent to a `proc_macro_derive` macro.
4 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
5 pub struct DeriveInput {
6     /// Name of the struct or enum.
7     pub ident: Ident,
8 
9     /// Visibility of the struct or enum.
10     pub vis: Visibility,
11 
12     /// Attributes tagged on the whole struct or enum.
13     pub attrs: Vec<Attribute>,
14 
15     /// Generics required to complete the definition.
16     pub generics: Generics,
17 
18     /// Data within the struct or enum.
19     pub body: Body,
20 }
21 
22 /// Body of a derived struct or enum.
23 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
24 pub enum Body {
25     /// It's an enum.
26     Enum(Vec<Variant>),
27 
28     /// It's a struct.
29     Struct(VariantData),
30 }
31 
32 #[cfg(feature = "parsing")]
33 pub mod parsing {
34     use super::*;
35     use Generics;
36     use attr::parsing::outer_attr;
37     use data::parsing::{visibility, struct_body, enum_body};
38     use generics::parsing::generics;
39     use ident::parsing::ident;
40 
41     named!(pub derive_input -> DeriveInput, do_parse!(
42         attrs: many0!(outer_attr) >>
43         vis: visibility >>
44         which: alt!(keyword!("struct") | keyword!("enum")) >>
45         id: ident >>
46         generics: generics >>
47         item: switch!(value!(which),
48             "struct" => map!(struct_body, move |(wh, body)| DeriveInput {
49                 ident: id,
50                 vis: vis,
51                 attrs: attrs,
52                 generics: Generics {
53                     where_clause: wh,
54                     .. generics
55                 },
56                 body: Body::Struct(body),
57             })
58             |
59             "enum" => map!(enum_body, move |(wh, body)| DeriveInput {
60                 ident: id,
61                 vis: vis,
62                 attrs: attrs,
63                 generics: Generics {
64                     where_clause: wh,
65                     .. generics
66                 },
67                 body: Body::Enum(body),
68             })
69         ) >>
70         (item)
71     ));
72 }
73 
74 #[cfg(feature = "printing")]
75 mod printing {
76     use super::*;
77     use attr::FilterAttrs;
78     use data::VariantData;
79     use quote::{Tokens, ToTokens};
80 
81     impl ToTokens for DeriveInput {
to_tokens(&self, tokens: &mut Tokens)82         fn to_tokens(&self, tokens: &mut Tokens) {
83             for attr in self.attrs.outer() {
84                 attr.to_tokens(tokens);
85             }
86             self.vis.to_tokens(tokens);
87             match self.body {
88                 Body::Enum(_) => tokens.append("enum"),
89                 Body::Struct(_) => tokens.append("struct"),
90             }
91             self.ident.to_tokens(tokens);
92             self.generics.to_tokens(tokens);
93             match self.body {
94                 Body::Enum(ref variants) => {
95                     self.generics.where_clause.to_tokens(tokens);
96                     tokens.append("{");
97                     for variant in variants {
98                         variant.to_tokens(tokens);
99                         tokens.append(",");
100                     }
101                     tokens.append("}");
102                 }
103                 Body::Struct(ref variant_data) => {
104                     match *variant_data {
105                         VariantData::Struct(_) => {
106                             self.generics.where_clause.to_tokens(tokens);
107                             variant_data.to_tokens(tokens);
108                             // no semicolon
109                         }
110                         VariantData::Tuple(_) => {
111                             variant_data.to_tokens(tokens);
112                             self.generics.where_clause.to_tokens(tokens);
113                             tokens.append(";");
114                         }
115                         VariantData::Unit => {
116                             self.generics.where_clause.to_tokens(tokens);
117                             tokens.append(";");
118                         }
119                     }
120                 }
121             }
122         }
123     }
124 }
125