1use super::*;
10use punctuated::Punctuated;
11
12ast_struct! {
13 pub struct Variant {
18 pub attrs: Vec<Attribute>,
20
21 pub ident: Ident,
23
24 pub fields: Fields,
26
27 pub discriminant: Option<(Token![=], Expr)>,
29 }
30}
31
32ast_enum_of_structs! {
33 pub enum Fields {
44 pub Named(FieldsNamed {
50 pub brace_token: token::Brace,
51 pub named: Punctuated<Field, Token![,]>,
52 }),
53
54 pub Unnamed(FieldsUnnamed {
59 pub paren_token: token::Paren,
60 pub unnamed: Punctuated<Field, Token![,]>,
61 }),
62
63 pub Unit,
65 }
66}
67
68impl Fields {
69 pub fn iter(&self) -> punctuated::Iter<Field, Token![,]> {
75 match *self {
76 Fields::Unit => punctuated::Iter::private_empty(),
77 Fields::Named(ref f) => f.named.iter(),
78 Fields::Unnamed(ref f) => f.unnamed.iter(),
79 }
80 }
81}
82
83impl<'a> IntoIterator for &'a Fields {
84 type Item = &'a Field;
85 type IntoIter = punctuated::Iter<'a, Field, Token![,]>;
86
87 fn into_iter(self) -> Self::IntoIter {
88 self.iter()
89 }
90}
91
92ast_struct! {
93 pub struct Field {
98 pub attrs: Vec<Attribute>,
100
101 pub vis: Visibility,
103
104 pub ident: Option<Ident>,
108
109 pub colon_token: Option<Token![:]>,
110
111 pub ty: Type,
113 }
114}
115
116ast_enum_of_structs! {
117 pub enum Visibility {
129 pub Public(VisPublic {
134 pub pub_token: Token![pub],
135 }),
136
137 pub Crate(VisCrate {
142 pub pub_token: Token![pub],
143 pub paren_token: token::Paren,
144 pub crate_token: Token![crate],
145 }),
146
147 pub Restricted(VisRestricted {
153 pub pub_token: Token![pub],
154 pub paren_token: token::Paren,
155 pub in_token: Option<Token![in]>,
156 pub path: Box<Path>,
157 }),
158
159 pub Inherited,
161 }
162}
163
164#[cfg(feature = "parsing")]
165pub mod parsing {
166 use super::*;
167
168 use synom::Synom;
169
170 impl Synom for Variant {
171 named!(parse -> Self, do_parse!(
172 attrs: many0!(Attribute::parse_outer) >>
173 id: syn!(Ident) >>
174 fields: alt!(
175 syn!(FieldsNamed) => { Fields::Named }
176 |
177 syn!(FieldsUnnamed) => { Fields::Unnamed }
178 |
179 epsilon!() => { |_| Fields::Unit }
180 ) >>
181 disr: option!(tuple!(punct!(=), syn!(Expr))) >>
182 (Variant {
183 ident: id,
184 attrs: attrs,
185 fields: fields,
186 discriminant: disr,
187 })
188 ));
189
190 fn description() -> Option<&'static str> {
191 Some("enum variant")
192 }
193 }
194
195 impl Synom for FieldsNamed {
196 named!(parse -> Self, map!(
197 braces!(call!(Punctuated::parse_terminated_with, Field::parse_named)),
198 |(brace, fields)| FieldsNamed {
199 brace_token: brace,
200 named: fields,
201 }
202 ));
203
204 fn description() -> Option<&'static str> {
205 Some("named fields in a struct or struct variant")
206 }
207 }
208
209 impl Synom for FieldsUnnamed {
210 named!(parse -> Self, map!(
211 parens!(call!(Punctuated::parse_terminated_with, Field::parse_unnamed)),
212 |(paren, fields)| FieldsUnnamed {
213 paren_token: paren,
214 unnamed: fields,
215 }
216 ));
217
218 fn description() -> Option<&'static str> {
219 Some("unnamed fields in a tuple struct or tuple variant")
220 }
221 }
222
223 impl Field {
224 named!(pub parse_named -> Self, do_parse!(
225 attrs: many0!(Attribute::parse_outer) >>
226 vis: syn!(Visibility) >>
227 id: syn!(Ident) >>
228 colon: punct!(:) >>
229 ty: syn!(Type) >>
230 (Field {
231 ident: Some(id),
232 vis: vis,
233 attrs: attrs,
234 ty: ty,
235 colon_token: Some(colon),
236 })
237 ));
238
239 named!(pub parse_unnamed -> Self, do_parse!(
240 attrs: many0!(Attribute::parse_outer) >>
241 vis: syn!(Visibility) >>
242 ty: syn!(Type) >>
243 (Field {
244 ident: None,
245 colon_token: None,
246 vis: vis,
247 attrs: attrs,
248 ty: ty,
249 })
250 ));
251 }
252
253 impl Synom for Visibility {
254 named!(parse -> Self, alt!(
255 do_parse!(
256 pub_token: keyword!(pub) >>
257 other: parens!(keyword!(crate)) >>
258 (Visibility::Crate(VisCrate {
259 pub_token: pub_token,
260 paren_token: other.0,
261 crate_token: other.1,
262 }))
263 )
264 |
265 do_parse!(
266 pub_token: keyword!(pub) >>
267 other: parens!(keyword!(self)) >>
268 (Visibility::Restricted(VisRestricted {
269 pub_token: pub_token,
270 paren_token: other.0,
271 in_token: None,
272 path: Box::new(other.1.into()),
273 }))
274 )
275 |
276 do_parse!(
277 pub_token: keyword!(pub) >>
278 other: parens!(keyword!(super)) >>
279 (Visibility::Restricted(VisRestricted {
280 pub_token: pub_token,
281 paren_token: other.0,
282 in_token: None,
283 path: Box::new(other.1.into()),
284 }))
285 )
286 |
287 do_parse!(
288 pub_token: keyword!(pub) >>
289 other: parens!(do_parse!(
290 in_tok: keyword!(in) >>
291 restricted: call!(Path::parse_mod_style) >>
292 (in_tok, restricted)
293 )) >>
294 (Visibility::Restricted(VisRestricted {
295 pub_token: pub_token,
296 paren_token: other.0,
297 in_token: Some((other.1).0),
298 path: Box::new((other.1).1),
299 }))
300 )
301 |
302 keyword!(pub) => { |tok| {
303 Visibility::Public(VisPublic {
304 pub_token: tok,
305 })
306 } }
307 |
308 epsilon!() => { |_| Visibility::Inherited }
309 ));
310
311 fn description() -> Option<&'static str> {
312 Some("visibility qualifier such as `pub`")
313 }
314 }
315}
316
317#[cfg(feature = "printing")]
318mod printing {
319 use super::*;
320 use quote::{ToTokens, Tokens};
321
322 impl ToTokens for Variant {
323 fn to_tokens(&self, tokens: &mut Tokens) {
324 tokens.append_all(&self.attrs);
325 self.ident.to_tokens(tokens);
326 self.fields.to_tokens(tokens);
327 if let Some((ref eq_token, ref disc)) = self.discriminant {
328 eq_token.to_tokens(tokens);
329 disc.to_tokens(tokens);
330 }
331 }
332 }
333
334 impl ToTokens for FieldsNamed {
335 fn to_tokens(&self, tokens: &mut Tokens) {
336 self.brace_token.surround(tokens, |tokens| {
337 self.named.to_tokens(tokens);
338 });
339 }
340 }
341
342 impl ToTokens for FieldsUnnamed {
343 fn to_tokens(&self, tokens: &mut Tokens) {
344 self.paren_token.surround(tokens, |tokens| {
345 self.unnamed.to_tokens(tokens);
346 });
347 }
348 }
349
350 impl ToTokens for Field {
351 fn to_tokens(&self, tokens: &mut Tokens) {
352 tokens.append_all(&self.attrs);
353 self.vis.to_tokens(tokens);
354 if let Some(ref ident) = self.ident {
355 ident.to_tokens(tokens);
356 TokensOrDefault(&self.colon_token).to_tokens(tokens);
357 }
358 self.ty.to_tokens(tokens);
359 }
360 }
361
362 impl ToTokens for VisPublic {
363 fn to_tokens(&self, tokens: &mut Tokens) {
364 self.pub_token.to_tokens(tokens)
365 }
366 }
367
368 impl ToTokens for VisCrate {
369 fn to_tokens(&self, tokens: &mut Tokens) {
370 self.pub_token.to_tokens(tokens);
371 self.paren_token.surround(tokens, |tokens| {
372 self.crate_token.to_tokens(tokens);
373 })
374 }
375 }
376
377 impl ToTokens for VisRestricted {
378 fn to_tokens(&self, tokens: &mut Tokens) {
379 self.pub_token.to_tokens(tokens);
380 self.paren_token.surround(tokens, |tokens| {
381 self.in_token.to_tokens(tokens);
384 self.path.to_tokens(tokens);
385 });
386 }
387 }
388}