1use super::*;
10use punctuated::Punctuated;
11
12ast_struct! {
13 pub struct DeriveInput {
17 pub attrs: Vec<Attribute>,
19
20 pub vis: Visibility,
22
23 pub ident: Ident,
25
26 pub generics: Generics,
28
29 pub data: Data,
31 }
32}
33
34ast_enum_of_structs! {
35 pub enum Data {
45 pub Struct(DataStruct {
50 pub struct_token: Token![struct],
51 pub fields: Fields,
52 pub semi_token: Option<Token![;]>,
53 }),
54
55 pub Enum(DataEnum {
60 pub enum_token: Token![enum],
61 pub brace_token: token::Brace,
62 pub variants: Punctuated<Variant, Token![,]>,
63 }),
64
65 pub Union(DataUnion {
70 pub union_token: Token![union],
71 pub fields: FieldsNamed,
72 }),
73 }
74
75 do_not_generate_to_tokens
76}
77
78#[cfg(feature = "parsing")]
79pub mod parsing {
80 use super::*;
81
82 use synom::Synom;
83
84 impl Synom for DeriveInput {
85 named!(parse -> Self, do_parse!(
86 attrs: many0!(Attribute::parse_outer) >>
87 vis: syn!(Visibility) >>
88 which: alt!(
89 keyword!(struct) => { Ok }
90 |
91 keyword!(enum) => { Err }
92 ) >>
93 id: syn!(Ident) >>
94 generics: syn!(Generics) >>
95 item: switch!(value!(which),
96 Ok(s) => map!(data_struct, move |(wh, fields, semi)| DeriveInput {
97 ident: id,
98 vis: vis,
99 attrs: attrs,
100 generics: Generics {
101 where_clause: wh,
102 .. generics
103 },
104 data: Data::Struct(DataStruct {
105 struct_token: s,
106 fields: fields,
107 semi_token: semi,
108 }),
109 })
110 |
111 Err(e) => map!(data_enum, move |(wh, brace, variants)| DeriveInput {
112 ident: id,
113 vis: vis,
114 attrs: attrs,
115 generics: Generics {
116 where_clause: wh,
117 .. generics
118 },
119 data: Data::Enum(DataEnum {
120 variants: variants,
121 brace_token: brace,
122 enum_token: e,
123 }),
124 })
125 ) >>
126 (item)
127 ));
128
129 fn description() -> Option<&'static str> {
130 Some("derive input")
131 }
132 }
133
134 named!(data_struct -> (Option<WhereClause>, Fields, Option<Token![;]>), alt!(
135 do_parse!(
136 wh: option!(syn!(WhereClause)) >>
137 fields: syn!(FieldsNamed) >>
138 (wh, Fields::Named(fields), None)
139 )
140 |
141 do_parse!(
142 fields: syn!(FieldsUnnamed) >>
143 wh: option!(syn!(WhereClause)) >>
144 semi: punct!(;) >>
145 (wh, Fields::Unnamed(fields), Some(semi))
146 )
147 |
148 do_parse!(
149 wh: option!(syn!(WhereClause)) >>
150 semi: punct!(;) >>
151 (wh, Fields::Unit, Some(semi))
152 )
153 ));
154
155 named!(data_enum -> (Option<WhereClause>, token::Brace, Punctuated<Variant, Token![,]>), do_parse!(
156 wh: option!(syn!(WhereClause)) >>
157 data: braces!(Punctuated::parse_terminated) >>
158 (wh, data.0, data.1)
159 ));
160}
161
162#[cfg(feature = "printing")]
163mod printing {
164 use super::*;
165 use attr::FilterAttrs;
166 use quote::{ToTokens, Tokens};
167
168 impl ToTokens for DeriveInput {
169 fn to_tokens(&self, tokens: &mut Tokens) {
170 for attr in self.attrs.outer() {
171 attr.to_tokens(tokens);
172 }
173 self.vis.to_tokens(tokens);
174 match self.data {
175 Data::Struct(ref d) => d.struct_token.to_tokens(tokens),
176 Data::Enum(ref d) => d.enum_token.to_tokens(tokens),
177 Data::Union(ref d) => d.union_token.to_tokens(tokens),
178 }
179 self.ident.to_tokens(tokens);
180 self.generics.to_tokens(tokens);
181 match self.data {
182 Data::Struct(ref data) => match data.fields {
183 Fields::Named(ref fields) => {
184 self.generics.where_clause.to_tokens(tokens);
185 fields.to_tokens(tokens);
186 }
187 Fields::Unnamed(ref fields) => {
188 fields.to_tokens(tokens);
189 self.generics.where_clause.to_tokens(tokens);
190 TokensOrDefault(&data.semi_token).to_tokens(tokens);
191 }
192 Fields::Unit => {
193 self.generics.where_clause.to_tokens(tokens);
194 TokensOrDefault(&data.semi_token).to_tokens(tokens);
195 }
196 },
197 Data::Enum(ref data) => {
198 self.generics.where_clause.to_tokens(tokens);
199 data.brace_token.surround(tokens, |tokens| {
200 data.variants.to_tokens(tokens);
201 });
202 }
203 Data::Union(ref data) => {
204 self.generics.where_clause.to_tokens(tokens);
205 data.fields.to_tokens(tokens);
206 }
207 }
208 }
209 }
210}