Skip to main content

dynasty_macros/
lib.rs

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}