macro_tools/
struct_like.rs1mod private
7{
8 #[ allow( clippy::wildcard_imports ) ]
9 use crate::*;
10
11 #[ derive( Debug, PartialEq, Clone ) ]
13 pub enum FieldOrVariant< 'a >
14 {
15 Field( &'a syn::Field ),
17 Variant( &'a syn::Variant ),
19 }
20
21 impl Copy for FieldOrVariant< '_ >
22 {
23 }
24
25 impl< 'a > From< &'a syn::Field > for FieldOrVariant< 'a >
26 {
27 fn from( field : &'a syn::Field ) -> Self
28 {
29 FieldOrVariant::Field( field )
30 }
31 }
32
33 impl< 'a > From< &'a syn::Variant > for FieldOrVariant< 'a >
34 {
35 fn from( variant : &'a syn::Variant ) -> Self
36 {
37 FieldOrVariant::Variant( variant )
38 }
39 }
40
41 impl quote::ToTokens for FieldOrVariant< '_ >
42 {
43 fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream )
44 {
45 match self
46 {
47 FieldOrVariant::Field( item ) =>
48 {
49 item.to_tokens( tokens );
50 },
51 FieldOrVariant::Variant( item ) =>
52 {
53 item.to_tokens( tokens );
54 },
55 }
56 }
57 }
58
59 impl FieldOrVariant< '_ >
60 {
61
62 #[ must_use ]
64 pub fn attrs( &self ) -> &Vec< syn::Attribute >
65 {
66 match self
67 {
68 FieldOrVariant::Field( e ) => &e.attrs,
69 FieldOrVariant::Variant( e ) => &e.attrs,
70 }
71 }
72
73 #[ must_use ]
75 pub fn vis( &self ) -> Option< &syn::Visibility >
76 {
77 match self
78 {
79 FieldOrVariant::Field( e ) => Some( &e.vis ),
80 FieldOrVariant::Variant( _ ) => None,
81 }
82 }
83
84 #[ must_use ]
86 pub fn mutability( &self ) -> Option< &syn::FieldMutability >
87 {
88 match self
89 {
90 FieldOrVariant::Field( e ) => Some( &e.mutability ),
91 FieldOrVariant::Variant( _ ) => None,
92 }
93 }
94
95 #[ must_use]
97 pub fn ident( &self ) -> Option< &syn::Ident >
98 {
99 match self
100 {
101 FieldOrVariant::Field( e ) => e.ident.as_ref(),
102 FieldOrVariant::Variant( e ) => Some( &e.ident ),
103 }
104 }
105
106 #[ must_use ]
108 pub fn typ( &self ) -> Option< &syn::Type >
109 {
110 match self
111 {
112 FieldOrVariant::Field( e ) =>
113 {
114 Some( &e.ty )
115 },
116 FieldOrVariant::Variant( _e ) =>
117 {
118 None
119 },
120 }
121 }
122
123 #[ must_use ]
125 pub fn fields( &self ) -> Option< &syn::Fields >
126 {
127 match self
128 {
129 FieldOrVariant::Field( _ ) => None,
130 FieldOrVariant::Variant( e ) => Some( &e.fields ),
131 }
132 }
133
134 #[ must_use ]
136 pub fn discriminant( &self ) -> Option< &( syn::token::Eq, syn::Expr ) >
137 {
138 match self
139 {
140 FieldOrVariant::Field( _ ) => None,
141 FieldOrVariant::Variant( e ) => e.discriminant.as_ref(),
142 }
143 }
144
145 }
146
147 #[ derive( Debug, PartialEq ) ]
162 pub enum StructLike
163 {
164 Unit( syn::ItemStruct ),
166 Struct( syn::ItemStruct ),
168 Enum( syn::ItemEnum ),
170 }
171
172 impl From< syn::ItemStruct > for StructLike
173 {
174 fn from( item_struct : syn::ItemStruct ) -> Self
175 {
176 if item_struct.fields.is_empty()
177 {
178 StructLike::Unit( item_struct )
179 }
180 else
181 {
182 StructLike::Struct( item_struct )
183 }
184 }
185 }
186
187 impl From< syn::ItemEnum > for StructLike
188 {
189 fn from( item_enum : syn::ItemEnum ) -> Self
190 {
191 StructLike::Enum( item_enum )
192 }
193 }
194
195 impl syn::parse::Parse for StructLike
196 {
197 fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self >
198 {
199 use syn::{ ItemStruct, ItemEnum, Visibility, Attribute };
200
201 let attributes : Vec< Attribute > = input.call( Attribute::parse_outer )?;
203 let visibility : Visibility = input.parse().unwrap_or( syn::Visibility::Inherited );
205
206 let lookahead = input.lookahead1();
208 if lookahead.peek( syn::Token![ struct ] )
209 {
210 let mut item_struct : ItemStruct = input.parse()?;
212 item_struct.vis = visibility;
213 item_struct.attrs = attributes;
214 if item_struct.fields.is_empty()
215 {
216 Ok( StructLike::Unit( item_struct ) )
217 }
218 else
219 {
220 Ok( StructLike::Struct( item_struct ) )
221 }
222 }
223 else if lookahead.peek( syn::Token![ enum ] )
224 {
225 let mut item_enum : ItemEnum = input.parse()?;
227 item_enum.vis = visibility;
228 item_enum.attrs = attributes;
229 Ok( StructLike::Enum( item_enum ) )
230 }
231 else
232 {
233 Err( lookahead.error() )
234 }
235 }
236 }
237
238 impl quote::ToTokens for StructLike
239 {
240 fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream )
241 {
242 match self
243 {
244 StructLike::Unit( item ) | StructLike::Struct( item ) =>
245 {
246 item.to_tokens( tokens );
247 },
248 StructLike::Enum( item ) =>
249 {
250 item.to_tokens( tokens );
251 },
252 }
253 }
254 }
255
256 impl StructLike
257 {
258
259
260 pub fn elements< 'a >( &'a self ) -> BoxedIter< 'a, FieldOrVariant< 'a > >
263 {
264 match self
265 {
266 StructLike::Unit( _ ) =>
267 {
268 let empty : Vec< FieldOrVariant< 'a > > = vec![];
269 Box::new( empty.into_iter() )
270 },
271 StructLike::Struct( item ) =>
272 {
273 let fields = item.fields.iter().map( FieldOrVariant::from );
274 Box::new( fields )
275 },
276 StructLike::Enum( item ) =>
277 {
278 let variants = item.variants.iter().map( FieldOrVariant::from );
279 Box::new( variants )
280 },
281 }
282 }
283
284 #[ must_use ]
286 pub fn attrs( &self ) -> &Vec< syn::Attribute >
287 {
288 match self
289 {
290 StructLike::Unit( item ) |
291 StructLike::Struct( item ) =>
292 {
293 &item.attrs
294 },
295 StructLike::Enum( item ) =>
296 {
297 &item.attrs
298 },
299 }
300 }
301
302 #[ must_use ]
304 pub fn vis( &self ) -> &syn::Visibility
305 {
306 match self
307 {
308 StructLike::Unit( item ) |
309 StructLike::Struct( item ) =>
310 {
311 &item.vis
312 },
313 StructLike::Enum( item ) =>
314 {
315 &item.vis
316 },
317 }
318 }
319
320 #[ must_use ]
322 pub fn ident( &self ) -> &syn::Ident
323 {
324 match self
325 {
326 StructLike::Unit( item ) |
327 StructLike::Struct( item ) =>
328 {
329 &item.ident
330 },
331 StructLike::Enum( item ) =>
332 {
333 &item.ident
334 },
335 }
336 }
337
338 #[ must_use ]
340 pub fn generics( &self ) -> &syn::Generics
341 {
342 match self
343 {
344 StructLike::Unit( item ) |
345 StructLike::Struct( item ) =>
346 {
347 &item.generics
348 },
349 StructLike::Enum( item ) =>
350 {
351 &item.generics
352 },
353 }
354 }
355
356 #[ must_use ]
359 pub fn fields< 'a >( &'a self ) -> BoxedIter< 'a, &'a syn::Field >
360 {
361 let result : BoxedIter< 'a, &'a syn::Field > = match self
362 {
363 StructLike::Unit( _item ) =>
364 {
365 Box::new( core::iter::empty() )
366 },
367 StructLike::Struct( item ) =>
368 {
369 Box::new( item.fields.iter() )
370 },
371 StructLike::Enum( _item ) =>
372 {
373 Box::new( core::iter::empty() )
374 },
375 };
376 result
377 }
378
379 #[ must_use ]
384 pub fn field_names( &self ) -> Option< BoxedIter< '_, &syn::Ident >>
385 {
386 match self
387 {
388 StructLike::Unit( item ) |
389 StructLike::Struct( item ) =>
390 {
391 item_struct::field_names( item )
392 },
393 StructLike::Enum( _item ) =>
394 {
395 let iter = Box::new( self.fields().map( | field | field.ident.as_ref().unwrap() ) );
396 Some( iter )
397 },
398 }
399 }
400
401 #[ must_use ]
403 pub fn field_types( & self )
404 -> BoxedIter< '_, & syn::Type >
405 {
411 Box::new( self.fields().map( move | field | &field.ty ) )
412 }
413
414 #[ must_use ]
417 pub fn field_attrs( & self )
418 -> BoxedIter< '_, &Vec< syn::Attribute > >
419 {
425 Box::new( self.fields().map( | field | &field.attrs ) )
426 }
427
428 #[ must_use ]
430 pub fn first_field( &self ) -> Option< &syn::Field >
431 {
432 self.fields().next()
433 }
435
436 }
437
438 }
441
442#[ doc( inline ) ]
443#[ allow( unused_imports ) ]
444pub use own::*;
445
446#[ allow( unused_imports ) ]
448pub mod own
449{
450 #[ allow( clippy::wildcard_imports ) ]
451 use super::*;
452 #[ doc( inline ) ]
453 pub use orphan::*;
454 #[ doc( inline ) ]
455 pub use private::
456 {
457 StructLike,
458 FieldOrVariant,
459 };
460}
461
462#[ allow( unused_imports ) ]
464pub mod orphan
465{
466 #[ allow( clippy::wildcard_imports ) ]
467 use super::*;
468 #[ doc( inline ) ]
469 pub use exposed::*;
470}
471
472#[ allow( unused_imports ) ]
474pub mod exposed
475{
476 #[ allow( clippy::wildcard_imports ) ]
477 use super::*;
478 pub use super::super::struct_like;
479
480 #[ doc( inline ) ]
481 pub use prelude::*;
482}
483
484#[ allow( unused_imports ) ]
486pub mod prelude
487{
488 use super::*;
489}