Remove TypeUuid (#11497)

# Objective
TypeUuid is deprecated, remove it.

## Migration Guide
Convert any uses of `#[derive(TypeUuid)]` with `#[derive(TypePath]` for
more complex uses see the relevant
[documentation](https://docs.rs/bevy/latest/bevy/prelude/trait.TypePath.html)
for more information.

---------

Co-authored-by: ebola <dev@axiomatic>
This commit is contained in:
AxiomaticSemantics 2024-01-25 11:16:58 -05:00 committed by GitHub
parent d974b8210e
commit 2ebf5a303e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 17 additions and 436 deletions

View File

@ -6,8 +6,8 @@ use bevy_ecs::{
prelude::EventWriter,
system::{Res, ResMut, Resource},
};
use bevy_reflect::{Reflect, TypePath, Uuid};
use bevy_utils::HashMap;
use bevy_reflect::{Reflect, TypePath};
use bevy_utils::{HashMap, Uuid};
use crossbeam_channel::{Receiver, Sender};
use serde::{Deserialize, Serialize};
use std::{

View File

@ -3,8 +3,8 @@ use crate::{
UntypedAssetId,
};
use bevy_ecs::prelude::*;
use bevy_reflect::{Reflect, TypePath, Uuid};
use bevy_utils::get_short_name;
use bevy_reflect::{Reflect, TypePath};
use bevy_utils::{get_short_name, Uuid};
use crossbeam_channel::{Receiver, Sender};
use std::{
any::TypeId,

View File

@ -1,5 +1,7 @@
use crate::{Asset, AssetIndex};
use bevy_reflect::{Reflect, Uuid};
use bevy_reflect::Reflect;
use bevy_utils::Uuid;
use std::{
any::TypeId,
fmt::{Debug, Display},

View File

@ -48,7 +48,7 @@ use std::marker::PhantomData;
/// ```
/// # use bevy_pbr::{Material, MaterialMeshBundle};
/// # use bevy_ecs::prelude::*;
/// # use bevy_reflect::{TypeUuid, TypePath};
/// # use bevy_reflect::TypePath;
/// # use bevy_render::{render_resource::{AsBindGroup, ShaderRef}, texture::Image, color::Color};
/// # use bevy_asset::{Handle, AssetServer, Assets, Asset};
///

View File

@ -2,7 +2,7 @@ use crate::{Material, MaterialPipeline, MaterialPipelineKey, MaterialPlugin};
use bevy_app::{Plugin, Startup, Update};
use bevy_asset::{load_internal_asset, Asset, Assets, Handle};
use bevy_ecs::prelude::*;
use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath, TypeUuid};
use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath};
use bevy_render::{
color::Color,
extract_resource::ExtractResource,
@ -194,8 +194,7 @@ fn apply_global_wireframe_material(
}
}
#[derive(Default, AsBindGroup, TypeUuid, TypePath, Debug, Clone, Asset)]
#[uuid = "9e694f70-9963-4418-8bc1-3474c66b13b8"]
#[derive(Default, AsBindGroup, TypePath, Debug, Clone, Asset)]
pub struct WireframeMaterial {
#[uniform(0)]
pub color: Color,

View File

@ -36,6 +36,7 @@ glam = { version = "0.25", features = ["serde"], optional = true }
smol_str = { version = "0.2.0", optional = true }
[dev-dependencies]
glam = { version = "0.25", features = ["serde"] }
ron = "0.8.0"
rmp-serde = "1.1"
bincode = "1.3"

View File

@ -5,11 +5,11 @@
//! such as `Struct`, `GetTypeRegistration`, and more— all with a single derive!
//!
//! Some other noteworthy exports include the derive macros for [`FromReflect`] and
//! [`TypeUuid`], as well as the [`reflect_trait`] attribute macro.
//! [`TypePath`], as well as the [`reflect_trait`] attribute macro.
//!
//! [`Reflect`]: crate::derive_reflect
//! [`FromReflect`]: crate::derive_from_reflect
//! [`TypeUuid`]: crate::derive_type_uuid
//! [`TypePath`]: crate::derive_type_path
//! [`reflect_trait`]: macro@reflect_trait
extern crate proc_macro;
@ -27,7 +27,6 @@ mod registration;
mod serialization;
mod trait_reflection;
mod type_path;
mod type_uuid;
mod utility;
use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};
@ -291,20 +290,6 @@ pub fn derive_type_path(input: TokenStream) -> TokenStream {
})
}
// From https://github.com/randomPoison/type-uuid
#[proc_macro_derive(TypeUuid, attributes(uuid))]
pub fn derive_type_uuid(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let uuid_impl =
type_uuid::type_uuid_derive(input).unwrap_or_else(syn::Error::into_compile_error);
TokenStream::from(quote! {
const _: () = {
#uuid_impl
};
})
}
/// A macro that automatically generates type data for traits, which their implementors can then register.
///
/// The output of this macro is a struct that takes reflected instances of the implementor's type
@ -616,16 +601,3 @@ pub fn impl_type_path(input: TokenStream) -> TokenStream {
};
})
}
/// Derives `TypeUuid` for the given type. This is used internally to implement `TypeUuid` on foreign types, such as those in the std. This macro should be used in the format of `<[Generic Params]> [Type (Path)], [Uuid (String Literal)]`.
#[proc_macro]
pub fn impl_type_uuid(input: TokenStream) -> TokenStream {
let def = parse_macro_input!(input as type_uuid::TypeUuidDef);
let uuid_impl = type_uuid::gen_impl_type_uuid(def);
TokenStream::from(quote! {
const _: () = {
#uuid_impl
};
})
}

