use syn::{Ident, Member};12/// Converts an optional identifier or index into a [`syn::Member`] variant.3///4/// 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.5/// There is also [`syn::Fields::members`], but this method doesn't work when you're dealing with single / filtered fields.6///7/// Rust struct syntax allows for `Struct { foo: "string" }` with explicitly8/// named fields. It allows the `Struct { 0: "string" }` syntax when the struct9/// is declared as a tuple struct.10///11/// # Example12/// ```rust13/// use syn::{Ident, parse_str, DeriveInput, Data, DataStruct};14/// use quote::quote;15/// use bevy_macro_utils::as_member;16///17/// let ast: DeriveInput = syn::parse_str(18/// r#"19/// struct Mystruct {20/// field: usize,21/// #[my_derive]22/// other_field: usize23/// }24/// "#,25/// )26/// .unwrap();27///28/// let Data::Struct(DataStruct { fields, .. }) = &ast.data else { return };29///30/// let field_members = fields31/// .iter()32/// .enumerate()33/// .filter(|(_, field)| field.attrs.iter().any(|attr| attr.path().is_ident("my_derive")))34/// .map(|(i, field)| { as_member(field.ident.as_ref(), i) });35///36/// // it won't matter now if it's a named field or a unnamed field. e.g self.field or self.037/// quote!(38/// #(self.#field_members.do_something();)*39/// );40///41/// ```42///43pub fn as_member(ident: Option<&Ident>, index: usize) -> Member {44ident.map_or_else(|| Member::from(index), |ident| Member::Named(ident.clone()))45}464748