Skip to content

Commit

Permalink
feat: add auto_state macro for state management
Browse files Browse the repository at this point in the history
  • Loading branch information
viniciusborgeis committed Aug 12, 2024
1 parent e27af6d commit 709c10f
Showing 1 changed file with 49 additions and 24 deletions.
73 changes: 49 additions & 24 deletions rustato-proc-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,58 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemStruct, LitStr};
use quote::{format_ident, quote};
use syn::{parse_macro_input, Field, FieldsNamed, ItemStruct};

#[proc_macro]
pub fn create_state(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as ItemStruct);
let struct_name = &input.ident;
let struct_def = &input;
#[proc_macro_attribute]
pub fn auto_state(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as ItemStruct);
let name = &input.ident;

// Extrair os campos da estrutura
let fields = match &input.fields {
syn::Fields::Named(FieldsNamed { named, .. }) => named,
_ => panic!("AutoState only supports structs with named fields"),
};

// Gerar a implementação de Fields
let field_impls = fields.iter().map(|f: &Field| {
let field_name = &f.ident;
quote! {
fields.push(&mut self.#field_name as &mut dyn ::std::any::Any);
}
});

let expanded = quote! {
#[derive(Clone, Default)]
#struct_def
#input

impl #name {
fn new() -> Self {
Self::default()
}
}

impl Drop for #name {
fn drop(&mut self) {
::rustato::unregister_global_state(stringify!(#name));
}
}

rustato::GLOBAL_STATE_MANAGER.register_state::<#struct_name>(stringify!(#struct_name), #struct_name::default());
impl ::rustato::AutoState for #name {}

impl ::rustato::Fields for #name {
fn fields_mut(&mut self) -> Vec<&mut dyn ::std::any::Any> {
let mut fields = Vec::new();
#(#field_impls)*
fields
}
}

::rustato::paste::paste! {
#[::rustato::ctor::ctor]
fn [<__register_ #name _state>]() {
::rustato::__register_global_state_immediately(stringify!(#name), || ::rustato::GlobalState::new(#name::new()));
}
}
};

TokenStream::from(expanded)
}

struct CreateStateInput {
id: LitStr,
struct_def: ItemStruct,
}

impl syn::parse::Parse for CreateStateInput {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let id = input.parse()?;
input.parse::<syn::Token![,]>()?;
let struct_def = input.parse()?;
Ok(CreateStateInput { id, struct_def })
}
}

0 comments on commit 709c10f

Please sign in to comment.