reflection: replace impl_reflect_struct with impl_reflect (#11437)

# Objective

- `impl_reflect_struct` doesn't cover tuple structs or enums.
- Problem brought up [on
Discord](https://discord.com/channels/691052431525675048/1002362493634629796/1190623345817960463).

## Solution

- Replaces `impl_reflect_struct` with the new `impl_reflect` which works
for tuple structs and enums too.

---

## Changelog

- Internally in `bevy_reflect_derive`, we have a new `ReflectProvenance`
type which is composed of `ReflectTraitToImpl` and `ReflectSource`.
- `impl_reflect_struct` is gone and totally superseded by
`impl_reflect`.

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
This commit is contained in:
radiish 2024-01-30 14:39:01 +00:00 committed by GitHub
parent 4b7ef44bb4
commit df761af49b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 258 additions and 188 deletions

View file

@ -5,11 +5,12 @@
//! the derive helper attribute for `Reflect`, which looks like: //! the derive helper attribute for `Reflect`, which looks like:
//! `#[reflect(PartialEq, Default, ...)]` and `#[reflect_value(PartialEq, Default, ...)]`. //! `#[reflect(PartialEq, Default, ...)]` and `#[reflect_value(PartialEq, Default, ...)]`.
use crate::derive_data::ReflectTraitToImpl;
use crate::utility; use crate::utility;
use bevy_macro_utils::fq_std::{FQAny, FQOption}; use bevy_macro_utils::fq_std::{FQAny, FQOption};
use proc_macro2::{Ident, Span, TokenTree}; use proc_macro2::{Ident, Span, TokenTree};
use quote::quote_spanned; use quote::quote_spanned;
use syn::parse::{Parse, ParseStream}; use syn::parse::ParseStream;
use syn::punctuated::Punctuated; use syn::punctuated::Punctuated;
use syn::spanned::Spanned; use syn::spanned::Spanned;
use syn::token::Comma; use syn::token::Comma;
@ -220,10 +221,7 @@ pub(crate) struct ReflectTraits {
} }
impl ReflectTraits { impl ReflectTraits {
pub fn from_meta_list( pub fn from_meta_list(meta: &MetaList, trait_: ReflectTraitToImpl) -> Result<Self, syn::Error> {
meta: &MetaList,
is_from_reflect_derive: bool,
) -> Result<Self, syn::Error> {
match meta.tokens.clone().into_iter().next() { match meta.tokens.clone().into_iter().next() {
// Handles `#[reflect(where T: Trait, U::Assoc: Trait)]` // Handles `#[reflect(where T: Trait, U::Assoc: Trait)]`
Some(TokenTree::Ident(ident)) if ident == "where" => Ok(Self { Some(TokenTree::Ident(ident)) if ident == "where" => Ok(Self {
@ -232,14 +230,14 @@ impl ReflectTraits {
}), }),
_ => Self::from_metas( _ => Self::from_metas(
meta.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)?, meta.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)?,
is_from_reflect_derive, trait_,
), ),
} }
} }
fn from_metas( fn from_metas(
metas: Punctuated<Meta, Comma>, metas: Punctuated<Meta, Comma>,
is_from_reflect_derive: bool, trait_: ReflectTraitToImpl,
) -> Result<Self, syn::Error> { ) -> Result<Self, syn::Error> {
let mut traits = ReflectTraits::default(); let mut traits = ReflectTraits::default();
for meta in &metas { for meta in &metas {
@ -317,7 +315,7 @@ impl ReflectTraits {
// Override `lit` if this is a `FromReflect` derive. // Override `lit` if this is a `FromReflect` derive.
// This typically means a user is opting out of the default implementation // This typically means a user is opting out of the default implementation
// from the `Reflect` derive and using the `FromReflect` derive directly instead. // from the `Reflect` derive and using the `FromReflect` derive directly instead.
is_from_reflect_derive (trait_ == ReflectTraitToImpl::FromReflect)
.then(|| LitBool::new(true, Span::call_site())) .then(|| LitBool::new(true, Span::call_site()))
.unwrap_or_else(|| lit.clone()) .unwrap_or_else(|| lit.clone())
})?); })?);
@ -334,6 +332,10 @@ impl ReflectTraits {
Ok(traits) Ok(traits)
} }
pub fn parse(input: ParseStream, trait_: ReflectTraitToImpl) -> syn::Result<Self> {
ReflectTraits::from_metas(Punctuated::parse_terminated(input)?, trait_)
}
/// Returns true if the given reflected trait name (i.e. `ReflectDefault` for `Default`) /// Returns true if the given reflected trait name (i.e. `ReflectDefault` for `Default`)
/// is registered for this type. /// is registered for this type.
pub fn contains(&self, name: &str) -> bool { pub fn contains(&self, name: &str) -> bool {
@ -466,12 +468,6 @@ impl ReflectTraits {
} }
} }
impl Parse for ReflectTraits {
fn parse(input: ParseStream) -> syn::Result<Self> {
ReflectTraits::from_metas(Punctuated::<Meta, Comma>::parse_terminated(input)?, false)
}
}
/// Adds an identifier to a vector of identifiers if it is not already present. /// Adds an identifier to a vector of identifiers if it is not already present.
/// ///
/// Returns an error if the identifier already exists in the list. /// Returns an error if the identifier already exists in the list.

