1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use ;
/// Converts an optional identifier or index into a [`syn::Member`] variant.
///
/// This is useful for when you want to access a field inside a `quote!` block regardless of whether it is an identifier or an index.
/// There is also [`syn::Fields::members`], but this method doesn't work when you're dealing with single / filtered fields.
///
/// Rust struct syntax allows for `Struct { foo: "string" }` with explicitly
/// named fields. It allows the `Struct { 0: "string" }` syntax when the struct
/// is declared as a tuple struct.
///
/// # Example
/// ```rust
/// use syn::{Ident, parse_str, DeriveInput, Data, DataStruct};
/// use quote::quote;
/// use bevy_macro_utils::as_member;
///
/// let ast: DeriveInput = syn::parse_str(
/// r#"
/// struct Mystruct {
/// field: usize,
/// #[my_derive]
/// other_field: usize
/// }
/// "#,
/// )
/// .unwrap();
///
/// let Data::Struct(DataStruct { fields, .. }) = &ast.data else { return };
///
/// let field_members = fields
/// .iter()
/// .enumerate()
/// .filter(|(_, field)| field.attrs.iter().any(|attr| attr.path().is_ident("my_derive")))
/// .map(|(i, field)| { as_member(field.ident.as_ref(), i) });
///
/// // it won't matter now if it's a named field or a unnamed field. e.g self.field or self.0
/// quote!(
/// #(self.#field_members.do_something();)*
/// );
///
/// ```
///