dynasty-macros 0.1.0

Procedural macros for the Dynasty class system
Documentation
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Type, Ident};

#[proc_macro_derive(Class)]
pub fn derive_class(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;

    let expanded = quote! {
        impl crate::traits::Class for #name {
            fn class_info() -> &'static crate::registry::ClassInfo {
                static INFO: once_cell::sync::Lazy<crate::registry::ClassInfo> = 
                    once_cell::sync::Lazy::new(|| {
                        crate::registry::ClassInfo {
                            id: uuid::Uuid::new_v4(),
                            name: stringify!(#name),
                            parent: None,
                            type_id: std::any::TypeId::of::<#name>(),
                            #[cfg(feature = "reflection")]
                            reflection_data: crate::reflection::ReflectionData::new::<#name>(),
                        }
                    });
                &INFO
            }

            fn as_any(&self) -> &dyn std::any::Any {
                self
            }

            fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
                self
            }
        }
    };

    TokenStream::from(expanded)
}

#[proc_macro_attribute]
pub fn inherit(args: TokenStream, input: TokenStream) -> TokenStream {
    let parent_type = parse_macro_input!(args as Type);
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;

    let expanded = quote! {
        #input

        impl crate::traits::Class for #name {
            fn class_info() -> &'static crate::registry::ClassInfo {
                static INFO: once_cell::sync::Lazy<crate::registry::ClassInfo> = 
                    once_cell::sync::Lazy::new(|| {
                        crate::registry::ClassInfo {
                            id: uuid::Uuid::new_v4(),
                            name: stringify!(#name),
                            parent: Some(std::any::TypeId::of::<#parent_type>()),
                            type_id: std::any::TypeId::of::<#name>(),
                            #[cfg(feature = "reflection")]
                            reflection_data: crate::reflection::ReflectionData::new::<#name>(),
                        }
                    });
                &INFO
            }

            fn as_any(&self) -> &dyn std::any::Any {
                self
            }

            fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
                self
            }
        }

        impl crate::traits::Inherits<#parent_type> for #name {
            fn as_parent(&self) -> &#parent_type {
                &self.base
            }

            fn as_parent_mut(&mut self) -> &mut #parent_type {
                &mut self.base
            }
        }
    };

    TokenStream::from(expanded)
}