View file

@ -1,3 +1,5 @@
use core::fmt;
use crate::container_attributes::{FromReflectAttrs, ReflectTraits, TypePathAttrs}; use crate::container_attributes::{FromReflectAttrs, ReflectTraits, TypePathAttrs};
use crate::field_attributes::{parse_field_attrs, ReflectFieldAttr}; use crate::field_attributes::{parse_field_attrs, ReflectFieldAttr};
use crate::type_path::parse_path_no_leading_colon; use crate::type_path::parse_path_no_leading_colon;
@ -140,10 +142,46 @@ enum ReflectMode {
Value, Value,
} }
/// How the macro was invoked.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub(crate) enum ReflectImplSource {
ImplRemoteType,
DeriveLocalType,
}
/// Which trait the macro explicitly implements.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub(crate) enum ReflectTraitToImpl {
Reflect,
FromReflect,
TypePath,
}
/// The provenance of a macro invocation.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub(crate) struct ReflectProvenance {
pub source: ReflectImplSource,
pub trait_: ReflectTraitToImpl,
}
impl fmt::Display for ReflectProvenance {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::{ReflectImplSource as S, ReflectTraitToImpl as T};
let str = match (self.source, self.trait_) {
(S::ImplRemoteType, T::Reflect) => "`impl_reflect`",
(S::DeriveLocalType, T::Reflect) => "`#[derive(Reflect)]`",
(S::DeriveLocalType, T::FromReflect) => "`#[derive(FromReflect)]`",
(S::DeriveLocalType, T::TypePath) => "`#[derive(TypePath)]`",
(S::ImplRemoteType, T::FromReflect | T::TypePath) => unreachable!(),
};
f.write_str(str)
}
}
impl<'a> ReflectDerive<'a> { impl<'a> ReflectDerive<'a> {
pub fn from_input( pub fn from_input(
input: &'a DeriveInput, input: &'a DeriveInput,
is_from_reflect_derive: bool, provenance: ReflectProvenance,
) -> Result<Self, syn::Error> { ) -> Result<Self, syn::Error> {
let mut traits = ReflectTraits::default(); let mut traits = ReflectTraits::default();
// Should indicate whether `#[reflect_value]` was used. // Should indicate whether `#[reflect_value]` was used.
@ -167,8 +205,7 @@ impl<'a> ReflectDerive<'a> {
} }
reflect_mode = Some(ReflectMode::Normal); reflect_mode = Some(ReflectMode::Normal);
let new_traits = let new_traits = ReflectTraits::from_meta_list(meta_list, provenance.trait_)?;
ReflectTraits::from_meta_list(meta_list, is_from_reflect_derive)?;
traits.merge(new_traits)?; traits.merge(new_traits)?;
} }
Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => { Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
@ -180,8 +217,7 @@ impl<'a> ReflectDerive<'a> {
} }
reflect_mode = Some(ReflectMode::Value); reflect_mode = Some(ReflectMode::Value);
let new_traits = let new_traits = ReflectTraits::from_meta_list(meta_list, provenance.trait_)?;
ReflectTraits::from_meta_list(meta_list, is_from_reflect_derive)?;
traits.merge(new_traits)?; traits.merge(new_traits)?;
} }
Meta::Path(path) if path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => { Meta::Path(path) if path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
@ -260,6 +296,16 @@ impl<'a> ReflectDerive<'a> {
let meta = ReflectMeta::new(type_path, traits); let meta = ReflectMeta::new(type_path, traits);
if provenance.source == ReflectImplSource::ImplRemoteType
&& meta.type_path_attrs().should_auto_derive()
&& !meta.type_path().has_custom_path()
{
return Err(syn::Error::new(
meta.type_path().span(),
format!("a #[{TYPE_PATH_ATTRIBUTE_NAME} = \"...\"] attribute must be specified when using {provenance}")
));
}
#[cfg(feature = "documentation")] #[cfg(feature = "documentation")]
let meta = meta.with_docs(doc); let meta = meta.with_docs(doc);

View file

@ -31,11 +31,10 @@ mod utility;
use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct}; use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};
use container_attributes::ReflectTraits; use container_attributes::ReflectTraits;
use derive_data::ReflectTypePath; use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use reflect_value::ReflectValueDef; use reflect_value::ReflectValueDef;
use syn::spanned::Spanned;
use syn::{parse_macro_input, DeriveInput}; use syn::{parse_macro_input, DeriveInput};
use type_path::NamedTypePathDef; use type_path::NamedTypePathDef;
@ -44,6 +43,65 @@ pub(crate) static REFLECT_VALUE_ATTRIBUTE_NAME: &str = "reflect_value";
pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path"; pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path";
pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name"; pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
/// Used both for [`impl_reflect`] and [`derive_reflect`].
///
/// [`impl_reflect`]: macro@impl_reflect
/// [`derive_reflect`]: derive_reflect()
fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream {
let derive_data = match ReflectDerive::from_input(
&ast,
ReflectProvenance {
source,
trait_: ReflectTraitToImpl::Reflect,
},
) {
Ok(data) => data,
Err(err) => return err.into_compile_error().into(),
};
let (reflect_impls, from_reflect_impl) = match derive_data {
ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => (
impls::impl_struct(&struct_data),
if struct_data.meta().from_reflect().should_auto_derive() {
Some(from_reflect::impl_struct(&struct_data))
} else {
None
},
),
ReflectDerive::TupleStruct(struct_data) => (
impls::impl_tuple_struct(&struct_data),
if struct_data.meta().from_reflect().should_auto_derive() {
Some(from_reflect::impl_tuple_struct(&struct_data))
} else {
None
},
),
ReflectDerive::Enum(enum_data) => (
impls::impl_enum(&enum_data),
if enum_data.meta().from_reflect().should_auto_derive() {
Some(from_reflect::impl_enum(&enum_data))
} else {
None
},
),
ReflectDerive::Value(meta) => (
impls::impl_value(&meta),
if meta.from_reflect().should_auto_derive() {
Some(from_reflect::impl_value(&meta))
} else {
None
},
),
};
TokenStream::from(quote! {
const _: () = {
#reflect_impls
#from_reflect_impl
};
})
}
/// The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait. /// The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait.
/// ///
/// This macro can be used on all structs and enums (unions are not supported). /// This macro can be used on all structs and enums (unions are not supported).
@ -240,53 +298,7 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
#[proc_macro_derive(Reflect, attributes(reflect, reflect_value, type_path, type_name))] #[proc_macro_derive(Reflect, attributes(reflect, reflect_value, type_path, type_name))]
pub fn derive_reflect(input: TokenStream) -> TokenStream { pub fn derive_reflect(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput); let ast = parse_macro_input!(input as DeriveInput);
match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)
let derive_data = match ReflectDerive::from_input(&ast, false) {
Ok(data) => data,
Err(err) => return err.into_compile_error().into(),
};
let (reflect_impls, from_reflect_impl) = match derive_data {
ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => (
impls::impl_struct(&struct_data),
if struct_data.meta().from_reflect().should_auto_derive() {
Some(from_reflect::impl_struct(&struct_data))
} else {
None
},
),
ReflectDerive::TupleStruct(struct_data) => (
impls::impl_tuple_struct(&struct_data),
if struct_data.meta().from_reflect().should_auto_derive() {
Some(from_reflect::impl_tuple_struct(&struct_data))
} else {
None
},
),
ReflectDerive::Enum(enum_data) => (
impls::impl_enum(&enum_data),
if enum_data.meta().from_reflect().should_auto_derive() {
Some(from_reflect::impl_enum(&enum_data))
} else {
None
},
),
ReflectDerive::Value(meta) => (
impls::impl_value(&meta),
if meta.from_reflect().should_auto_derive() {
Some(from_reflect::impl_value(&meta))
} else {
None
},
),
};
TokenStream::from(quote! {
const _: () = {
#reflect_impls
#from_reflect_impl
};
})
} }
/// Derives the `FromReflect` trait. /// Derives the `FromReflect` trait.
@ -319,7 +331,13 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream {
pub fn derive_from_reflect(input: TokenStream) -> TokenStream { pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput); let ast = parse_macro_input!(input as DeriveInput);
let derive_data = match ReflectDerive::from_input(&ast, true) { let derive_data = match ReflectDerive::from_input(
&ast,
ReflectProvenance {
source: ReflectImplSource::DeriveLocalType,
trait_: ReflectTraitToImpl::FromReflect,
},
) {
Ok(data) => data, Ok(data) => data,
Err(err) => return err.into_compile_error().into(), Err(err) => return err.into_compile_error().into(),
}; };
@ -358,7 +376,13 @@ pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
#[proc_macro_derive(TypePath, attributes(type_path, type_name))] #[proc_macro_derive(TypePath, attributes(type_path, type_name))]
pub fn derive_type_path(input: TokenStream) -> TokenStream { pub fn derive_type_path(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput); let ast = parse_macro_input!(input as DeriveInput);
let derive_data = match ReflectDerive::from_input(&ast, false) { let derive_data = match ReflectDerive::from_input(
&ast,
ReflectProvenance {
source: ReflectImplSource::DeriveLocalType,
trait_: ReflectTraitToImpl::TypePath,
},
) {
Ok(data) => data, Ok(data) => data,
Err(err) => return err.into_compile_error().into(), Err(err) => return err.into_compile_error().into(),
}; };
@ -459,7 +483,7 @@ pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {
/// [deriving `Reflect`]: Reflect /// [deriving `Reflect`]: Reflect
#[proc_macro] #[proc_macro]
pub fn impl_reflect_value(input: TokenStream) -> TokenStream { pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
let def = parse_macro_input!(input as ReflectValueDef); let def = parse_macro_input!(input with ReflectValueDef::parse_reflect);
let default_name = &def.type_path.segments.last().unwrap().ident; let default_name = &def.type_path.segments.last().unwrap().ident;
let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() { let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {
@ -492,8 +516,9 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
/// the definitions of cannot be altered. /// the definitions of cannot be altered.
/// ///
/// This macro is an alternative to [`impl_reflect_value!`] and [`impl_from_reflect_value!`] /// This macro is an alternative to [`impl_reflect_value!`] and [`impl_from_reflect_value!`]
/// which implement foreign types as Value types. Note that there is no `impl_from_reflect_struct`, /// which implement foreign types as Value types. Note that there is no `impl_from_reflect`,
/// as this macro will do the job of both. This macro implements them as `Struct` types, /// as this macro will do the job of both. This macro implements them using one of the reflect
/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.),
/// which have greater functionality. The type being reflected must be in scope, as you cannot /// which have greater functionality. The type being reflected must be in scope, as you cannot
/// qualify it in the macro as e.g. `bevy::prelude::Vec3`. /// qualify it in the macro as e.g. `bevy::prelude::Vec3`.
/// ///
@ -510,7 +535,7 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
/// ```ignore (bevy_reflect is not accessible from this crate) /// ```ignore (bevy_reflect is not accessible from this crate)
/// use bevy::prelude::Vec3; /// use bevy::prelude::Vec3;
/// ///
/// impl_reflect_struct!( /// impl_reflect!(
/// #[reflect(PartialEq, Serialize, Deserialize, Default)] /// #[reflect(PartialEq, Serialize, Deserialize, Default)]
/// #[type_path = "bevy::prelude"] /// #[type_path = "bevy::prelude"]
/// struct Vec3 { /// struct Vec3 {
@ -521,51 +546,9 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
/// ); /// );
/// ``` /// ```
#[proc_macro] #[proc_macro]
pub fn impl_reflect_struct(input: TokenStream) -> TokenStream { pub fn impl_reflect(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput); let ast = parse_macro_input!(input as DeriveInput);
let derive_data = match ReflectDerive::from_input(&ast, false) { match_reflect_impls(ast, ReflectImplSource::ImplRemoteType)
Ok(data) => data,
Err(err) => return err.into_compile_error().into(),
};
let output = match derive_data {
ReflectDerive::Struct(struct_data) => {
if !struct_data.meta().type_path().has_custom_path() {
return syn::Error::new(
struct_data.meta().type_path().span(),
format!("a #[{TYPE_PATH_ATTRIBUTE_NAME} = \"...\"] attribute must be specified when using `impl_reflect_struct`")
)
.into_compile_error()
.into();
}
let impl_struct = impls::impl_struct(&struct_data);
let impl_from_struct = from_reflect::impl_struct(&struct_data);
quote! {
#impl_struct
#impl_from_struct
}
}
ReflectDerive::TupleStruct(..) => syn::Error::new(
ast.span(),
"impl_reflect_struct does not support tuple structs",
)
.into_compile_error(),
ReflectDerive::UnitStruct(..) => syn::Error::new(
ast.span(),
"impl_reflect_struct does not support unit structs",
)
.into_compile_error(),
_ => syn::Error::new(ast.span(), "impl_reflect_struct only supports structs")
.into_compile_error(),
};
TokenStream::from(quote! {
const _: () = {
#output
};
})
} }
/// A macro used to generate a `FromReflect` trait implementation for the given type. /// A macro used to generate a `FromReflect` trait implementation for the given type.
@ -590,7 +573,7 @@ pub fn impl_reflect_struct(input: TokenStream) -> TokenStream {
/// [derives `Reflect`]: Reflect /// [derives `Reflect`]: Reflect
#[proc_macro] #[proc_macro]
pub fn impl_from_reflect_value(input: TokenStream) -> TokenStream { pub fn impl_from_reflect_value(input: TokenStream) -> TokenStream {
let def = parse_macro_input!(input as ReflectValueDef); let def = parse_macro_input!(input with ReflectValueDef::parse_from_reflect);
let default_name = &def.type_path.segments.last().unwrap().ident; let default_name = &def.type_path.segments.last().unwrap().ident;
let type_path = if def.type_path.leading_colon.is_none() let type_path = if def.type_path.leading_colon.is_none()

View file

@ -1,6 +1,7 @@
use crate::container_attributes::ReflectTraits; use crate::container_attributes::ReflectTraits;
use crate::derive_data::ReflectTraitToImpl;
use crate::type_path::CustomPathDef; use crate::type_path::CustomPathDef;
use syn::parse::{Parse, ParseStream}; use syn::parse::ParseStream;
use syn::token::Paren; use syn::token::Paren;
use syn::{parenthesized, Attribute, Generics, Path}; use syn::{parenthesized, Attribute, Generics, Path};
@ -32,8 +33,16 @@ pub(crate) struct ReflectValueDef {
pub custom_path: Option<CustomPathDef>, pub custom_path: Option<CustomPathDef>,
} }
impl Parse for ReflectValueDef { impl ReflectValueDef {
fn parse(input: ParseStream) -> syn::Result<Self> { pub fn parse_reflect(input: ParseStream) -> syn::Result<Self> {
Self::parse(input, ReflectTraitToImpl::Reflect)
}
pub fn parse_from_reflect(input: ParseStream) -> syn::Result<Self> {
Self::parse(input, ReflectTraitToImpl::FromReflect)
}
fn parse(input: ParseStream, trait_: ReflectTraitToImpl) -> syn::Result<Self> {
let attrs = input.call(Attribute::parse_outer)?; let attrs = input.call(Attribute::parse_outer)?;
let custom_path = CustomPathDef::parse_parenthesized(input)?; let custom_path = CustomPathDef::parse_parenthesized(input)?;
@ -46,7 +55,7 @@ impl Parse for ReflectValueDef {
if input.peek(Paren) { if input.peek(Paren) {
let content; let content;
parenthesized!(content in input); parenthesized!(content in input);
traits = Some(content.parse::<ReflectTraits>()?); traits = Some(ReflectTraits::parse(&content, trait_)?);
} }
Ok(ReflectValueDef { Ok(ReflectValueDef {
attrs, attrs,

View file

@ -1,9 +1,9 @@
use crate as bevy_reflect; use crate as bevy_reflect;
use crate::prelude::ReflectDefault; use crate::prelude::ReflectDefault;
use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value}; use bevy_reflect_derive::{impl_reflect, impl_reflect_value};
use glam::*; use glam::*;
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct IVec2 { struct IVec2 {
@ -11,7 +11,7 @@ impl_reflect_struct!(
y: i32, y: i32,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct IVec3 { struct IVec3 {
@ -20,7 +20,7 @@ impl_reflect_struct!(
z: i32, z: i32,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct IVec4 { struct IVec4 {
@ -31,7 +31,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct I64Vec2 { struct I64Vec2 {
@ -40,7 +40,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct I64Vec3 { struct I64Vec3 {
@ -50,7 +50,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct I64Vec4 { struct I64Vec4 {
@ -61,7 +61,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct UVec2 { struct UVec2 {
@ -69,7 +69,7 @@ impl_reflect_struct!(
y: u32, y: u32,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct UVec3 { struct UVec3 {
@ -78,7 +78,7 @@ impl_reflect_struct!(
z: u32, z: u32,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct UVec4 { struct UVec4 {
@ -89,7 +89,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct U64Vec2 { struct U64Vec2 {
@ -97,7 +97,7 @@ impl_reflect_struct!(
y: u64, y: u64,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct U64Vec3 { struct U64Vec3 {
@ -106,7 +106,7 @@ impl_reflect_struct!(
z: u64, z: u64,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)] #[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct U64Vec4 { struct U64Vec4 {
@ -117,7 +117,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Vec2 { struct Vec2 {
@ -125,7 +125,7 @@ impl_reflect_struct!(
y: f32, y: f32,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Vec3 { struct Vec3 {
@ -134,7 +134,7 @@ impl_reflect_struct!(
z: f32, z: f32,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Vec3A { struct Vec3A {
@ -143,7 +143,7 @@ impl_reflect_struct!(
z: f32, z: f32,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Vec4 { struct Vec4 {
@ -154,7 +154,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct BVec2 { struct BVec2 {
@ -162,7 +162,7 @@ impl_reflect_struct!(
y: bool, y: bool,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct BVec3 { struct BVec3 {
@ -171,7 +171,7 @@ impl_reflect_struct!(
z: bool, z: bool,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct BVec4 { struct BVec4 {
@ -182,7 +182,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct DVec2 { struct DVec2 {
@ -190,7 +190,7 @@ impl_reflect_struct!(
y: f64, y: f64,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct DVec3 { struct DVec3 {
@ -199,7 +199,7 @@ impl_reflect_struct!(
z: f64, z: f64,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct DVec4 { struct DVec4 {
@ -210,7 +210,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Mat2 { struct Mat2 {
@ -218,7 +218,7 @@ impl_reflect_struct!(
y_axis: Vec2, y_axis: Vec2,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Mat3 { struct Mat3 {
@ -227,7 +227,7 @@ impl_reflect_struct!(
z_axis: Vec3, z_axis: Vec3,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Mat3A { struct Mat3A {
@ -236,7 +236,7 @@ impl_reflect_struct!(
z_axis: Vec3A, z_axis: Vec3A,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Mat4 { struct Mat4 {
@ -247,7 +247,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct DMat2 { struct DMat2 {
@ -255,7 +255,7 @@ impl_reflect_struct!(
y_axis: DVec2, y_axis: DVec2,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct DMat3 { struct DMat3 {
@ -264,7 +264,7 @@ impl_reflect_struct!(
z_axis: DVec3, z_axis: DVec3,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct DMat4 { struct DMat4 {
@ -275,7 +275,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Affine2 { struct Affine2 {
@ -283,7 +283,7 @@ impl_reflect_struct!(
translation: Vec2, translation: Vec2,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Affine3A { struct Affine3A {
@ -292,7 +292,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct DAffine2 { struct DAffine2 {
@ -300,7 +300,7 @@ impl_reflect_struct!(
translation: DVec2, translation: DVec2,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct DAffine3 { struct DAffine3 {
@ -309,7 +309,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct Quat { struct Quat {
@ -319,7 +319,7 @@ impl_reflect_struct!(
w: f32, w: f32,
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Default)] #[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"] #[type_path = "glam"]
struct DQuat { struct DQuat {

View file

@ -1,7 +1,7 @@
use crate as bevy_reflect; use crate as bevy_reflect;
use crate::{ReflectDeserialize, ReflectSerialize}; use crate::{ReflectDeserialize, ReflectSerialize};
use bevy_math::{primitives::*, Vec2}; use bevy_math::{primitives::*, Vec2};
use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value}; use bevy_reflect_derive::{impl_reflect, impl_reflect_value};
impl_reflect_value!(::bevy_math::primitives::Direction2d( impl_reflect_value!(::bevy_math::primitives::Direction2d(
Debug, Debug,
@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction2d(
Deserialize Deserialize
)); ));
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Circle { struct Circle {
@ -18,7 +18,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Ellipse { struct Ellipse {
@ -26,7 +26,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Plane2d { struct Plane2d {
@ -34,7 +34,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Line2d { struct Line2d {
@ -42,7 +42,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Segment2d { struct Segment2d {
@ -51,7 +51,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq)] #[reflect(Debug, PartialEq)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Polyline2d<const N: usize> { struct Polyline2d<const N: usize> {
@ -59,7 +59,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Triangle2d { struct Triangle2d {
@ -67,7 +67,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Rectangle { struct Rectangle {
@ -75,7 +75,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq)] #[reflect(Debug, PartialEq)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Polygon<const N: usize> { struct Polygon<const N: usize> {
@ -83,7 +83,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct RegularPolygon { struct RegularPolygon {
@ -92,7 +92,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Capsule2d { struct Capsule2d {

View file

@ -1,7 +1,7 @@
use crate as bevy_reflect; use crate as bevy_reflect;
use crate::{ReflectDeserialize, ReflectSerialize}; use crate::{ReflectDeserialize, ReflectSerialize};
use bevy_math::{primitives::*, Vec3}; use bevy_math::{primitives::*, Vec3};
use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value}; use bevy_reflect_derive::{impl_reflect, impl_reflect_value};
impl_reflect_value!(::bevy_math::primitives::Direction3d( impl_reflect_value!(::bevy_math::primitives::Direction3d(
Debug, Debug,
@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction3d(
Deserialize Deserialize
)); ));
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Sphere { struct Sphere {
@ -18,7 +18,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Plane3d { struct Plane3d {
@ -26,7 +26,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Line3d { struct Line3d {
@ -34,7 +34,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Segment3d { struct Segment3d {
@ -43,7 +43,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq)] #[reflect(Debug, PartialEq)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Polyline3d<const N: usize> { struct Polyline3d<const N: usize> {
@ -51,7 +51,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Cuboid { struct Cuboid {
@ -59,7 +59,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Cylinder { struct Cylinder {
@ -68,7 +68,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Capsule3d { struct Capsule3d {
@ -77,7 +77,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Cone { struct Cone {
@ -86,7 +86,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct ConicalFrustum { struct ConicalFrustum {
@ -96,7 +96,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)] #[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"] #[type_path = "bevy_math::primitives"]
struct Torus { struct Torus {

View file

@ -2,9 +2,9 @@ use crate as bevy_reflect;
use crate::prelude::ReflectDefault; use crate::prelude::ReflectDefault;
use crate::{ReflectDeserialize, ReflectSerialize}; use crate::{ReflectDeserialize, ReflectSerialize};
use bevy_math::{IRect, IVec2, Rect, URect, UVec2, Vec2}; use bevy_math::{IRect, IVec2, Rect, URect, UVec2, Vec2};
use bevy_reflect_derive::impl_reflect_struct; use bevy_reflect_derive::impl_reflect;
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)] #[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)]
#[type_path = "bevy_math"] #[type_path = "bevy_math"]
struct IRect { struct IRect {
@ -13,7 +13,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)]
#[type_path = "bevy_math"] #[type_path = "bevy_math"]
struct Rect { struct Rect {
@ -22,7 +22,7 @@ impl_reflect_struct!(
} }
); );
impl_reflect_struct!( impl_reflect!(
#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)] #[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)]
#[type_path = "bevy_math"] #[type_path = "bevy_math"]
struct URect { struct URect {

View file

@ -1565,7 +1565,7 @@ mod tests {
let info = <SomeStruct as Typed>::type_info(); let info = <SomeStruct as Typed>::type_info();
assert_eq!( assert_eq!(
Some(" Some struct.\n\n # Example\n\n ```ignore\n let some_struct = SomeStruct;\n ```"), Some(" Some struct.\n\n # Example\n\n ```ignore (This is only used for a unit test, no need to doc test)\n let some_struct = SomeStruct;\n ```"),
info.docs() info.docs()
); );
@ -2095,6 +2095,42 @@ bevy_reflect::tests::Test {
); );
} }
#[test]
fn assert_impl_reflect_macro_on_all() {
struct Struct {
foo: (),
}
struct TupleStruct(());
enum Enum {
Foo { foo: () },
Bar(()),
}
impl_reflect!(
#[type_path = "my_crate::foo"]
struct Struct {
foo: (),
}
);
impl_reflect!(
#[type_path = "my_crate::foo"]
struct TupleStruct(());
);
impl_reflect!(
#[type_path = "my_crate::foo"]
enum Enum {
Foo { foo: () },
Bar(()),
}
);
assert_impl_all!(Struct: Reflect);
assert_impl_all!(TupleStruct: Reflect);
assert_impl_all!(Enum: Reflect);
}
#[cfg(feature = "glam")] #[cfg(feature = "glam")]
mod glam { mod glam {
use super::*; use super::*;