syn_pub_items/
data.rs

1use super::*;
2use punctuated::Punctuated;
3
4ast_struct! {
5    /// An enum variant.
6    ///
7    /// *This type is available if Syn is built with the `"derive"` or `"full"`
8    /// feature.*
9    pub struct Variant {
10        /// Attributes tagged on the variant.
11        pub attrs: Vec<Attribute>,
12
13        /// Name of the variant.
14        pub ident: Ident,
15
16        /// Content stored in the variant.
17        pub fields: Fields,
18
19        /// Explicit discriminant: `Variant = 1`
20        pub discriminant: Option<(Token![=], Expr)>,
21    }
22}
23
24ast_enum_of_structs! {
25    /// Data stored within an enum variant or struct.
26    ///
27    /// *This type is available if Syn is built with the `"derive"` or `"full"`
28    /// feature.*
29    ///
30    /// # Syntax tree enum
31    ///
32    /// This type is a [syntax tree enum].
33    ///
34    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
35    pub enum Fields {
36        /// Named fields of a struct or struct variant such as `Point { x: f64,
37        /// y: f64 }`.
38        ///
39        /// *This type is available if Syn is built with the `"derive"` or
40        /// `"full"` feature.*
41        pub Named(FieldsNamed {
42            pub brace_token: token::Brace,
43            pub named: Punctuated<Field, Token![,]>,
44        }),
45
46        /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
47        ///
48        /// *This type is available if Syn is built with the `"derive"` or
49        /// `"full"` feature.*
50        pub Unnamed(FieldsUnnamed {
51            pub paren_token: token::Paren,
52            pub unnamed: Punctuated<Field, Token![,]>,
53        }),
54
55        /// Unit struct or unit variant such as `None`.
56        pub Unit,
57    }
58}
59
60impl Fields {
61    /// Get an iterator over the borrowed [`Field`] items in this object. This
62    /// iterator can be used to iterate over a named or unnamed struct or
63    /// variant's fields uniformly.
64    ///
65    /// [`Field`]: struct.Field.html
66    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    /// Get an iterator over the mutably borrowed [`Field`] items in this
75    /// object. This iterator can be used to iterate over a named or unnamed
76    /// struct or variant's fields uniformly.
77    ///
78    /// [`Field`]: struct.Field.html
79    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    /// A field of a struct or enum variant.
108    ///
109    /// *This type is available if Syn is built with the `"derive"` or `"full"`
110    /// feature.*
111    pub struct Field {
112        /// Attributes tagged on the field.
113        pub attrs: Vec<Attribute>,
114
115        /// Visibility of the field.
116        pub vis: Visibility,
117
118        /// Name of the field, if any.
119        ///
120        /// Fields of tuple structs have no names.
121        pub ident: Option<Ident>,
122
123        pub colon_token: Option<Token![:]>,
124
125        /// Type of the field.
126        pub ty: Type,
127    }
128}
129
130ast_enum_of_structs! {
131    /// The visibility level of an item: inherited or `pub` or
132    /// `pub(restricted)`.
133    ///
134    /// *This type is available if Syn is built with the `"derive"` or `"full"`
135    /// feature.*
136    ///
137    /// # Syntax tree enum
138    ///
139    /// This type is a [syntax tree enum].
140    ///
141    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
142    pub enum Visibility {
143        /// A public visibility level: `pub`.
144        ///
145        /// *This type is available if Syn is built with the `"derive"` or
146        /// `"full"` feature.*
147        pub Public(VisPublic {
148            pub pub_token: Token![pub],
149        }),
150
151        /// A crate-level visibility: `crate`.
152        ///
153        /// *This type is available if Syn is built with the `"derive"` or
154        /// `"full"` feature.*
155        pub Crate(VisCrate {
156            pub crate_token: Token![crate],
157        }),
158
159        /// A visibility level restricted to some path: `pub(self)` or
160        /// `pub(super)` or `pub(crate)` or `pub(in some::module)`.
161        ///
162        /// *This type is available if Syn is built with the `"derive"` or
163        /// `"full"` feature.*
164        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        /// An inherited visibility, which usually means private.
172        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        /// Parses a named (braced struct) field.
232        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        /// Parses an unnamed (tuple struct) field.
243        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                // TODO: If we have a path which is not "self" or "super" or
378                // "crate", automatically add the "in" token.
379                self.in_token.to_tokens(tokens);
380                self.path.to_tokens(tokens);
381            });
382        }
383    }
384}