1use super::*;
2use crate::punctuated::Punctuated;
3
4ast_struct! {
5 pub struct DeriveInput {
9 pub attrs: Vec<Attribute>,
11
12 pub vis: Visibility,
14
15 pub ident: Ident,
17
18 pub generics: Generics,
20
21 pub data: Data,
23 }
24}
25
26ast_enum_of_structs! {
27 pub enum Data {
40 Struct(DataStruct),
42
43 Enum(DataEnum),
45
46 Union(DataUnion),
48 }
49
50 do_not_generate_to_tokens
51}
52
53ast_struct! {
54 pub struct DataStruct {
59 pub struct_token: Token![struct],
60 pub fields: Fields,
61 pub semi_token: Option<Token![;]>,
62 }
63}
64
65ast_struct! {
66 pub struct DataEnum {
71 pub enum_token: Token![enum],
72 pub brace_token: token::Brace,
73 pub variants: Punctuated<Variant, Token![,]>,
74 }
75}
76
77ast_struct! {
78 pub struct DataUnion {
83 pub union_token: Token![union],
84 pub fields: FieldsNamed,
85 }
86}
87
88#[cfg(feature = "parsing")]
89pub mod parsing {
90 use super::*;
91
92 use crate::parse::{Parse, ParseStream, Result};
93
94 impl Parse for DeriveInput {
95 fn parse(input: ParseStream) -> Result<Self> {
96 let attrs = input.call(Attribute::parse_outer)?;
97 let vis = input.parse::<Visibility>()?;
98
99 let lookahead = input.lookahead1();
100 if lookahead.peek(Token![struct]) {
101 let struct_token = input.parse::<Token![struct]>()?;
102 let ident = input.parse::<Ident>()?;
103 let generics = input.parse::<Generics>()?;
104 let (where_clause, fields, semi) = data_struct(input)?;
105 Ok(DeriveInput {
106 attrs,
107 vis,
108 ident,
109 generics: Generics {
110 where_clause,
111 ..generics
112 },
113 data: Data::Struct(DataStruct {
114 struct_token,
115 fields,
116 semi_token: semi,
117 }),
118 })
119 } else if lookahead.peek(Token![enum]) {
120 let enum_token = input.parse::<Token![enum]>()?;
121 let ident = input.parse::<Ident>()?;
122 let generics = input.parse::<Generics>()?;
123 let (where_clause, brace, variants) = data_enum(input)?;
124 Ok(DeriveInput {
125 attrs,
126 vis,
127 ident,
128 generics: Generics {
129 where_clause,
130 ..generics
131 },
132 data: Data::Enum(DataEnum {
133 enum_token,
134 brace_token: brace,
135 variants,
136 }),
137 })
138 } else if lookahead.peek(Token![union]) {
139 let union_token = input.parse::<Token![union]>()?;
140 let ident = input.parse::<Ident>()?;
141 let generics = input.parse::<Generics>()?;
142 let (where_clause, fields) = data_union(input)?;
143 Ok(DeriveInput {
144 attrs,
145 vis,
146 ident,
147 generics: Generics {
148 where_clause,
149 ..generics
150 },
151 data: Data::Union(DataUnion {
152 union_token,
153 fields,
154 }),
155 })
156 } else {
157 Err(lookahead.error())
158 }
159 }
160 }
161
162 pub fn data_struct(
163 input: ParseStream,
164 ) -> Result<(Option<WhereClause>, Fields, Option<Token![;]>)> {
165 let mut lookahead = input.lookahead1();
166 let mut where_clause = None;
167 if lookahead.peek(Token![where]) {
168 where_clause = Some(input.parse()?);
169 lookahead = input.lookahead1();
170 }
171
172 if where_clause.is_none() && lookahead.peek(token::Paren) {
173 let fields = input.parse()?;
174
175 lookahead = input.lookahead1();
176 if lookahead.peek(Token![where]) {
177 where_clause = Some(input.parse()?);
178 lookahead = input.lookahead1();
179 }
180
181 if lookahead.peek(Token![;]) {
182 let semi = input.parse()?;
183 Ok((where_clause, Fields::Unnamed(fields), Some(semi)))
184 } else {
185 Err(lookahead.error())
186 }
187 } else if lookahead.peek(token::Brace) {
188 let fields = input.parse()?;
189 Ok((where_clause, Fields::Named(fields), None))
190 } else if lookahead.peek(Token![;]) {
191 let semi = input.parse()?;
192 Ok((where_clause, Fields::Unit, Some(semi)))
193 } else {
194 Err(lookahead.error())
195 }
196 }
197
198 pub fn data_enum(
199 input: ParseStream,
200 ) -> Result<(
201 Option<WhereClause>,
202 token::Brace,
203 Punctuated<Variant, Token![,]>,
204 )> {
205 let where_clause = input.parse()?;
206
207 let content;
208 let brace = braced!(content in input);
209 let variants = content.parse_terminated(Variant::parse)?;
210
211 Ok((where_clause, brace, variants))
212 }
213
214 pub fn data_union(input: ParseStream) -> Result<(Option<WhereClause>, FieldsNamed)> {
215 let where_clause = input.parse()?;
216 let fields = input.parse()?;
217 Ok((where_clause, fields))
218 }
219}
220
221#[cfg(feature = "printing")]
222mod printing {
223 use super::*;
224
225 use proc_macro2::TokenStream;
226 use quote::ToTokens;
227
228 use crate::attr::FilterAttrs;
229 use crate::print::TokensOrDefault;
230
231 impl ToTokens for DeriveInput {
232 fn to_tokens(&self, tokens: &mut TokenStream) {
233 for attr in self.attrs.outer() {
234 attr.to_tokens(tokens);
235 }
236 self.vis.to_tokens(tokens);
237 match &self.data {
238 Data::Struct(d) => d.struct_token.to_tokens(tokens),
239 Data::Enum(d) => d.enum_token.to_tokens(tokens),
240 Data::Union(d) => d.union_token.to_tokens(tokens),
241 }
242 self.ident.to_tokens(tokens);
243 self.generics.to_tokens(tokens);
244 match &self.data {
245 Data::Struct(data) => match &data.fields {
246 Fields::Named(fields) => {
247 self.generics.where_clause.to_tokens(tokens);
248 fields.to_tokens(tokens);
249 }
250 Fields::Unnamed(fields) => {
251 fields.to_tokens(tokens);
252 self.generics.where_clause.to_tokens(tokens);
253 TokensOrDefault(&data.semi_token).to_tokens(tokens);
254 }
255 Fields::Unit => {
256 self.generics.where_clause.to_tokens(tokens);
257 TokensOrDefault(&data.semi_token).to_tokens(tokens);
258 }
259 },
260 Data::Enum(data) => {
261 self.generics.where_clause.to_tokens(tokens);
262 data.brace_token.surround(tokens, |tokens| {
263 data.variants.to_tokens(tokens);
264 });
265 }
266 Data::Union(data) => {
267 self.generics.where_clause.to_tokens(tokens);
268 data.fields.to_tokens(tokens);
269 }
270 }
271 }
272 }
273}