From 1a631d40275d707bee4b2256eb9c67f8a8b0b01e Mon Sep 17 00:00:00 2001 From: AlephCubed Date: Sat, 26 Apr 2025 14:55:26 -0700 Subject: [PATCH] Fixed attributes. --- immediate_stats_macros/src/lib.rs | 45 ++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/immediate_stats_macros/src/lib.rs b/immediate_stats_macros/src/lib.rs index 9362f74..904bf71 100644 --- a/immediate_stats_macros/src/lib.rs +++ b/immediate_stats_macros/src/lib.rs @@ -8,7 +8,7 @@ use proc_macro_error::{ use proc_macro2::{Span, TokenStream}; use quote::{ToTokens, quote}; use syn::spanned::Spanned; -use syn::{Data, DataEnum, DataStruct, DeriveInput, Field, Ident, Index, Type, parse_macro_input}; +use syn::{Data, DataEnum, DataStruct, DeriveInput, Field, Ident, Index, parse_macro_input}; #[proc_macro_derive(StatContainer, attributes(stat, stat_ignore, add_component))] #[proc_macro_error] @@ -48,29 +48,44 @@ pub fn stat_container_derive(item: proc_macro::TokenStream) -> proc_macro::Token method.into() } -#[derive(FromField)] // Todo Implement manually to allow for naked attributes. -#[darling(attributes(stat, stat_ignore))] -struct FieldState { +#[derive(Default)] +struct FieldOptions { ident: Option, - ty: Type, - #[darling(default, rename = "stat")] + stat_type: bool, include: bool, - #[darling(default, rename = "stat")] exclude: bool, } +impl FromField for FieldOptions { + fn from_field(field: &Field) -> darling::Result { + let mut options = FieldOptions { + ident: field.ident.clone(), + ..Self::default() + }; + + options.stat_type = field.ty.to_token_stream().to_string().contains("Stat"); + + for attribute in &field.attrs { + if let Some(ident) = attribute.path().get_ident() { + match ident.to_string().as_str() { + // Todo Warn about double tags. + "stat" => options.include = true, + "stat_ignore" => options.exclude = true, + _ => continue, + } + } + } + + Ok(options) + } +} + fn struct_fields(s: DataStruct) -> darling::Result { let mut tokens = TokenStream::new(); for (index, field) in s.fields.iter().enumerate() { - let field_state = FieldState::from_field(&field)?; - - let is_stat_type = field_state - .ty - .to_token_stream() - .to_string() - .contains("Stat"); + let field_state = FieldOptions::from_field(&field)?; - if (field_state.include || is_stat_type) && !field_state.exclude { + if (field_state.include || field_state.stat_type) && !field_state.exclude { if let Some(ident) = field_state.ident { tokens.extend(quote! { self.#ident.reset_modifiers(); -- 2.51.2