1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, DeriveInput, Type, Ident};
4
5#[proc_macro_derive(Class)]
6pub fn derive_class(input: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(input as DeriveInput);
8 let name = &input.ident;
9
10 let expanded = quote! {
11 impl crate::traits::Class for #name {
12 fn class_info() -> &'static crate::registry::ClassInfo {
13 static INFO: once_cell::sync::Lazy<crate::registry::ClassInfo> =
14 once_cell::sync::Lazy::new(|| {
15 crate::registry::ClassInfo {
16 id: uuid::Uuid::new_v4(),
17 name: stringify!(#name),
18 parent: None,
19 type_id: std::any::TypeId::of::<#name>(),
20 #[cfg(feature = "reflection")]
21 reflection_data: crate::reflection::ReflectionData::new::<#name>(),
22 }
23 });
24 &INFO
25 }
26
27 fn as_any(&self) -> &dyn std::any::Any {
28 self
29 }
30
31 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
32 self
33 }
34 }
35 };
36
37 TokenStream::from(expanded)
38}
39
40#[proc_macro_attribute]
41pub fn inherit(args: TokenStream, input: TokenStream) -> TokenStream {
42 let parent_type = parse_macro_input!(args as Type);
43 let input = parse_macro_input!(input as DeriveInput);
44 let name = &input.ident;
45
46 let expanded = quote! {
47 #input
48
49 impl crate::traits::Class for #name {
50 fn class_info() -> &'static crate::registry::ClassInfo {
51 static INFO: once_cell::sync::Lazy<crate::registry::ClassInfo> =
52 once_cell::sync::Lazy::new(|| {
53 crate::registry::ClassInfo {
54 id: uuid::Uuid::new_v4(),
55 name: stringify!(#name),
56 parent: Some(std::any::TypeId::of::<#parent_type>()),
57 type_id: std::any::TypeId::of::<#name>(),
58 #[cfg(feature = "reflection")]
59 reflection_data: crate::reflection::ReflectionData::new::<#name>(),
60 }
61 });
62 &INFO
63 }
64
65 fn as_any(&self) -> &dyn std::any::Any {
66 self
67 }
68
69 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
70 self
71 }
72 }
73
74 impl crate::traits::Inherits<#parent_type> for #name {
75 fn as_parent(&self) -> &#parent_type {
76 &self.base
77 }
78
79 fn as_parent_mut(&mut self) -> &mut #parent_type {
80 &mut self.base
81 }
82 }
83 };
84
85 TokenStream::from(expanded)
86}