View File

@ -1,108 +0,0 @@
use bevy_macro_utils::BevyManifest;
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::token::Comma;
use syn::{DeriveInput, Expr, ExprLit, Generics, Ident, Lit, LitInt, LitStr, Meta};
use uuid::Uuid;
pub(crate) fn type_uuid_derive(input: DeriveInput) -> syn::Result<TokenStream> {
let mut uuid = None;
#[allow(clippy::manual_let_else)]
for attribute in input
.attrs
.iter()
.filter(|attr| attr.path().is_ident("uuid"))
{
let Meta::NameValue(ref name_value) = attribute.meta else {
continue;
};
let uuid_str = match &name_value.value {
Expr::Lit(ExprLit{lit: Lit::Str(lit_str), ..}) => lit_str,
_ => return Err(syn::Error::new_spanned(attribute, "`uuid` attribute must take the form `#[uuid = \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"]`.")),
};
uuid =
Some(Uuid::parse_str(&uuid_str.value()).map_err(|err| {
syn::Error::new_spanned(uuid_str, format!("Invalid UUID: {err}"))
})?);
}
let uuid = uuid.ok_or_else(|| {
syn::Error::new(
Span::call_site(),
"No `#[uuid = \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"]` attribute found.",
)
})?;
Ok(gen_impl_type_uuid(TypeUuidDef {
type_ident: input.ident,
generics: input.generics,
uuid,
}))
}
/// Generates an implementation of `TypeUuid`. If there any generics, the `TYPE_UUID` will be a composite of the generic types' `TYPE_UUID`.
pub(crate) fn gen_impl_type_uuid(def: TypeUuidDef) -> TokenStream {
let uuid = def.uuid;
let mut generics = def.generics;
let ty = def.type_ident;
let bevy_reflect_path = BevyManifest::default().get_path("bevy_reflect");
generics.type_params_mut().for_each(|param| {
param
.bounds
.push(syn::parse_quote!(#bevy_reflect_path::TypeUuid));
});
let bytes = uuid
.as_bytes()
.iter()
.map(|byte| format!("{byte:#X}"))
.map(|byte_str| syn::parse_str::<LitInt>(&byte_str).unwrap());
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
let base = quote! { #bevy_reflect_path::Uuid::from_bytes([#( #bytes ),*]) };
let type_uuid = generics.type_params().enumerate().fold(base, |acc, (index, param)| {
let ident = &param.ident;
let param_uuid = quote!(
#bevy_reflect_path::Uuid::from_u128(<#ident as #bevy_reflect_path::TypeUuid>::TYPE_UUID.as_u128().wrapping_add(#index as u128))
);
quote! {
#bevy_reflect_path::__macro_exports::generate_composite_uuid(#acc, #param_uuid)
}
});
quote! {
impl #impl_generics #bevy_reflect_path::TypeUuid for #ty #type_generics #where_clause {
const TYPE_UUID: #bevy_reflect_path::Uuid = #type_uuid;
}
}
}
/// A struct containing the data required to generate an implementation of `TypeUuid`. This can be generated by either [`impl_type_uuid!`][crate::impl_type_uuid!] or [`type_uuid_derive`].
pub(crate) struct TypeUuidDef {
pub type_ident: Ident,
pub generics: Generics,
pub uuid: Uuid,
}
impl Parse for TypeUuidDef {
fn parse(input: ParseStream) -> syn::Result<Self> {
let type_ident = input.parse::<Ident>()?;
let generics = input.parse::<Generics>()?;
input.parse::<Comma>()?;
let uuid = input.parse::<LitStr>()?.value();
let uuid = Uuid::parse_str(&uuid).map_err(|err| input.error(format!("{err}")))?;
Ok(Self {
type_ident,
generics,
uuid,
})
}
}

View File

@ -478,8 +478,6 @@ mod tuple_struct;
mod type_info;
mod type_path;
mod type_registry;
mod type_uuid;
mod type_uuid_impl;
mod impls {
#[cfg(feature = "glam")]
mod glam;
@ -523,7 +521,6 @@ pub use tuple_struct::*;
pub use type_info::*;
pub use type_path::*;
pub use type_registry::*;
pub use type_uuid::*;
pub use bevy_reflect_derive::*;
pub use erased_serde;
@ -538,14 +535,15 @@ pub mod __macro_exports {
#[cfg(test)]
#[allow(clippy::disallowed_types, clippy::approx_constant)]
mod tests {
#[cfg(feature = "glam")]
use ::glam::{quat, vec3, Quat, Vec3};
use ::serde::{de::DeserializeSeed, Deserialize, Serialize};
use bevy_utils::HashMap;
#[rustfmt::skip] // This is used to avoid import conflicts with `super`
use ::glam::{quat, vec3, Quat, Vec3};
use ron::{
ser::{to_string_pretty, PrettyConfig},
Deserializer,
};
#[rustfmt::skip] // This is used to avoid import conflicts with `super::`
use ::serde::{de::DeserializeSeed, Deserialize, Serialize};
use std::{
any::TypeId,
borrow::Cow,

View File

@ -1,157 +0,0 @@
pub use bevy_reflect_derive::TypeUuid;
pub use bevy_utils::uuid::Uuid;
/// A trait for types with a statically associated UUID.
pub trait TypeUuid {
const TYPE_UUID: Uuid;
}
/// A trait for types with an associated UUID.
pub trait TypeUuidDynamic {
fn type_uuid(&self) -> Uuid;
fn type_name(&self) -> &'static str;
}
impl<T> TypeUuidDynamic for T
where
T: TypeUuid,
{
/// Returns the UUID associated with this value's type.
fn type_uuid(&self) -> Uuid {
Self::TYPE_UUID
}
/// Returns the [type name] of this value's type.
///
/// [type name]: std::any::type_name
fn type_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
}
#[cfg(test)]
mod test {
use super::*;
use crate as bevy_reflect;
use bevy_reflect_derive::TypeUuid;
use std::marker::PhantomData;
#[derive(TypeUuid)]
#[uuid = "af6466c2-a9f4-11eb-bcbc-0242ac130002"]
struct TestDeriveStruct<T>
where
T: Clone,
{
_value: T,
}
fn test_impl_type_uuid(_: &impl TypeUuid) {}
#[test]
fn test_generic_type_uuid_derive() {
#[derive(TypeUuid, Clone)]
#[uuid = "ebb16cc9-4d5a-453c-aa8c-c72bd8ec83a2"]
struct T;
let test_struct = TestDeriveStruct { _value: T };
test_impl_type_uuid(&test_struct);
}
#[test]
fn test_generic_type_unique_uuid() {
#[derive(TypeUuid, Clone)]
#[uuid = "49951b1c-4811-45e7-acc6-3119249fbd8f"]
struct A;
#[derive(TypeUuid, Clone)]
#[uuid = "4882b8f5-5556-4cee-bea6-a2e5991997b7"]
struct B;
let uuid_a = TestDeriveStruct::<A>::TYPE_UUID;
let uuid_b = TestDeriveStruct::<B>::TYPE_UUID;
assert_ne!(uuid_a, uuid_b);
assert_ne!(uuid_a, A::TYPE_UUID);
assert_ne!(uuid_b, B::TYPE_UUID);
}
#[test]
fn test_inverted_generic_type_unique_uuid() {
#[derive(TypeUuid, Clone)]
#[uuid = "49951b1c-4811-45e7-acc6-3119249fbd8f"]
struct Inner;
#[derive(TypeUuid, Clone)]
#[uuid = "23ebc0c3-ef69-4ea0-8c2a-dca1b4e27c0d"]
struct TestDeriveStructA<T>
where
T: Clone,
{
_phantom: PhantomData<T>,
}
#[derive(TypeUuid, Clone)]
#[uuid = "a82f9936-70cb-482a-bd3d-cb99d87de55f"]
struct TestDeriveStructB<T>
where
T: Clone,
{
_phantom: PhantomData<T>,
}
let uuid_ab = TestDeriveStructA::<TestDeriveStructB<Inner>>::TYPE_UUID;
let uuid_ba = TestDeriveStructB::<TestDeriveStructA<Inner>>::TYPE_UUID;
assert_ne!(uuid_ab, uuid_ba);
assert_ne!(uuid_ab, TestDeriveStructA::<Inner>::TYPE_UUID);
assert_ne!(uuid_ba, TestDeriveStructB::<Inner>::TYPE_UUID);
}
#[test]
fn test_generic_type_uuid_same_for_eq_param() {
#[derive(TypeUuid, Clone)]
#[uuid = "49951b1c-4811-45e7-acc6-3119249fbd8f"]
struct A;
#[derive(TypeUuid, Clone)]
#[uuid = "49951b1c-4811-45e7-acc6-3119249fbd8f"]
struct BButSameAsA;
let uuid_a = TestDeriveStruct::<A>::TYPE_UUID;
let uuid_b = TestDeriveStruct::<BButSameAsA>::TYPE_UUID;
assert_eq!(uuid_a, uuid_b);
}
#[test]
fn test_multiple_generic_uuid() {
#[derive(TypeUuid)]
#[uuid = "35c8a7d3-d4b3-4bd7-b847-1118dc78092f"]
struct TestGeneric<A, B> {
_value_a: A,
_value_b: B,
}
assert_ne!(
TestGeneric::<f32, bool>::TYPE_UUID,
TestGeneric::<bool, f32>::TYPE_UUID
);
}
#[test]
fn test_primitive_generic_uuid() {
test_impl_type_uuid(&true);
test_impl_type_uuid(&Some(true));
test_impl_type_uuid(&TestDeriveStruct::<bool> { _value: true });
assert_ne!(Option::<bool>::TYPE_UUID, Option::<f32>::TYPE_UUID);
assert_ne!(<[bool; 0]>::TYPE_UUID, <[bool; 1]>::TYPE_UUID);
assert_ne!(<[bool; 0]>::TYPE_UUID, <[f32; 0]>::TYPE_UUID);
assert_ne!(
<(bool, bool)>::TYPE_UUID,
<(bool, bool, bool, bool)>::TYPE_UUID
);
assert_ne!(<(bool, f32)>::TYPE_UUID, <(f32, bool)>::TYPE_UUID);
}
}

View File

@ -1,84 +0,0 @@
use crate::TypeUuid;
use crate::{self as bevy_reflect, __macro_exports::generate_composite_uuid};
use bevy_reflect_derive::impl_type_uuid;
use bevy_utils::{all_tuples, Duration, HashMap, HashSet, Instant, Uuid};
#[cfg(feature = "smallvec")]
use bevy_utils::{smallvec, smallvec::SmallVec};
#[cfg(any(unix, windows))]
use std::ffi::OsString;
use std::{
num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Saturating, Wrapping,
},
ops::{RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
path::PathBuf,
};
impl<T: TypeUuid, const N: usize> TypeUuid for [T; N] {
const TYPE_UUID: Uuid = generate_composite_uuid(
Uuid::from_u128(0x18d33c78e63c47b9bbf8f095008ab693),
generate_composite_uuid(Uuid::from_u128(N as u128), T::TYPE_UUID),
);
}
impl_type_uuid!(bool, "eb1ad0ee2dff473285bc54ebbdef682c");
impl_type_uuid!(char, "45a4710278ba48f8b31f0d72ff7f9d46");
impl_type_uuid!(u8, "fdf1a88a3e0543ca9f51ad5978ca519f");
impl_type_uuid!(u16, "ddeb93f791074860aaac1540de254edc");
impl_type_uuid!(u32, "fc565ea2367f405591e1c55f91cb60bd");
impl_type_uuid!(u64, "6c74b6a983eb44b096a9169baa6af0a1");
impl_type_uuid!(u128, "f837371a4f534b7381ed776d5056d0c1");
impl_type_uuid!(usize, "0129e1d8cff041f9b23aa99c6e1006b8");
impl_type_uuid!(i8, "af7a5411661e43b0b1631ea43a825fd2");
impl_type_uuid!(i16, "68592d5de5be4a608603c6988edfdf9c");
impl_type_uuid!(i32, "439ff07f96c94aa5a86352ded71e4730");
impl_type_uuid!(i64, "7f9534793ad24ab2b9f05d8254f4204a");
impl_type_uuid!(i128, "6e5009be5845460daf814e052cc9fcf0");
impl_type_uuid!(isize, "d3d52630da45497faf86859051c79e7d");
impl_type_uuid!(f32, "006607124a8148e1910c86f0c18c9015");
impl_type_uuid!(f64, "a5bc32f5632b478c92a0939b821fff80");
impl_type_uuid!(Result<T, E>, "d5960af2e8a743dfb7427dd59b70df95");
impl_type_uuid!(String, "c9f90d31b52d4bcd8b5c1d8b6fc1bcba");
impl_type_uuid!(PathBuf, "aa79933abd1743698583a3acad3b8989");
impl_type_uuid!(Vec<T>, "ab98f5408b974475b643662247fb3886");
impl_type_uuid!(HashMap<K, V>,"f37bfad9ca8c4f6ea7448f1c39e05f98");
impl_type_uuid!(Option<T>, "8d5ba9a9031347078955fba01ff439f0");
#[cfg(feature = "smallvec")]
impl_type_uuid!(
SmallVec<T: smallvec::Array>,
"26fd5c1bed7144fbb8d1546c02ba255a"
);
impl_type_uuid!(HashSet<K>, "5ebd2379ece44ef2b1478262962617a3");
impl_type_uuid!(RangeInclusive<T>, "79613b729ca9490881c7f47b24b22b60");
impl_type_uuid!(RangeFrom<T>, "1bd8c975f122486c9ed443e277964642");
impl_type_uuid!(RangeTo<T>, "7d938903749a4d198f496cb354929b9b");
impl_type_uuid!(RangeToInclusive<T>, "2fec56936206462fa5f35c99a62c5ed1");
impl_type_uuid!(RangeFull, "227af17f65db448782a2f6980ceae25d");
impl_type_uuid!(Duration, "cee5978c60f74a53b6848cb9c46a6e1c");
impl_type_uuid!(Instant, "9b0194a1d31c44c1afd2f6fd80ab8dfb");
impl_type_uuid!(NonZeroI128, "915a1e7fcaeb433982cebf58c2ac20e7");
impl_type_uuid!(NonZeroU128, "286de521146042cda31dfbef8f3f6cdc");
impl_type_uuid!(NonZeroIsize, "9318740a9fd14603b709b8fbc6fd2812");
impl_type_uuid!(NonZeroUsize, "a26533ed16324189878263d5e7a294ce");
impl_type_uuid!(NonZeroI64, "1aa38623127a42419cca4992e6fc3152");
impl_type_uuid!(NonZeroU64, "46be65e669a2477d942e2ec39d0d2af7");
impl_type_uuid!(NonZeroU32, "cf53a46d9efe4022967160cb61762c91");
impl_type_uuid!(NonZeroI32, "a69fbd659bef4322b88b15ff3263f530");
impl_type_uuid!(NonZeroI16, "8744c2ec8a10491fae40f8bafa58b30d");
impl_type_uuid!(NonZeroU16, "c7b8b60780a6495bab4fda2bdfedabcc");
impl_type_uuid!(NonZeroU8, "635ee104ef7947fb9d7f79dad47255a3");
impl_type_uuid!(NonZeroI8, "2d3f1570b7f64779826d44da5c7ba069");
impl_type_uuid!(Saturating<T>, "e9d7c5d5b9e94c9c9c8c8c0f5f3c5c5f");
impl_type_uuid!(Wrapping<T>, "d5b9e94c9c9c8c8c0f5f3c5c5fe9d7c5");
#[cfg(any(unix, windows))]
impl_type_uuid!(OsString, "809e7b3c1ea240979ecd832f91eb842a");
macro_rules! impl_tuple {
( $($name: ident),* ) => {
const _: () = {
type Tuple< $($name),* > = ( $($name,)* );
impl_type_uuid!(Tuple< $($name),* > , "35c8a7d3d4b34bd7b8471118dc78092f");
};
};
}
all_tuples!(impl_tuple, 0, 12, A);

View File

@ -1,5 +0,0 @@
#[test]
fn test() {
let t = trybuild::TestCases::new();
t.compile_fail("tests/type_uuid_derive/*.rs");
}

View File

@ -1,17 +0,0 @@
use bevy_reflect::TypeUuid;
fn main() {}
// Missing #[uuid] attribute
#[derive(TypeUuid)]
struct A;
// Malformed attribute
#[derive(TypeUuid)]
#[uuid = 42]
struct B;
// UUID parse fail
#[derive(TypeUuid)]
#[uuid = "000"]
struct C;

View File

@ -1,19 +0,0 @@
error: No `#[uuid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]` attribute found.
--> tests/type_uuid_derive/derive_type_uuid.rs:6:10
|
6 | #[derive(TypeUuid)]
| ^^^^^^^^
|
= note: this error originates in the derive macro `TypeUuid` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `uuid` attribute must take the form `#[uuid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]`.
--> tests/type_uuid_derive/derive_type_uuid.rs:11:1
|
11 | #[uuid = 42]
| ^^^^^^^^^^^^
error: Invalid UUID: invalid length: expected length 32 for simple format, found 3
--> tests/type_uuid_derive/derive_type_uuid.rs:16:10
|
16 | #[uuid = "000"]
| ^^^^^

View File

@ -8,7 +8,6 @@ use bevy::utils::Duration;
// This struct usually contains the data for the audio being played.
// This is where data read from an audio file would be stored, for example.
// Implementing `TypeUuid` will automatically implement `Asset`.
// This allows the type to be registered as an asset.
#[derive(Asset, TypePath)]
struct SineAudio {