xref: /linux/rust/syn/data.rs (revision 784faa8eca8270671e0ed6d9d21f04bbb80fc5f7)
1*69942c0aSMiguel Ojeda // SPDX-License-Identifier: Apache-2.0 OR MIT
2*69942c0aSMiguel Ojeda 
3808c999fSMiguel Ojeda use crate::attr::Attribute;
4808c999fSMiguel Ojeda use crate::expr::{Expr, Index, Member};
5808c999fSMiguel Ojeda use crate::ident::Ident;
6808c999fSMiguel Ojeda use crate::punctuated::{self, Punctuated};
7808c999fSMiguel Ojeda use crate::restriction::{FieldMutability, Visibility};
8808c999fSMiguel Ojeda use crate::token;
9808c999fSMiguel Ojeda use crate::ty::Type;
10808c999fSMiguel Ojeda 
11808c999fSMiguel Ojeda ast_struct! {
12808c999fSMiguel Ojeda     /// An enum variant.
13808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
14808c999fSMiguel Ojeda     pub struct Variant {
15808c999fSMiguel Ojeda         pub attrs: Vec<Attribute>,
16808c999fSMiguel Ojeda 
17808c999fSMiguel Ojeda         /// Name of the variant.
18808c999fSMiguel Ojeda         pub ident: Ident,
19808c999fSMiguel Ojeda 
20808c999fSMiguel Ojeda         /// Content stored in the variant.
21808c999fSMiguel Ojeda         pub fields: Fields,
22808c999fSMiguel Ojeda 
23808c999fSMiguel Ojeda         /// Explicit discriminant: `Variant = 1`
24808c999fSMiguel Ojeda         pub discriminant: Option<(Token![=], Expr)>,
25808c999fSMiguel Ojeda     }
26808c999fSMiguel Ojeda }
27808c999fSMiguel Ojeda 
28808c999fSMiguel Ojeda ast_enum_of_structs! {
29808c999fSMiguel Ojeda     /// Data stored within an enum variant or struct.
30808c999fSMiguel Ojeda     ///
31808c999fSMiguel Ojeda     /// # Syntax tree enum
32808c999fSMiguel Ojeda     ///
33808c999fSMiguel Ojeda     /// This type is a [syntax tree enum].
34808c999fSMiguel Ojeda     ///
35808c999fSMiguel Ojeda     /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
36808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
37808c999fSMiguel Ojeda     pub enum Fields {
38808c999fSMiguel Ojeda         /// Named fields of a struct or struct variant such as `Point { x: f64,
39808c999fSMiguel Ojeda         /// y: f64 }`.
40808c999fSMiguel Ojeda         Named(FieldsNamed),
41808c999fSMiguel Ojeda 
42808c999fSMiguel Ojeda         /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
43808c999fSMiguel Ojeda         Unnamed(FieldsUnnamed),
44808c999fSMiguel Ojeda 
45808c999fSMiguel Ojeda         /// Unit struct or unit variant such as `None`.
46808c999fSMiguel Ojeda         Unit,
47808c999fSMiguel Ojeda     }
48808c999fSMiguel Ojeda }
49808c999fSMiguel Ojeda 
50808c999fSMiguel Ojeda ast_struct! {
51808c999fSMiguel Ojeda     /// Named fields of a struct or struct variant such as `Point { x: f64,
52808c999fSMiguel Ojeda     /// y: f64 }`.
53808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
54808c999fSMiguel Ojeda     pub struct FieldsNamed {
55808c999fSMiguel Ojeda         pub brace_token: token::Brace,
56808c999fSMiguel Ojeda         pub named: Punctuated<Field, Token![,]>,
57808c999fSMiguel Ojeda     }
58808c999fSMiguel Ojeda }
59808c999fSMiguel Ojeda 
60808c999fSMiguel Ojeda ast_struct! {
61808c999fSMiguel Ojeda     /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
62808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
63808c999fSMiguel Ojeda     pub struct FieldsUnnamed {
64808c999fSMiguel Ojeda         pub paren_token: token::Paren,
65808c999fSMiguel Ojeda         pub unnamed: Punctuated<Field, Token![,]>,
66808c999fSMiguel Ojeda     }
67808c999fSMiguel Ojeda }
68808c999fSMiguel Ojeda 
69808c999fSMiguel Ojeda impl Fields {
70808c999fSMiguel Ojeda     /// Get an iterator over the borrowed [`Field`] items in this object. This
71808c999fSMiguel Ojeda     /// iterator can be used to iterate over a named or unnamed struct or
72808c999fSMiguel Ojeda     /// variant's fields uniformly.
iter(&self) -> punctuated::Iter<Field>73808c999fSMiguel Ojeda     pub fn iter(&self) -> punctuated::Iter<Field> {
74808c999fSMiguel Ojeda         match self {
75808c999fSMiguel Ojeda             Fields::Unit => crate::punctuated::empty_punctuated_iter(),
76808c999fSMiguel Ojeda             Fields::Named(f) => f.named.iter(),
77808c999fSMiguel Ojeda             Fields::Unnamed(f) => f.unnamed.iter(),
78808c999fSMiguel Ojeda         }
79808c999fSMiguel Ojeda     }
80808c999fSMiguel Ojeda 
81808c999fSMiguel Ojeda     /// Get an iterator over the mutably borrowed [`Field`] items in this
82808c999fSMiguel Ojeda     /// object. This iterator can be used to iterate over a named or unnamed
83808c999fSMiguel Ojeda     /// struct or variant's fields uniformly.
iter_mut(&mut self) -> punctuated::IterMut<Field>84808c999fSMiguel Ojeda     pub fn iter_mut(&mut self) -> punctuated::IterMut<Field> {
85808c999fSMiguel Ojeda         match self {
86808c999fSMiguel Ojeda             Fields::Unit => crate::punctuated::empty_punctuated_iter_mut(),
87808c999fSMiguel Ojeda             Fields::Named(f) => f.named.iter_mut(),
88808c999fSMiguel Ojeda             Fields::Unnamed(f) => f.unnamed.iter_mut(),
89808c999fSMiguel Ojeda         }
90808c999fSMiguel Ojeda     }
91808c999fSMiguel Ojeda 
92808c999fSMiguel Ojeda     /// Returns the number of fields.
len(&self) -> usize93808c999fSMiguel Ojeda     pub fn len(&self) -> usize {
94808c999fSMiguel Ojeda         match self {
95808c999fSMiguel Ojeda             Fields::Unit => 0,
96808c999fSMiguel Ojeda             Fields::Named(f) => f.named.len(),
97808c999fSMiguel Ojeda             Fields::Unnamed(f) => f.unnamed.len(),
98808c999fSMiguel Ojeda         }
99808c999fSMiguel Ojeda     }
100808c999fSMiguel Ojeda 
101808c999fSMiguel Ojeda     /// Returns `true` if there are zero fields.
is_empty(&self) -> bool102808c999fSMiguel Ojeda     pub fn is_empty(&self) -> bool {
103808c999fSMiguel Ojeda         match self {
104808c999fSMiguel Ojeda             Fields::Unit => true,
105808c999fSMiguel Ojeda             Fields::Named(f) => f.named.is_empty(),
106808c999fSMiguel Ojeda             Fields::Unnamed(f) => f.unnamed.is_empty(),
107808c999fSMiguel Ojeda         }
108808c999fSMiguel Ojeda     }
109808c999fSMiguel Ojeda 
110808c999fSMiguel Ojeda     return_impl_trait! {
111808c999fSMiguel Ojeda         /// Get an iterator over the fields of a struct or variant as [`Member`]s.
112808c999fSMiguel Ojeda         /// This iterator can be used to iterate over a named or unnamed struct or
113808c999fSMiguel Ojeda         /// variant's fields uniformly.
114808c999fSMiguel Ojeda         ///
115808c999fSMiguel Ojeda         /// # Example
116808c999fSMiguel Ojeda         ///
117808c999fSMiguel Ojeda         /// The following is a simplistic [`Clone`] derive for structs. (A more
118808c999fSMiguel Ojeda         /// complete implementation would additionally want to infer trait bounds on
119808c999fSMiguel Ojeda         /// the generic type parameters.)
120808c999fSMiguel Ojeda         ///
121808c999fSMiguel Ojeda         /// ```
122808c999fSMiguel Ojeda         /// # use quote::quote;
123808c999fSMiguel Ojeda         /// #
124808c999fSMiguel Ojeda         /// fn derive_clone(input: &syn::ItemStruct) -> proc_macro2::TokenStream {
125808c999fSMiguel Ojeda         ///     let ident = &input.ident;
126808c999fSMiguel Ojeda         ///     let members = input.fields.members();
127808c999fSMiguel Ojeda         ///     let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
128808c999fSMiguel Ojeda         ///     quote! {
129808c999fSMiguel Ojeda         ///         impl #impl_generics Clone for #ident #ty_generics #where_clause {
130808c999fSMiguel Ojeda         ///             fn clone(&self) -> Self {
131808c999fSMiguel Ojeda         ///                 Self {
132808c999fSMiguel Ojeda         ///                     #(#members: self.#members.clone()),*
133808c999fSMiguel Ojeda         ///                 }
134808c999fSMiguel Ojeda         ///             }
135808c999fSMiguel Ojeda         ///         }
136808c999fSMiguel Ojeda         ///     }
137808c999fSMiguel Ojeda         /// }
138808c999fSMiguel Ojeda         /// ```
139808c999fSMiguel Ojeda         ///
140808c999fSMiguel Ojeda         /// For structs with named fields, it produces an expression like `Self { a:
141808c999fSMiguel Ojeda         /// self.a.clone() }`. For structs with unnamed fields, `Self { 0:
142808c999fSMiguel Ojeda         /// self.0.clone() }`. And for unit structs, `Self {}`.
143808c999fSMiguel Ojeda         pub fn members(&self) -> impl Iterator<Item = Member> + Clone + '_ [Members] {
144808c999fSMiguel Ojeda             Members {
145808c999fSMiguel Ojeda                 fields: self.iter(),
146808c999fSMiguel Ojeda                 index: 0,
147808c999fSMiguel Ojeda             }
148808c999fSMiguel Ojeda         }
149808c999fSMiguel Ojeda     }
150808c999fSMiguel Ojeda }
151808c999fSMiguel Ojeda 
152808c999fSMiguel Ojeda impl IntoIterator for Fields {
153808c999fSMiguel Ojeda     type Item = Field;
154808c999fSMiguel Ojeda     type IntoIter = punctuated::IntoIter<Field>;
155808c999fSMiguel Ojeda 
into_iter(self) -> Self::IntoIter156808c999fSMiguel Ojeda     fn into_iter(self) -> Self::IntoIter {
157808c999fSMiguel Ojeda         match self {
158808c999fSMiguel Ojeda             Fields::Unit => Punctuated::<Field, ()>::new().into_iter(),
159808c999fSMiguel Ojeda             Fields::Named(f) => f.named.into_iter(),
160808c999fSMiguel Ojeda             Fields::Unnamed(f) => f.unnamed.into_iter(),
161808c999fSMiguel Ojeda         }
162808c999fSMiguel Ojeda     }
163808c999fSMiguel Ojeda }
164808c999fSMiguel Ojeda 
165808c999fSMiguel Ojeda impl<'a> IntoIterator for &'a Fields {
166808c999fSMiguel Ojeda     type Item = &'a Field;
167808c999fSMiguel Ojeda     type IntoIter = punctuated::Iter<'a, Field>;
168808c999fSMiguel Ojeda 
into_iter(self) -> Self::IntoIter169808c999fSMiguel Ojeda     fn into_iter(self) -> Self::IntoIter {
170808c999fSMiguel Ojeda         self.iter()
171808c999fSMiguel Ojeda     }
172808c999fSMiguel Ojeda }
173808c999fSMiguel Ojeda 
174808c999fSMiguel Ojeda impl<'a> IntoIterator for &'a mut Fields {
175808c999fSMiguel Ojeda     type Item = &'a mut Field;
176808c999fSMiguel Ojeda     type IntoIter = punctuated::IterMut<'a, Field>;
177808c999fSMiguel Ojeda 
into_iter(self) -> Self::IntoIter178808c999fSMiguel Ojeda     fn into_iter(self) -> Self::IntoIter {
179808c999fSMiguel Ojeda         self.iter_mut()
180808c999fSMiguel Ojeda     }
181808c999fSMiguel Ojeda }
182808c999fSMiguel Ojeda 
183808c999fSMiguel Ojeda ast_struct! {
184808c999fSMiguel Ojeda     /// A field of a struct or enum variant.
185808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
186808c999fSMiguel Ojeda     pub struct Field {
187808c999fSMiguel Ojeda         pub attrs: Vec<Attribute>,
188808c999fSMiguel Ojeda 
189808c999fSMiguel Ojeda         pub vis: Visibility,
190808c999fSMiguel Ojeda 
191808c999fSMiguel Ojeda         pub mutability: FieldMutability,
192808c999fSMiguel Ojeda 
193808c999fSMiguel Ojeda         /// Name of the field, if any.
194808c999fSMiguel Ojeda         ///
195808c999fSMiguel Ojeda         /// Fields of tuple structs have no names.
196808c999fSMiguel Ojeda         pub ident: Option<Ident>,
197808c999fSMiguel Ojeda 
198808c999fSMiguel Ojeda         pub colon_token: Option<Token![:]>,
199808c999fSMiguel Ojeda 
200808c999fSMiguel Ojeda         pub ty: Type,
201808c999fSMiguel Ojeda     }
202808c999fSMiguel Ojeda }
203808c999fSMiguel Ojeda 
204808c999fSMiguel Ojeda pub struct Members<'a> {
205808c999fSMiguel Ojeda     fields: punctuated::Iter<'a, Field>,
206808c999fSMiguel Ojeda     index: u32,
207808c999fSMiguel Ojeda }
208808c999fSMiguel Ojeda 
209808c999fSMiguel Ojeda impl<'a> Iterator for Members<'a> {
210808c999fSMiguel Ojeda     type Item = Member;
211808c999fSMiguel Ojeda 
next(&mut self) -> Option<Self::Item>212808c999fSMiguel Ojeda     fn next(&mut self) -> Option<Self::Item> {
213808c999fSMiguel Ojeda         let field = self.fields.next()?;
214808c999fSMiguel Ojeda         let member = match &field.ident {
215808c999fSMiguel Ojeda             Some(ident) => Member::Named(ident.clone()),
216808c999fSMiguel Ojeda             None => {
217808c999fSMiguel Ojeda                 #[cfg(all(feature = "parsing", feature = "printing"))]
218808c999fSMiguel Ojeda                 let span = crate::spanned::Spanned::span(&field.ty);
219808c999fSMiguel Ojeda                 #[cfg(not(all(feature = "parsing", feature = "printing")))]
220808c999fSMiguel Ojeda                 let span = proc_macro2::Span::call_site();
221808c999fSMiguel Ojeda                 Member::Unnamed(Index {
222808c999fSMiguel Ojeda                     index: self.index,
223808c999fSMiguel Ojeda                     span,
224808c999fSMiguel Ojeda                 })
225808c999fSMiguel Ojeda             }
226808c999fSMiguel Ojeda         };
227808c999fSMiguel Ojeda         self.index += 1;
228808c999fSMiguel Ojeda         Some(member)
229808c999fSMiguel Ojeda     }
230808c999fSMiguel Ojeda }
231808c999fSMiguel Ojeda 
232808c999fSMiguel Ojeda impl<'a> Clone for Members<'a> {
clone(&self) -> Self233808c999fSMiguel Ojeda     fn clone(&self) -> Self {
234808c999fSMiguel Ojeda         Members {
235808c999fSMiguel Ojeda             fields: self.fields.clone(),
236808c999fSMiguel Ojeda             index: self.index,
237808c999fSMiguel Ojeda         }
238808c999fSMiguel Ojeda     }
239808c999fSMiguel Ojeda }
240808c999fSMiguel Ojeda 
241808c999fSMiguel Ojeda #[cfg(feature = "parsing")]
242808c999fSMiguel Ojeda pub(crate) mod parsing {
243808c999fSMiguel Ojeda     use crate::attr::Attribute;
244808c999fSMiguel Ojeda     use crate::data::{Field, Fields, FieldsNamed, FieldsUnnamed, Variant};
245808c999fSMiguel Ojeda     use crate::error::Result;
246808c999fSMiguel Ojeda     use crate::expr::Expr;
247808c999fSMiguel Ojeda     use crate::ext::IdentExt as _;
248808c999fSMiguel Ojeda     use crate::ident::Ident;
249808c999fSMiguel Ojeda     #[cfg(not(feature = "full"))]
250808c999fSMiguel Ojeda     use crate::parse::discouraged::Speculative as _;
251808c999fSMiguel Ojeda     use crate::parse::{Parse, ParseStream};
252808c999fSMiguel Ojeda     use crate::restriction::{FieldMutability, Visibility};
253808c999fSMiguel Ojeda     #[cfg(not(feature = "full"))]
254808c999fSMiguel Ojeda     use crate::scan_expr::scan_expr;
255808c999fSMiguel Ojeda     use crate::token;
256808c999fSMiguel Ojeda     use crate::ty::Type;
257808c999fSMiguel Ojeda     use crate::verbatim;
258808c999fSMiguel Ojeda 
259808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
260808c999fSMiguel Ojeda     impl Parse for Variant {
parse(input: ParseStream) -> Result<Self>261808c999fSMiguel Ojeda         fn parse(input: ParseStream) -> Result<Self> {
262808c999fSMiguel Ojeda             let attrs = input.call(Attribute::parse_outer)?;
263808c999fSMiguel Ojeda             let _visibility: Visibility = input.parse()?;
264808c999fSMiguel Ojeda             let ident: Ident = input.parse()?;
265808c999fSMiguel Ojeda             let fields = if input.peek(token::Brace) {
266808c999fSMiguel Ojeda                 Fields::Named(input.parse()?)
267808c999fSMiguel Ojeda             } else if input.peek(token::Paren) {
268808c999fSMiguel Ojeda                 Fields::Unnamed(input.parse()?)
269808c999fSMiguel Ojeda             } else {
270808c999fSMiguel Ojeda                 Fields::Unit
271808c999fSMiguel Ojeda             };
272808c999fSMiguel Ojeda             let discriminant = if input.peek(Token![=]) {
273808c999fSMiguel Ojeda                 let eq_token: Token![=] = input.parse()?;
274808c999fSMiguel Ojeda                 #[cfg(feature = "full")]
275808c999fSMiguel Ojeda                 let discriminant: Expr = input.parse()?;
276808c999fSMiguel Ojeda                 #[cfg(not(feature = "full"))]
277808c999fSMiguel Ojeda                 let discriminant = {
278808c999fSMiguel Ojeda                     let begin = input.fork();
279808c999fSMiguel Ojeda                     let ahead = input.fork();
280808c999fSMiguel Ojeda                     let mut discriminant: Result<Expr> = ahead.parse();
281808c999fSMiguel Ojeda                     if discriminant.is_ok() {
282808c999fSMiguel Ojeda                         input.advance_to(&ahead);
283808c999fSMiguel Ojeda                     } else if scan_expr(input).is_ok() {
284808c999fSMiguel Ojeda                         discriminant = Ok(Expr::Verbatim(verbatim::between(&begin, input)));
285808c999fSMiguel Ojeda                     }
286808c999fSMiguel Ojeda                     discriminant?
287808c999fSMiguel Ojeda                 };
288808c999fSMiguel Ojeda                 Some((eq_token, discriminant))
289808c999fSMiguel Ojeda             } else {
290808c999fSMiguel Ojeda                 None
291808c999fSMiguel Ojeda             };
292808c999fSMiguel Ojeda             Ok(Variant {
293808c999fSMiguel Ojeda                 attrs,
294808c999fSMiguel Ojeda                 ident,
295808c999fSMiguel Ojeda                 fields,
296808c999fSMiguel Ojeda                 discriminant,
297808c999fSMiguel Ojeda             })
298808c999fSMiguel Ojeda         }
299808c999fSMiguel Ojeda     }
300808c999fSMiguel Ojeda 
301808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
302808c999fSMiguel Ojeda     impl Parse for FieldsNamed {
parse(input: ParseStream) -> Result<Self>303808c999fSMiguel Ojeda         fn parse(input: ParseStream) -> Result<Self> {
304808c999fSMiguel Ojeda             let content;
305808c999fSMiguel Ojeda             Ok(FieldsNamed {
306808c999fSMiguel Ojeda                 brace_token: braced!(content in input),
307808c999fSMiguel Ojeda                 named: content.parse_terminated(Field::parse_named, Token![,])?,
308808c999fSMiguel Ojeda             })
309808c999fSMiguel Ojeda         }
310808c999fSMiguel Ojeda     }
311808c999fSMiguel Ojeda 
312808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
313808c999fSMiguel Ojeda     impl Parse for FieldsUnnamed {
parse(input: ParseStream) -> Result<Self>314808c999fSMiguel Ojeda         fn parse(input: ParseStream) -> Result<Self> {
315808c999fSMiguel Ojeda             let content;
316808c999fSMiguel Ojeda             Ok(FieldsUnnamed {
317808c999fSMiguel Ojeda                 paren_token: parenthesized!(content in input),
318808c999fSMiguel Ojeda                 unnamed: content.parse_terminated(Field::parse_unnamed, Token![,])?,
319808c999fSMiguel Ojeda             })
320808c999fSMiguel Ojeda         }
321808c999fSMiguel Ojeda     }
322808c999fSMiguel Ojeda 
323808c999fSMiguel Ojeda     impl Field {
324808c999fSMiguel Ojeda         /// Parses a named (braced struct) field.
325808c999fSMiguel Ojeda         #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
parse_named(input: ParseStream) -> Result<Self>326808c999fSMiguel Ojeda         pub fn parse_named(input: ParseStream) -> Result<Self> {
327808c999fSMiguel Ojeda             let attrs = input.call(Attribute::parse_outer)?;
328808c999fSMiguel Ojeda             let vis: Visibility = input.parse()?;
329808c999fSMiguel Ojeda 
330808c999fSMiguel Ojeda             let unnamed_field = cfg!(feature = "full") && input.peek(Token![_]);
331808c999fSMiguel Ojeda             let ident = if unnamed_field {
332808c999fSMiguel Ojeda                 input.call(Ident::parse_any)
333808c999fSMiguel Ojeda             } else {
334808c999fSMiguel Ojeda                 input.parse()
335808c999fSMiguel Ojeda             }?;
336808c999fSMiguel Ojeda 
337808c999fSMiguel Ojeda             let colon_token: Token![:] = input.parse()?;
338808c999fSMiguel Ojeda 
339808c999fSMiguel Ojeda             let ty: Type = if unnamed_field
340808c999fSMiguel Ojeda                 && (input.peek(Token![struct])
341808c999fSMiguel Ojeda                     || input.peek(Token![union]) && input.peek2(token::Brace))
342808c999fSMiguel Ojeda             {
343808c999fSMiguel Ojeda                 let begin = input.fork();
344808c999fSMiguel Ojeda                 input.call(Ident::parse_any)?;
345808c999fSMiguel Ojeda                 input.parse::<FieldsNamed>()?;
346808c999fSMiguel Ojeda                 Type::Verbatim(verbatim::between(&begin, input))
347808c999fSMiguel Ojeda             } else {
348808c999fSMiguel Ojeda                 input.parse()?
349808c999fSMiguel Ojeda             };
350808c999fSMiguel Ojeda 
351808c999fSMiguel Ojeda             Ok(Field {
352808c999fSMiguel Ojeda                 attrs,
353808c999fSMiguel Ojeda                 vis,
354808c999fSMiguel Ojeda                 mutability: FieldMutability::None,
355808c999fSMiguel Ojeda                 ident: Some(ident),
356808c999fSMiguel Ojeda                 colon_token: Some(colon_token),
357808c999fSMiguel Ojeda                 ty,
358808c999fSMiguel Ojeda             })
359808c999fSMiguel Ojeda         }
360808c999fSMiguel Ojeda 
361808c999fSMiguel Ojeda         /// Parses an unnamed (tuple struct) field.
362808c999fSMiguel Ojeda         #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
parse_unnamed(input: ParseStream) -> Result<Self>363808c999fSMiguel Ojeda         pub fn parse_unnamed(input: ParseStream) -> Result<Self> {
364808c999fSMiguel Ojeda             Ok(Field {
365808c999fSMiguel Ojeda                 attrs: input.call(Attribute::parse_outer)?,
366808c999fSMiguel Ojeda                 vis: input.parse()?,
367808c999fSMiguel Ojeda                 mutability: FieldMutability::None,
368808c999fSMiguel Ojeda                 ident: None,
369808c999fSMiguel Ojeda                 colon_token: None,
370808c999fSMiguel Ojeda                 ty: input.parse()?,
371808c999fSMiguel Ojeda             })
372808c999fSMiguel Ojeda         }
373808c999fSMiguel Ojeda     }
374808c999fSMiguel Ojeda }
375808c999fSMiguel Ojeda 
376808c999fSMiguel Ojeda #[cfg(feature = "printing")]
377808c999fSMiguel Ojeda mod printing {
378808c999fSMiguel Ojeda     use crate::data::{Field, FieldsNamed, FieldsUnnamed, Variant};
379808c999fSMiguel Ojeda     use crate::print::TokensOrDefault;
380808c999fSMiguel Ojeda     use proc_macro2::TokenStream;
381808c999fSMiguel Ojeda     use quote::{ToTokens, TokenStreamExt};
382808c999fSMiguel Ojeda 
383808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
384808c999fSMiguel Ojeda     impl ToTokens for Variant {
to_tokens(&self, tokens: &mut TokenStream)385808c999fSMiguel Ojeda         fn to_tokens(&self, tokens: &mut TokenStream) {
386808c999fSMiguel Ojeda             tokens.append_all(&self.attrs);
387808c999fSMiguel Ojeda             self.ident.to_tokens(tokens);
388808c999fSMiguel Ojeda             self.fields.to_tokens(tokens);
389808c999fSMiguel Ojeda             if let Some((eq_token, disc)) = &self.discriminant {
390808c999fSMiguel Ojeda                 eq_token.to_tokens(tokens);
391808c999fSMiguel Ojeda                 disc.to_tokens(tokens);
392808c999fSMiguel Ojeda             }
393808c999fSMiguel Ojeda         }
394808c999fSMiguel Ojeda     }
395808c999fSMiguel Ojeda 
396808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
397808c999fSMiguel Ojeda     impl ToTokens for FieldsNamed {
to_tokens(&self, tokens: &mut TokenStream)398808c999fSMiguel Ojeda         fn to_tokens(&self, tokens: &mut TokenStream) {
399808c999fSMiguel Ojeda             self.brace_token.surround(tokens, |tokens| {
400808c999fSMiguel Ojeda                 self.named.to_tokens(tokens);
401808c999fSMiguel Ojeda             });
402808c999fSMiguel Ojeda         }
403808c999fSMiguel Ojeda     }
404808c999fSMiguel Ojeda 
405808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
406808c999fSMiguel Ojeda     impl ToTokens for FieldsUnnamed {
to_tokens(&self, tokens: &mut TokenStream)407808c999fSMiguel Ojeda         fn to_tokens(&self, tokens: &mut TokenStream) {
408808c999fSMiguel Ojeda             self.paren_token.surround(tokens, |tokens| {
409808c999fSMiguel Ojeda                 self.unnamed.to_tokens(tokens);
410808c999fSMiguel Ojeda             });
411808c999fSMiguel Ojeda         }
412808c999fSMiguel Ojeda     }
413808c999fSMiguel Ojeda 
414808c999fSMiguel Ojeda     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
415808c999fSMiguel Ojeda     impl ToTokens for Field {
to_tokens(&self, tokens: &mut TokenStream)416808c999fSMiguel Ojeda         fn to_tokens(&self, tokens: &mut TokenStream) {
417808c999fSMiguel Ojeda             tokens.append_all(&self.attrs);
418808c999fSMiguel Ojeda             self.vis.to_tokens(tokens);
419808c999fSMiguel Ojeda             if let Some(ident) = &self.ident {
420808c999fSMiguel Ojeda                 ident.to_tokens(tokens);
421808c999fSMiguel Ojeda                 TokensOrDefault(&self.colon_token).to_tokens(tokens);
422808c999fSMiguel Ojeda             }
423808c999fSMiguel Ojeda             self.ty.to_tokens(tokens);
424808c999fSMiguel Ojeda         }
425808c999fSMiguel Ojeda     }
426808c999fSMiguel Ojeda }
427