mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
proc-macro for TypeUuidProvider
- allows to add `#[type_uuid(id = "15a8ecd6-a09f-4c5d-b9f9-b7f0e8a44ac9")]` attribute to types that `#[derive(TypeUuidProvider)]`
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
mod reflect;
|
||||
mod uuid;
|
||||
mod visit;
|
||||
|
||||
use darling::FromDeriveInput;
|
||||
@@ -43,3 +44,12 @@ pub fn impl_reflect(input: TokenStream) -> TokenStream {
|
||||
|
||||
TokenStream::from(reflect_impl)
|
||||
}
|
||||
|
||||
/// Implements `TypeUuidProvider` trait
|
||||
///
|
||||
/// User has to import `TypeUuidProvider` trait to use this macro.
|
||||
#[proc_macro_derive(TypeUuidProvider, attributes(type_uuid))]
|
||||
pub fn type_uuid(input: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(input as DeriveInput);
|
||||
TokenStream::from(uuid::impl_type_uuid_provider(ast))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
use darling::*;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::*;
|
||||
use syn::*;
|
||||
|
||||
#[derive(FromDeriveInput)]
|
||||
#[darling(attributes(type_uuid), supports(struct_any, enum_any))]
|
||||
pub struct TypeArgs {
|
||||
pub ident: Ident,
|
||||
pub generics: Generics,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
pub fn impl_type_uuid_provider(ast: DeriveInput) -> TokenStream2 {
|
||||
let ty_args = TypeArgs::from_derive_input(&ast).unwrap();
|
||||
let ty_ident = &ty_args.ident;
|
||||
let id = &ty_args.id;
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = ty_args.generics.split_for_impl();
|
||||
|
||||
quote! {
|
||||
impl #impl_generics TypeUuidProvider for #ty_ident #ty_generics #where_clause {
|
||||
fn type_uuid() -> Uuid {
|
||||
uuid!(#id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,5 @@
|
||||
// trace_macros!(true);
|
||||
|
||||
pub mod reflect;
|
||||
pub mod uuid;
|
||||
pub mod visit;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
use fyrox_core::type_traits::prelude::*;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(TypeUuidProvider)]
|
||||
#[type_uuid(id = "5fb10a22-4ea9-4a13-a58c-82f2734aefd8")]
|
||||
struct Foo {}
|
||||
|
||||
#[derive(TypeUuidProvider)]
|
||||
#[type_uuid(id = "5fb10a22-4ea9-4a13-a58c-82f2734aefd9")]
|
||||
struct Bar<T> {
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
+3
-63
@@ -45,6 +45,7 @@ pub mod reflect;
|
||||
pub mod sparse;
|
||||
pub mod sstorage;
|
||||
pub mod task;
|
||||
pub mod type_traits;
|
||||
pub mod variable;
|
||||
pub mod visitor;
|
||||
pub mod watcher;
|
||||
@@ -58,7 +59,6 @@ pub use notify;
|
||||
pub use js_sys;
|
||||
use std::iter::FromIterator;
|
||||
use std::marker::PhantomData;
|
||||
use uuid::Uuid;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub use wasm_bindgen;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
@@ -66,6 +66,8 @@ pub use wasm_bindgen_futures;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub use web_sys;
|
||||
|
||||
pub use type_traits::prelude::*;
|
||||
|
||||
/// Defines as_(variant), as_mut_(variant) and is_(variant) methods.
|
||||
#[macro_export]
|
||||
macro_rules! define_is_as {
|
||||
@@ -298,68 +300,6 @@ pub fn make_relative_path<P: AsRef<Path>>(path: P) -> Result<PathBuf, std::io::E
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for an entity that has unique type identifier.
|
||||
pub trait TypeUuidProvider: Sized {
|
||||
/// Return type UUID.
|
||||
fn type_uuid() -> Uuid;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! uuid_provider {
|
||||
($type:ident $(<$($generics:tt),*>)? = $uuid:expr) => {
|
||||
impl$(<$($generics),*>)? $crate::TypeUuidProvider for $type $(<$($generics),*>)? {
|
||||
fn type_uuid() -> $crate::uuid::Uuid {
|
||||
$crate::uuid::uuid!($uuid)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! stub_uuid_provider {
|
||||
($type:ty) => {
|
||||
impl $crate::TypeUuidProvider for $type {
|
||||
fn type_uuid() -> $crate::uuid::Uuid {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
uuid_provider!(u8 = "7a8c337c-0219-466b-92b5-81460fa9c836");
|
||||
uuid_provider!(i8 = "3036f00e-5986-4ac3-8763-19e51d0889d7");
|
||||
uuid_provider!(u16 = "c662169d-cc3b-453c-bdf3-e0104ac3b966");
|
||||
uuid_provider!(i16 = "abce35a9-5e7b-4f7e-a729-2620a9806a6b");
|
||||
uuid_provider!(u32 = "8c4d2541-76a5-4dd8-9eb1-10222d2d6912");
|
||||
uuid_provider!(i32 = "7413ddd4-71ce-484d-a808-4f3479f5712d");
|
||||
uuid_provider!(u64 = "d1a45bd5-5066-4b28-b103-95c59c230e77");
|
||||
uuid_provider!(i64 = "35b89368-805f-486d-b3b1-fd3e86b5d645");
|
||||
uuid_provider!(f32 = "479e29c6-85fd-4bb8-b311-7b98793b8bf6");
|
||||
uuid_provider!(f64 = "dac09d54-d069-47f4-aa0e-aa0057cc2b52");
|
||||
uuid_provider!(usize = "620e24e3-fb51-48c6-a885-91d65135c5c9");
|
||||
uuid_provider!(isize = "0a06591a-1c66-4299-ba6f-2b205b795575");
|
||||
uuid_provider!(bool = "3b104074-9d39-4a2b-b974-da8cc1759fe8");
|
||||
|
||||
impl<T: TypeUuidProvider> TypeUuidProvider for Option<T> {
|
||||
fn type_uuid() -> Uuid {
|
||||
combine_uuids(
|
||||
uuid::uuid!("ffe06d3b-0d07-42cd-886b-5248f6ca7f7d"),
|
||||
T::type_uuid(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn combine_uuids(a: Uuid, b: Uuid) -> Uuid {
|
||||
let mut combined_bytes = a.into_bytes();
|
||||
|
||||
for (src, dest) in b.into_bytes().into_iter().zip(combined_bytes.iter_mut()) {
|
||||
*dest ^= src;
|
||||
}
|
||||
|
||||
Uuid::from_bytes(combined_bytes)
|
||||
}
|
||||
|
||||
/// "Transmutes" array of any sized type to a slice of bytes.
|
||||
pub fn array_as_u8_slice<T: Sized>(v: &[T]) -> &'_ [u8] {
|
||||
// SAFETY: It is safe to reinterpret data to read it.
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
pub use fyrox_core_derive::TypeUuidProvider;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::{combine_uuids, TypeUuidProvider};
|
||||
pub use uuid::{uuid, Uuid};
|
||||
}
|
||||
|
||||
/// A trait for an entity that has unique type identifier.
|
||||
pub trait TypeUuidProvider: Sized {
|
||||
/// Return type UUID.
|
||||
fn type_uuid() -> Uuid;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! uuid_provider {
|
||||
($type:ident $(<$($generics:tt),*>)? = $uuid:expr) => {
|
||||
impl$(<$($generics),*>)? $crate::type_traits::TypeUuidProvider for $type $(<$($generics),*>)? {
|
||||
fn type_uuid() -> $crate::uuid::Uuid {
|
||||
$crate::uuid::uuid!($uuid)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! stub_uuid_provider {
|
||||
($type:ty) => {
|
||||
impl $crate::TypeUuidProvider for $type {
|
||||
fn type_uuid() -> $crate::uuid::Uuid {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
uuid_provider!(u8 = "7a8c337c-0219-466b-92b5-81460fa9c836");
|
||||
uuid_provider!(i8 = "3036f00e-5986-4ac3-8763-19e51d0889d7");
|
||||
uuid_provider!(u16 = "c662169d-cc3b-453c-bdf3-e0104ac3b966");
|
||||
uuid_provider!(i16 = "abce35a9-5e7b-4f7e-a729-2620a9806a6b");
|
||||
uuid_provider!(u32 = "8c4d2541-76a5-4dd8-9eb1-10222d2d6912");
|
||||
uuid_provider!(i32 = "7413ddd4-71ce-484d-a808-4f3479f5712d");
|
||||
uuid_provider!(u64 = "d1a45bd5-5066-4b28-b103-95c59c230e77");
|
||||
uuid_provider!(i64 = "35b89368-805f-486d-b3b1-fd3e86b5d645");
|
||||
uuid_provider!(f32 = "479e29c6-85fd-4bb8-b311-7b98793b8bf6");
|
||||
uuid_provider!(f64 = "dac09d54-d069-47f4-aa0e-aa0057cc2b52");
|
||||
uuid_provider!(usize = "620e24e3-fb51-48c6-a885-91d65135c5c9");
|
||||
uuid_provider!(isize = "0a06591a-1c66-4299-ba6f-2b205b795575");
|
||||
uuid_provider!(bool = "3b104074-9d39-4a2b-b974-da8cc1759fe8");
|
||||
|
||||
impl<T: TypeUuidProvider> TypeUuidProvider for Option<T> {
|
||||
fn type_uuid() -> Uuid {
|
||||
combine_uuids(
|
||||
uuid::uuid!("ffe06d3b-0d07-42cd-886b-5248f6ca7f7d"),
|
||||
T::type_uuid(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn combine_uuids(a: Uuid, b: Uuid) -> Uuid {
|
||||
let mut combined_bytes = a.into_bytes();
|
||||
|
||||
for (src, dest) in b.into_bytes().into_iter().zip(combined_bytes.iter_mut()) {
|
||||
*dest ^= src;
|
||||
}
|
||||
|
||||
Uuid::from_bytes(combined_bytes)
|
||||
}
|
||||
Reference in New Issue
Block a user