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