2 use punctuated
::Punctuated
;
5 /// Data structure sent to a `proc_macro_derive` macro.
7 /// *This type is available if Syn is built with the `"derive"` feature.*
8 pub struct DeriveInput
{
9 /// Attributes tagged on the whole struct or enum.
10 pub attrs
: Vec
<Attribute
>,
12 /// Visibility of the struct or enum.
15 /// Name of the struct or enum.
18 /// Generics required to complete the definition.
19 pub generics
: Generics
,
21 /// Data within the struct or enum.
26 ast_enum_of_structs
! {
27 /// The storage of a struct, enum or union data structure.
29 /// *This type is available if Syn is built with the `"derive"` feature.*
31 /// # Syntax tree enum
33 /// This type is a [syntax tree enum].
35 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
37 /// A struct input to a `proc_macro_derive` macro.
39 /// *This type is available if Syn is built with the `"derive"`
41 pub Struct(DataStruct
{
42 pub struct_token
: Token
![struct],
44 pub semi_token
: Option
<Token
![;]>,
47 /// An enum input to a `proc_macro_derive` macro.
49 /// *This type is available if Syn is built with the `"derive"`
52 pub enum_token
: Token
![enum],
53 pub brace_token
: token
::Brace
,
54 pub variants
: Punctuated
<Variant
, Token
![,]>,
57 /// A tagged union input to a `proc_macro_derive` macro.
59 /// *This type is available if Syn is built with the `"derive"`
62 pub union_token
: Token
![union],
63 pub fields
: FieldsNamed
,
67 do_not_generate_to_tokens
70 #[cfg(feature = "parsing")]
74 use parse
::{Parse, ParseStream, Result}
;
76 impl Parse
for DeriveInput
{
77 fn parse(input
: ParseStream
) -> Result
<Self> {
78 let attrs
= input
.call(Attribute
::parse_outer
)?
;
79 let vis
= input
.parse
::<Visibility
>()?
;
81 let lookahead
= input
.lookahead1();
82 if lookahead
.peek(Token
![struct]) {
83 let struct_token
= input
.parse
::<Token
![struct]>()?
;
84 let ident
= input
.parse
::<Ident
>()?
;
85 let generics
= input
.parse
::<Generics
>()?
;
86 let (where_clause
, fields
, semi
) = data_struct(input
)?
;
92 where_clause
: where_clause
,
95 data
: Data
::Struct(DataStruct
{
96 struct_token
: struct_token
,
101 } else if lookahead
.peek(Token
![enum]) {
102 let enum_token
= input
.parse
::<Token
![enum]>()?
;
103 let ident
= input
.parse
::<Ident
>()?
;
104 let generics
= input
.parse
::<Generics
>()?
;
105 let (where_clause
, brace
, variants
) = data_enum(input
)?
;
111 where_clause
: where_clause
,
114 data
: Data
::Enum(DataEnum
{
115 enum_token
: enum_token
,
120 } else if lookahead
.peek(Token
![union]) {
121 let union_token
= input
.parse
::<Token
![union]>()?
;
122 let ident
= input
.parse
::<Ident
>()?
;
123 let generics
= input
.parse
::<Generics
>()?
;
124 let (where_clause
, fields
) = data_union(input
)?
;
130 where_clause
: where_clause
,
133 data
: Data
::Union(DataUnion
{
134 union_token
: union_token
,
139 Err(lookahead
.error())
146 ) -> Result
<(Option
<WhereClause
>, Fields
, Option
<Token
![;]>)> {
147 let mut lookahead
= input
.lookahead1();
148 let mut where_clause
= None
;
149 if lookahead
.peek(Token
![where]) {
150 where_clause
= Some(input
.parse()?
);
151 lookahead
= input
.lookahead1();
154 if where_clause
.is_none() && lookahead
.peek(token
::Paren
) {
155 let fields
= input
.parse()?
;
157 lookahead
= input
.lookahead1();
158 if lookahead
.peek(Token
![where]) {
159 where_clause
= Some(input
.parse()?
);
160 lookahead
= input
.lookahead1();
163 if lookahead
.peek(Token
![;]) {
164 let semi
= input
.parse()?
;
165 Ok((where_clause
, Fields
::Unnamed(fields
), Some(semi
)))
167 Err(lookahead
.error())
169 } else if lookahead
.peek(token
::Brace
) {
170 let fields
= input
.parse()?
;
171 Ok((where_clause
, Fields
::Named(fields
), None
))
172 } else if lookahead
.peek(Token
![;]) {
173 let semi
= input
.parse()?
;
174 Ok((where_clause
, Fields
::Unit
, Some(semi
)))
176 Err(lookahead
.error())
185 Punctuated
<Variant
, Token
![,]>,
187 let where_clause
= input
.parse()?
;
190 let brace
= braced
!(content
in input
);
191 let variants
= content
.parse_terminated(Variant
::parse
)?
;
193 Ok((where_clause
, brace
, variants
))
196 pub fn data_union(input
: ParseStream
) -> Result
<(Option
<WhereClause
>, FieldsNamed
)> {
197 let where_clause
= input
.parse()?
;
198 let fields
= input
.parse()?
;
199 Ok((where_clause
, fields
))
203 #[cfg(feature = "printing")]
207 use proc_macro2
::TokenStream
;
210 use attr
::FilterAttrs
;
211 use print
::TokensOrDefault
;
213 impl ToTokens
for DeriveInput
{
214 fn to_tokens(&self, tokens
: &mut TokenStream
) {
215 for attr
in self.attrs
.outer() {
216 attr
.to_tokens(tokens
);
218 self.vis
.to_tokens(tokens
);
220 Data
::Struct(ref d
) => d
.struct_token
.to_tokens(tokens
),
221 Data
::Enum(ref d
) => d
.enum_token
.to_tokens(tokens
),
222 Data
::Union(ref d
) => d
.union_token
.to_tokens(tokens
),
224 self.ident
.to_tokens(tokens
);
225 self.generics
.to_tokens(tokens
);
227 Data
::Struct(ref data
) => match data
.fields
{
228 Fields
::Named(ref fields
) => {
229 self.generics
.where_clause
.to_tokens(tokens
);
230 fields
.to_tokens(tokens
);
232 Fields
::Unnamed(ref fields
) => {
233 fields
.to_tokens(tokens
);
234 self.generics
.where_clause
.to_tokens(tokens
);
235 TokensOrDefault(&data
.semi_token
).to_tokens(tokens
);
238 self.generics
.where_clause
.to_tokens(tokens
);
239 TokensOrDefault(&data
.semi_token
).to_tokens(tokens
);
242 Data
::Enum(ref data
) => {
243 self.generics
.where_clause
.to_tokens(tokens
);
244 data
.brace_token
.surround(tokens
, |tokens
| {
245 data
.variants
.to_tokens(tokens
);
248 Data
::Union(ref data
) => {
249 self.generics
.where_clause
.to_tokens(tokens
);
250 data
.fields
.to_tokens(tokens
);