2 use crate::punctuated
::Punctuated
;
5 /// Data structure sent to a `proc_macro_derive` macro.
7 /// *This type is available only if Syn is built with the `"derive"` feature.*
8 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
9 pub struct DeriveInput
{
10 /// Attributes tagged on the whole struct or enum.
11 pub attrs
: Vec
<Attribute
>,
13 /// Visibility of the struct or enum.
16 /// Name of the struct or enum.
19 /// Generics required to complete the definition.
20 pub generics
: Generics
,
22 /// Data within the struct or enum.
27 ast_enum_of_structs
! {
28 /// The storage of a struct, enum or union data structure.
30 /// *This type is available only if Syn is built with the `"derive"` feature.*
32 /// # Syntax tree enum
34 /// This type is a [syntax tree enum].
36 /// [syntax tree enum]: Expr#syntax-tree-enums
37 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
39 /// A struct input to a `proc_macro_derive` macro.
42 /// An enum input to a `proc_macro_derive` macro.
45 /// An untagged union input to a `proc_macro_derive` macro.
49 do_not_generate_to_tokens
53 /// A struct input to a `proc_macro_derive` macro.
55 /// *This type is available only if Syn is built with the `"derive"`
57 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
58 pub struct DataStruct
{
59 pub struct_token
: Token
![struct],
61 pub semi_token
: Option
<Token
![;]>,
66 /// An enum input to a `proc_macro_derive` macro.
68 /// *This type is available only if Syn is built with the `"derive"`
70 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
72 pub enum_token
: Token
![enum],
73 pub brace_token
: token
::Brace
,
74 pub variants
: Punctuated
<Variant
, Token
![,]>,
79 /// An untagged union input to a `proc_macro_derive` macro.
81 /// *This type is available only if Syn is built with the `"derive"`
83 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
84 pub struct DataUnion
{
85 pub union_token
: Token
![union],
86 pub fields
: FieldsNamed
,
90 #[cfg(feature = "parsing")]
93 use crate::parse
::{Parse, ParseStream, Result}
;
95 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
96 impl Parse
for DeriveInput
{
97 fn parse(input
: ParseStream
) -> Result
<Self> {
98 let mut attrs
= input
.call(Attribute
::parse_outer
)?
;
99 let vis
= input
.parse
::<Visibility
>()?
;
101 let lookahead
= input
.lookahead1();
102 if lookahead
.peek(Token
![struct]) {
103 let struct_token
= input
.parse
::<Token
![struct]>()?
;
104 let ident
= input
.parse
::<Ident
>()?
;
105 let generics
= input
.parse
::<Generics
>()?
;
106 let (where_clause
, fields
, semi
) = data_struct(input
, &mut attrs
)?
;
115 data
: Data
::Struct(DataStruct
{
121 } else if lookahead
.peek(Token
![enum]) {
122 let enum_token
= input
.parse
::<Token
![enum]>()?
;
123 let ident
= input
.parse
::<Ident
>()?
;
124 let generics
= input
.parse
::<Generics
>()?
;
125 let (where_clause
, brace
, variants
) = data_enum(input
, &mut attrs
)?
;
134 data
: Data
::Enum(DataEnum
{
140 } else if lookahead
.peek(Token
![union]) {
141 let union_token
= input
.parse
::<Token
![union]>()?
;
142 let ident
= input
.parse
::<Ident
>()?
;
143 let generics
= input
.parse
::<Generics
>()?
;
144 let (where_clause
, fields
) = data_union(input
, &mut attrs
)?
;
153 data
: Data
::Union(DataUnion
{
159 Err(lookahead
.error())
166 attrs
: &mut Vec
<Attribute
>,
167 ) -> Result
<(Option
<WhereClause
>, Fields
, Option
<Token
![;]>)> {
168 let mut lookahead
= input
.lookahead1();
169 let mut where_clause
= None
;
170 if lookahead
.peek(Token
![where]) {
171 where_clause
= Some(input
.parse()?
);
172 lookahead
= input
.lookahead1();
175 if where_clause
.is_none() && lookahead
.peek(token
::Paren
) {
176 let fields
= input
.parse()?
;
178 lookahead
= input
.lookahead1();
179 if lookahead
.peek(Token
![where]) {
180 where_clause
= Some(input
.parse()?
);
181 lookahead
= input
.lookahead1();
184 if lookahead
.peek(Token
![;]) {
185 let semi
= input
.parse()?
;
186 Ok((where_clause
, Fields
::Unnamed(fields
), Some(semi
)))
188 Err(lookahead
.error())
190 } else if lookahead
.peek(token
::Brace
) {
191 let fields
= data
::parsing
::parse_braced(input
, attrs
)?
;
192 Ok((where_clause
, Fields
::Named(fields
), None
))
193 } else if lookahead
.peek(Token
![;]) {
194 let semi
= input
.parse()?
;
195 Ok((where_clause
, Fields
::Unit
, Some(semi
)))
197 Err(lookahead
.error())
203 attrs
: &mut Vec
<Attribute
>,
207 Punctuated
<Variant
, Token
![,]>,
209 let where_clause
= input
.parse()?
;
212 let brace
= braced
!(content
in input
);
213 attr
::parsing
::parse_inner(&content
, attrs
)?
;
214 let variants
= content
.parse_terminated(Variant
::parse
)?
;
216 Ok((where_clause
, brace
, variants
))
221 attrs
: &mut Vec
<Attribute
>,
222 ) -> Result
<(Option
<WhereClause
>, FieldsNamed
)> {
223 let where_clause
= input
.parse()?
;
224 let fields
= data
::parsing
::parse_braced(input
, attrs
)?
;
225 Ok((where_clause
, fields
))
229 #[cfg(feature = "printing")]
232 use crate::attr
::FilterAttrs
;
233 use crate::print
::TokensOrDefault
;
234 use proc_macro2
::TokenStream
;
237 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
238 impl ToTokens
for DeriveInput
{
239 fn to_tokens(&self, tokens
: &mut TokenStream
) {
240 for attr
in self.attrs
.outer() {
241 attr
.to_tokens(tokens
);
243 self.vis
.to_tokens(tokens
);
245 Data
::Struct(d
) => d
.struct_token
.to_tokens(tokens
),
246 Data
::Enum(d
) => d
.enum_token
.to_tokens(tokens
),
247 Data
::Union(d
) => d
.union_token
.to_tokens(tokens
),
249 self.ident
.to_tokens(tokens
);
250 self.generics
.to_tokens(tokens
);
252 Data
::Struct(data
) => match &data
.fields
{
253 Fields
::Named(fields
) => {
254 self.generics
.where_clause
.to_tokens(tokens
);
255 fields
.to_tokens(tokens
);
257 Fields
::Unnamed(fields
) => {
258 fields
.to_tokens(tokens
);
259 self.generics
.where_clause
.to_tokens(tokens
);
260 TokensOrDefault(&data
.semi_token
).to_tokens(tokens
);
263 self.generics
.where_clause
.to_tokens(tokens
);
264 TokensOrDefault(&data
.semi_token
).to_tokens(tokens
);
267 Data
::Enum(data
) => {
268 self.generics
.where_clause
.to_tokens(tokens
);
269 data
.brace_token
.surround(tokens
, |tokens
| {
270 data
.variants
.to_tokens(tokens
);
273 Data
::Union(data
) => {
274 self.generics
.where_clause
.to_tokens(tokens
);
275 data
.fields
.to_tokens(tokens
);