mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
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:
parent
4b7ef44bb4
commit
df761af49b
9 changed files with 258 additions and 188 deletions
|
@ -5,11 +5,12 @@
|
|||
//! the derive helper attribute for `Reflect`, which looks like:
|
||||
//! `#[reflect(PartialEq, Default, ...)]` and `#[reflect_value(PartialEq, Default, ...)]`.
|
||||
|
||||
use crate::derive_data::ReflectTraitToImpl;
|
||||
use crate::utility;
|
||||
use bevy_macro_utils::fq_std::{FQAny, FQOption};
|
||||
use proc_macro2::{Ident, Span, TokenTree};
|
||||
use quote::quote_spanned;
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::parse::ParseStream;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::token::Comma;
|
||||
|
@ -220,10 +221,7 @@ pub(crate) struct ReflectTraits {
|
|||
}
|
||||
|
||||
impl ReflectTraits {
|
||||
pub fn from_meta_list(
|
||||
meta: &MetaList,
|
||||
is_from_reflect_derive: bool,
|
||||
) -> Result<Self, syn::Error> {
|
||||
pub fn from_meta_list(meta: &MetaList, trait_: ReflectTraitToImpl) -> Result<Self, syn::Error> {
|
||||
match meta.tokens.clone().into_iter().next() {
|
||||
// Handles `#[reflect(where T: Trait, U::Assoc: Trait)]`
|
||||
Some(TokenTree::Ident(ident)) if ident == "where" => Ok(Self {
|
||||
|
@ -232,14 +230,14 @@ impl ReflectTraits {
|
|||
}),
|
||||
_ => Self::from_metas(
|
||||
meta.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)?,
|
||||
is_from_reflect_derive,
|
||||
trait_,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_metas(
|
||||
metas: Punctuated<Meta, Comma>,
|
||||
is_from_reflect_derive: bool,
|
||||
trait_: ReflectTraitToImpl,
|
||||
) -> Result<Self, syn::Error> {
|
||||
let mut traits = ReflectTraits::default();
|
||||
for meta in &metas {
|
||||
|
@ -317,7 +315,7 @@ impl ReflectTraits {
|
|||
// Override `lit` if this is a `FromReflect` derive.
|
||||
// This typically means a user is opting out of the default implementation
|
||||
// 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()))
|
||||
.unwrap_or_else(|| lit.clone())
|
||||
})?);
|
||||
|
@ -334,6 +332,10 @@ impl ReflectTraits {
|
|||
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`)
|
||||
/// is registered for this type.
|
||||
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.
|
||||
///
|
||||
/// Returns an error if the identifier already exists in the list.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use core::fmt;
|
||||
|
||||
use crate::container_attributes::{FromReflectAttrs, ReflectTraits, TypePathAttrs};
|
||||
use crate::field_attributes::{parse_field_attrs, ReflectFieldAttr};
|
||||
use crate::type_path::parse_path_no_leading_colon;
|
||||
|
@ -140,10 +142,46 @@ enum ReflectMode {
|
|||
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> {
|
||||
pub fn from_input(
|
||||
input: &'a DeriveInput,
|
||||
is_from_reflect_derive: bool,
|
||||
provenance: ReflectProvenance,
|
||||
) -> Result<Self, syn::Error> {
|
||||
let mut traits = ReflectTraits::default();
|
||||
// Should indicate whether `#[reflect_value]` was used.
|
||||
|
@ -167,8 +205,7 @@ impl<'a> ReflectDerive<'a> {
|
|||
}
|
||||
|
||||
reflect_mode = Some(ReflectMode::Normal);
|
||||
let new_traits =
|
||||
ReflectTraits::from_meta_list(meta_list, is_from_reflect_derive)?;
|
||||
let new_traits = ReflectTraits::from_meta_list(meta_list, provenance.trait_)?;
|
||||
traits.merge(new_traits)?;
|
||||
}
|
||||
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);
|
||||
let new_traits =
|
||||
ReflectTraits::from_meta_list(meta_list, is_from_reflect_derive)?;
|
||||
let new_traits = ReflectTraits::from_meta_list(meta_list, provenance.trait_)?;
|
||||
traits.merge(new_traits)?;
|
||||
}
|
||||
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);
|
||||
|
||||
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")]
|
||||
let meta = meta.with_docs(doc);
|
||||
|
||||
|
|
|
@ -31,11 +31,10 @@ mod utility;
|
|||
|
||||
use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};
|
||||
use container_attributes::ReflectTraits;
|
||||
use derive_data::ReflectTypePath;
|
||||
use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use reflect_value::ReflectValueDef;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{parse_macro_input, DeriveInput};
|
||||
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_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.
|
||||
///
|
||||
/// 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))]
|
||||
pub fn derive_reflect(input: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(input as DeriveInput);
|
||||
|
||||
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
|
||||
};
|
||||
})
|
||||
match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)
|
||||
}
|
||||
|
||||
/// Derives the `FromReflect` trait.
|
||||
|
@ -319,7 +331,13 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream {
|
|||
pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
|
||||
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,
|
||||
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))]
|
||||
pub fn derive_type_path(input: TokenStream) -> TokenStream {
|
||||
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,
|
||||
Err(err) => return err.into_compile_error().into(),
|
||||
};
|
||||
|
@ -459,7 +483,7 @@ pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||
/// [deriving `Reflect`]: Reflect
|
||||
#[proc_macro]
|
||||
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 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.
|
||||
///
|
||||
/// 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`,
|
||||
/// as this macro will do the job of both. This macro implements them as `Struct` types,
|
||||
/// 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 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
|
||||
/// 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)
|
||||
/// use bevy::prelude::Vec3;
|
||||
///
|
||||
/// impl_reflect_struct!(
|
||||
/// impl_reflect!(
|
||||
/// #[reflect(PartialEq, Serialize, Deserialize, Default)]
|
||||
/// #[type_path = "bevy::prelude"]
|
||||
/// struct Vec3 {
|
||||
|
@ -521,51 +546,9 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
|
|||
/// );
|
||||
/// ```
|
||||
#[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 derive_data = match ReflectDerive::from_input(&ast, false) {
|
||||
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
|
||||
};
|
||||
})
|
||||
match_reflect_impls(ast, ReflectImplSource::ImplRemoteType)
|
||||
}
|
||||
|
||||
/// 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
|
||||
#[proc_macro]
|
||||
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 type_path = if def.type_path.leading_colon.is_none()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::container_attributes::ReflectTraits;
|
||||
use crate::derive_data::ReflectTraitToImpl;
|
||||
use crate::type_path::CustomPathDef;
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::parse::ParseStream;
|
||||
use syn::token::Paren;
|
||||
use syn::{parenthesized, Attribute, Generics, Path};
|
||||
|
||||
|
@ -32,8 +33,16 @@ pub(crate) struct ReflectValueDef {
|
|||
pub custom_path: Option<CustomPathDef>,
|
||||
}
|
||||
|
||||
impl Parse for ReflectValueDef {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
impl ReflectValueDef {
|
||||
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 custom_path = CustomPathDef::parse_parenthesized(input)?;
|
||||
|
@ -46,7 +55,7 @@ impl Parse for ReflectValueDef {
|
|||
if input.peek(Paren) {
|
||||
let content;
|
||||
parenthesized!(content in input);
|
||||
traits = Some(content.parse::<ReflectTraits>()?);
|
||||
traits = Some(ReflectTraits::parse(&content, trait_)?);
|
||||
}
|
||||
Ok(ReflectValueDef {
|
||||
attrs,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate as bevy_reflect;
|
||||
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::*;
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct IVec2 {
|
||||
|
@ -11,7 +11,7 @@ impl_reflect_struct!(
|
|||
y: i32,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct IVec3 {
|
||||
|
@ -20,7 +20,7 @@ impl_reflect_struct!(
|
|||
z: i32,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct IVec4 {
|
||||
|
@ -31,7 +31,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct I64Vec2 {
|
||||
|
@ -40,7 +40,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct I64Vec3 {
|
||||
|
@ -50,7 +50,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct I64Vec4 {
|
||||
|
@ -61,7 +61,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct UVec2 {
|
||||
|
@ -69,7 +69,7 @@ impl_reflect_struct!(
|
|||
y: u32,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct UVec3 {
|
||||
|
@ -78,7 +78,7 @@ impl_reflect_struct!(
|
|||
z: u32,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct UVec4 {
|
||||
|
@ -89,7 +89,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct U64Vec2 {
|
||||
|
@ -97,7 +97,7 @@ impl_reflect_struct!(
|
|||
y: u64,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct U64Vec3 {
|
||||
|
@ -106,7 +106,7 @@ impl_reflect_struct!(
|
|||
z: u64,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct U64Vec4 {
|
||||
|
@ -117,7 +117,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Vec2 {
|
||||
|
@ -125,7 +125,7 @@ impl_reflect_struct!(
|
|||
y: f32,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Vec3 {
|
||||
|
@ -134,7 +134,7 @@ impl_reflect_struct!(
|
|||
z: f32,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Vec3A {
|
||||
|
@ -143,7 +143,7 @@ impl_reflect_struct!(
|
|||
z: f32,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Vec4 {
|
||||
|
@ -154,7 +154,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct BVec2 {
|
||||
|
@ -162,7 +162,7 @@ impl_reflect_struct!(
|
|||
y: bool,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct BVec3 {
|
||||
|
@ -171,7 +171,7 @@ impl_reflect_struct!(
|
|||
z: bool,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct BVec4 {
|
||||
|
@ -182,7 +182,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct DVec2 {
|
||||
|
@ -190,7 +190,7 @@ impl_reflect_struct!(
|
|||
y: f64,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct DVec3 {
|
||||
|
@ -199,7 +199,7 @@ impl_reflect_struct!(
|
|||
z: f64,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct DVec4 {
|
||||
|
@ -210,7 +210,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Mat2 {
|
||||
|
@ -218,7 +218,7 @@ impl_reflect_struct!(
|
|||
y_axis: Vec2,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Mat3 {
|
||||
|
@ -227,7 +227,7 @@ impl_reflect_struct!(
|
|||
z_axis: Vec3,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Mat3A {
|
||||
|
@ -236,7 +236,7 @@ impl_reflect_struct!(
|
|||
z_axis: Vec3A,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Mat4 {
|
||||
|
@ -247,7 +247,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct DMat2 {
|
||||
|
@ -255,7 +255,7 @@ impl_reflect_struct!(
|
|||
y_axis: DVec2,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct DMat3 {
|
||||
|
@ -264,7 +264,7 @@ impl_reflect_struct!(
|
|||
z_axis: DVec3,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct DMat4 {
|
||||
|
@ -275,7 +275,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Affine2 {
|
||||
|
@ -283,7 +283,7 @@ impl_reflect_struct!(
|
|||
translation: Vec2,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Affine3A {
|
||||
|
@ -292,7 +292,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct DAffine2 {
|
||||
|
@ -300,7 +300,7 @@ impl_reflect_struct!(
|
|||
translation: DVec2,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct DAffine3 {
|
||||
|
@ -309,7 +309,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct Quat {
|
||||
|
@ -319,7 +319,7 @@ impl_reflect_struct!(
|
|||
w: f32,
|
||||
}
|
||||
);
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
#[type_path = "glam"]
|
||||
struct DQuat {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate as bevy_reflect;
|
||||
use crate::{ReflectDeserialize, ReflectSerialize};
|
||||
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(
|
||||
Debug,
|
||||
|
@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction2d(
|
|||
Deserialize
|
||||
));
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Circle {
|
||||
|
@ -18,7 +18,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Ellipse {
|
||||
|
@ -26,7 +26,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Plane2d {
|
||||
|
@ -34,7 +34,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Line2d {
|
||||
|
@ -42,7 +42,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Segment2d {
|
||||
|
@ -51,7 +51,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Polyline2d<const N: usize> {
|
||||
|
@ -59,7 +59,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Triangle2d {
|
||||
|
@ -67,7 +67,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Rectangle {
|
||||
|
@ -75,7 +75,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Polygon<const N: usize> {
|
||||
|
@ -83,7 +83,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct RegularPolygon {
|
||||
|
@ -92,7 +92,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Capsule2d {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate as bevy_reflect;
|
||||
use crate::{ReflectDeserialize, ReflectSerialize};
|
||||
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(
|
||||
Debug,
|
||||
|
@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction3d(
|
|||
Deserialize
|
||||
));
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Sphere {
|
||||
|
@ -18,7 +18,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Plane3d {
|
||||
|
@ -26,7 +26,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Line3d {
|
||||
|
@ -34,7 +34,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Segment3d {
|
||||
|
@ -43,7 +43,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Polyline3d<const N: usize> {
|
||||
|
@ -51,7 +51,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Cuboid {
|
||||
|
@ -59,7 +59,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Cylinder {
|
||||
|
@ -68,7 +68,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Capsule3d {
|
||||
|
@ -77,7 +77,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Cone {
|
||||
|
@ -86,7 +86,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct ConicalFrustum {
|
||||
|
@ -96,7 +96,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[type_path = "bevy_math::primitives"]
|
||||
struct Torus {
|
||||
|
|
|
@ -2,9 +2,9 @@ use crate as bevy_reflect;
|
|||
use crate::prelude::ReflectDefault;
|
||||
use crate::{ReflectDeserialize, ReflectSerialize};
|
||||
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)]
|
||||
#[type_path = "bevy_math"]
|
||||
struct IRect {
|
||||
|
@ -13,7 +13,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Serialize, Deserialize, Default)]
|
||||
#[type_path = "bevy_math"]
|
||||
struct Rect {
|
||||
|
@ -22,7 +22,7 @@ impl_reflect_struct!(
|
|||
}
|
||||
);
|
||||
|
||||
impl_reflect_struct!(
|
||||
impl_reflect!(
|
||||
#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)]
|
||||
#[type_path = "bevy_math"]
|
||||
struct URect {
|
||||
|
|
|
@ -1565,7 +1565,7 @@ mod tests {
|
|||
|
||||
let info = <SomeStruct as Typed>::type_info();
|
||||
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()
|
||||
);
|
||||
|
||||
|
@ -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")]
|
||||
mod glam {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in a new issue