1use super::*;
2use punctuated::Punctuated;
3
4ast_struct! {
5 pub struct Variant {
10 pub attrs: Vec<Attribute>,
12
13 pub ident: Ident,
15
16 pub fields: Fields,
18
19 pub discriminant: Option<(Token![=], Expr)>,
21 }
22}
23
24ast_enum_of_structs! {
25 pub enum Fields {
36 pub Named(FieldsNamed {
42 pub brace_token: token::Brace,
43 pub named: Punctuated<Field, Token![,]>,
44 }),
45
46 pub Unnamed(FieldsUnnamed {
51 pub paren_token: token::Paren,
52 pub unnamed: Punctuated<Field, Token![,]>,
53 }),
54
55 pub Unit,
57 }
58}
59
60impl Fields {
61 pub fn iter(&self) -> punctuated::Iter<Field> {
67 match *self {
68 Fields::Unit => private::empty_punctuated_iter(),
69 Fields::Named(ref f) => f.named.iter(),
70 Fields::Unnamed(ref f) => f.unnamed.iter(),
71 }
72 }
73
74 pub fn iter_mut(&mut self) -> punctuated::IterMut<Field> {
80 match *self {
81 Fields::Unit => private::empty_punctuated_iter_mut(),
82 Fields::Named(ref mut f) => f.named.iter_mut(),
83 Fields::Unnamed(ref mut f) => f.unnamed.iter_mut(),
84 }
85 }
86}
87
88impl<'a> IntoIterator for &'a Fields {
89 type Item = &'a Field;
90 type IntoIter = punctuated::Iter<'a, Field>;
91
92 fn into_iter(self) -> Self::IntoIter {
93 self.iter()
94 }
95}
96
97impl<'a> IntoIterator for &'a mut Fields {
98 type Item = &'a mut Field;
99 type IntoIter = punctuated::IterMut<'a, Field>;
100
101 fn into_iter(self) -> Self::IntoIter {
102 self.iter_mut()
103 }
104}
105
106ast_struct! {
107 pub struct Field {
112 pub attrs: Vec<Attribute>,
114
115 pub vis: Visibility,
117
118 pub ident: Option<Ident>,
122
123 pub colon_token: Option<Token![:]>,
124
125 pub ty: Type,
127 }
128}
129
130ast_enum_of_structs! {
131 pub enum Visibility {
143 pub Public(VisPublic {
148 pub pub_token: Token![pub],
149 }),
150
151 pub Crate(VisCrate {
156 pub crate_token: Token![crate],
157 }),
158
159 pub Restricted(VisRestricted {
165 pub pub_token: Token![pub],
166 pub paren_token: token::Paren,
167 pub in_token: Option<Token![in]>,
168 pub path: Box<Path>,
169 }),
170
171 pub Inherited,
173 }
174}
175
176#[cfg(feature = "parsing")]
177pub mod parsing {
178 use super::*;
179
180 use ext::IdentExt;
181 use parse::{Parse, ParseStream, Result};
182
183 impl Parse for Variant {
184 fn parse(input: ParseStream) -> Result<Self> {
185 Ok(Variant {
186 attrs: input.call(Attribute::parse_outer)?,
187 ident: input.parse()?,
188 fields: {
189 if input.peek(token::Brace) {
190 Fields::Named(input.parse()?)
191 } else if input.peek(token::Paren) {
192 Fields::Unnamed(input.parse()?)
193 } else {
194 Fields::Unit
195 }
196 },
197 discriminant: {
198 if input.peek(Token![=]) {
199 let eq_token: Token![=] = input.parse()?;
200 let discriminant: Expr = input.parse()?;
201 Some((eq_token, discriminant))
202 } else {
203 None
204 }
205 },
206 })
207 }
208 }
209
210 impl Parse for FieldsNamed {
211 fn parse(input: ParseStream) -> Result<Self> {
212 let content;
213 Ok(FieldsNamed {
214 brace_token: braced!(content in input),
215 named: content.parse_terminated(Field::parse_named)?,
216 })
217 }
218 }
219
220 impl Parse for FieldsUnnamed {
221 fn parse(input: ParseStream) -> Result<Self> {
222 let content;
223 Ok(FieldsUnnamed {
224 paren_token: parenthesized!(content in input),
225 unnamed: content.parse_terminated(Field::parse_unnamed)?,
226 })
227 }
228 }
229
230 impl Field {
231 pub fn parse_named(input: ParseStream) -> Result<Self> {
233 Ok(Field {
234 attrs: input.call(Attribute::parse_outer)?,
235 vis: input.parse()?,
236 ident: Some(input.parse()?),
237 colon_token: Some(input.parse()?),
238 ty: input.parse()?,
239 })
240 }
241
242 pub fn parse_unnamed(input: ParseStream) -> Result<Self> {
244 Ok(Field {
245 attrs: input.call(Attribute::parse_outer)?,
246 vis: input.parse()?,
247 ident: None,
248 colon_token: None,
249 ty: input.parse()?,
250 })
251 }
252 }
253
254 impl Parse for Visibility {
255 fn parse(input: ParseStream) -> Result<Self> {
256 if input.peek(Token![pub]) {
257 Self::parse_pub(input)
258 } else if input.peek(Token![crate]) {
259 Self::parse_crate(input)
260 } else {
261 Ok(Visibility::Inherited)
262 }
263 }
264 }
265
266 impl Visibility {
267 fn parse_pub(input: ParseStream) -> Result<Self> {
268 let pub_token = input.parse::<Token![pub]>()?;
269
270 if input.peek(token::Paren) {
271 let ahead = input.fork();
272 let mut content;
273 parenthesized!(content in ahead);
274
275 if content.peek(Token![crate])
276 || content.peek(Token![self])
277 || content.peek(Token![super])
278 {
279 return Ok(Visibility::Restricted(VisRestricted {
280 pub_token: pub_token,
281 paren_token: parenthesized!(content in input),
282 in_token: None,
283 path: Box::new(Path::from(content.call(Ident::parse_any)?)),
284 }));
285 } else if content.peek(Token![in]) {
286 return Ok(Visibility::Restricted(VisRestricted {
287 pub_token: pub_token,
288 paren_token: parenthesized!(content in input),
289 in_token: Some(content.parse()?),
290 path: Box::new(content.call(Path::parse_mod_style)?),
291 }));
292 }
293 }
294
295 Ok(Visibility::Public(VisPublic {
296 pub_token: pub_token,
297 }))
298 }
299
300 fn parse_crate(input: ParseStream) -> Result<Self> {
301 if input.peek2(Token![::]) {
302 Ok(Visibility::Inherited)
303 } else {
304 Ok(Visibility::Crate(VisCrate {
305 crate_token: input.parse()?,
306 }))
307 }
308 }
309 }
310}
311
312#[cfg(feature = "printing")]
313mod printing {
314 use super::*;
315
316 use proc_macro2::TokenStream;
317 use quote::{ToTokens, TokenStreamExt};
318
319 use print::TokensOrDefault;
320
321 impl ToTokens for Variant {
322 fn to_tokens(&self, tokens: &mut TokenStream) {
323 tokens.append_all(&self.attrs);
324 self.ident.to_tokens(tokens);
325 self.fields.to_tokens(tokens);
326 if let Some((ref eq_token, ref disc)) = self.discriminant {
327 eq_token.to_tokens(tokens);
328 disc.to_tokens(tokens);
329 }
330 }
331 }
332
333 impl ToTokens for FieldsNamed {
334 fn to_tokens(&self, tokens: &mut TokenStream) {
335 self.brace_token.surround(tokens, |tokens| {
336 self.named.to_tokens(tokens);
337 });
338 }
339 }
340
341 impl ToTokens for FieldsUnnamed {
342 fn to_tokens(&self, tokens: &mut TokenStream) {
343 self.paren_token.surround(tokens, |tokens| {
344 self.unnamed.to_tokens(tokens);
345 });
346 }
347 }
348
349 impl ToTokens for Field {
350 fn to_tokens(&self, tokens: &mut TokenStream) {
351 tokens.append_all(&self.attrs);
352 self.vis.to_tokens(tokens);
353 if let Some(ref ident) = self.ident {
354 ident.to_tokens(tokens);
355 TokensOrDefault(&self.colon_token).to_tokens(tokens);
356 }
357 self.ty.to_tokens(tokens);
358 }
359 }
360
361 impl ToTokens for VisPublic {
362 fn to_tokens(&self, tokens: &mut TokenStream) {
363 self.pub_token.to_tokens(tokens)
364 }
365 }
366
367 impl ToTokens for VisCrate {
368 fn to_tokens(&self, tokens: &mut TokenStream) {
369 self.crate_token.to_tokens(tokens);
370 }
371 }
372
373 impl ToTokens for VisRestricted {
374 fn to_tokens(&self, tokens: &mut TokenStream) {
375 self.pub_token.to_tokens(tokens);
376 self.paren_token.surround(tokens, |tokens| {
377 self.in_token.to_tokens(tokens);
380 self.path.to_tokens(tokens);
381 });
382 }
383 }
384}