From b159478ece8ac002d11497d795766ab847e07cbb Mon Sep 17 00:00:00 2001 From: Matt Hunzinger Date: Tue, 3 Dec 2024 15:08:44 -0500 Subject: [PATCH] feat!: add `#[actuate(path = "..")]` attribute to Data macro and use fully-qualified path to Actuate by default --- macros/src/lib.rs | 24 +++++++++++++++++++----- src/compose/catch.rs | 1 + src/compose/memo.rs | 1 + src/compose/mod.rs | 1 + src/composer.rs | 7 +++++++ src/ecs.rs | 1 + src/lib.rs | 2 +- 7 files changed, 31 insertions(+), 6 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 171b094..f91a207 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -2,16 +2,30 @@ use proc_macro::TokenStream; use quote::{format_ident, quote, ToTokens}; use syn::{ parse_macro_input, parse_quote, punctuated::Punctuated, token::Comma, Data, DeriveInput, - GenericParam, ItemTrait, TypeParamBound, + GenericParam, ItemTrait, MetaNameValue, TypeParamBound, }; -#[proc_macro_derive(Data)] +#[proc_macro_derive(Data, attributes(actuate))] pub fn derive_data(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let ident = &input.ident; let generics = &input.generics; + let mut cell = None; + if let Some(attr) = input + .attrs + .iter() + .find(|attr| attr.path().is_ident("actuate")) + { + let args: MetaNameValue = attr.parse_args().unwrap(); + if args.path.get_ident().unwrap().to_string() == "path" { + let value = args.value.to_token_stream().to_string(); + cell = Some(format_ident!("{}", &value[1..value.len() - 1])); + } + } + let actuate = cell.unwrap_or(format_ident!("actuate")); + let generic_params: Punctuated<_, Comma> = generics .params .iter() @@ -21,7 +35,7 @@ pub fn derive_data(input: TokenStream) -> TokenStream { let ident = &type_param.ident; let mut bounds = type_param.bounds.clone(); - bounds.push(parse_quote!(Data)); + bounds.push(parse_quote!(#actuate::data::Data)); quote! { #ident: #bounds @@ -61,7 +75,7 @@ pub fn derive_data(input: TokenStream) -> TokenStream { #( #checks )* #[doc(hidden)] - unsafe impl <#generic_params> Data for #ident <#generic_ty_params> {} + unsafe impl <#generic_params> #actuate::data::Data for #ident <#generic_ty_params> {} }; gen.into() } @@ -95,7 +109,7 @@ pub fn data(_attrs: TokenStream, input: TokenStream) -> TokenStream { quote! { #item - unsafe impl Data for Box {} + unsafe impl actuate::data::Data for Box {} } .into() } diff --git a/src/compose/catch.rs b/src/compose/catch.rs index 3e5823c..08de002 100644 --- a/src/compose/catch.rs +++ b/src/compose/catch.rs @@ -20,6 +20,7 @@ pub fn catch<'a, C: Compose>( /// /// See [`catch`] for more. #[derive(Data)] +#[actuate(path = "crate")] pub struct Catch<'a, C> { content: C, f: Box) + 'a>, diff --git a/src/compose/memo.rs b/src/compose/memo.rs index ad9eb6b..ab4abb4 100644 --- a/src/compose/memo.rs +++ b/src/compose/memo.rs @@ -22,6 +22,7 @@ where /// /// See [`memo`] for more. #[derive(Data)] +#[actuate(path = "crate")] #[must_use = "Composables do nothing unless composed or returned from other composables."] pub struct Memo { dependency: T, diff --git a/src/compose/mod.rs b/src/compose/mod.rs index ba6ce2d..06fab11 100644 --- a/src/compose/mod.rs +++ b/src/compose/mod.rs @@ -102,6 +102,7 @@ impl Compose for Option { /// /// This can be handled by a parent composable with [`Catch`]. #[derive(Data)] +#[actuate(path = "crate")] pub struct Error { make_error: Box Box>, } diff --git a/src/composer.rs b/src/composer.rs index 02a747e..feceab9 100644 --- a/src/composer.rs +++ b/src/composer.rs @@ -209,6 +209,7 @@ mod tests { }; #[derive(Data)] + #[actuate(path = "crate")] struct Counter { x: Rc>, } @@ -222,6 +223,7 @@ mod tests { } #[derive(Data)] + #[actuate(path = "crate")] struct NonUpdateCounter { x: Rc>, } @@ -235,6 +237,7 @@ mod tests { #[test] fn it_composes() { #[derive(Data)] + #[actuate(path = "crate")] struct Wrap { x: Rc>, } @@ -260,6 +263,7 @@ mod tests { #[test] fn it_skips_recomposes() { #[derive(Data)] + #[actuate(path = "crate")] struct Wrap { x: Rc>, } @@ -285,6 +289,7 @@ mod tests { #[test] fn it_composes_any_compose() { #[derive(Data)] + #[actuate(path = "crate")] struct Wrap { x: Rc>, } @@ -310,6 +315,7 @@ mod tests { #[test] fn it_memoizes_composables() { #[derive(Data)] + #[actuate(path = "crate")] struct B { x: Rc>, } @@ -321,6 +327,7 @@ mod tests { } #[derive(Data)] + #[actuate(path = "crate")] struct A { x: Rc>, } diff --git a/src/ecs.rs b/src/ecs.rs index e369c42..3db5e59 100644 --- a/src/ecs.rs +++ b/src/ecs.rs @@ -161,6 +161,7 @@ where } #[derive(Data)] +#[actuate(path = "crate")] struct CompositionContent { content: C, target: Entity, diff --git a/src/lib.rs b/src/lib.rs index 00798be..b5927db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -137,7 +137,7 @@ use std::collections::HashMap; /// Prelude of commonly used items. pub mod prelude { pub use crate::{ - compose::{self, catch, memo, Compose, DynCompose, Error, Memo,dyn_compose}, + compose::{self, catch, dyn_compose, memo, Compose, DynCompose, Error, Memo}, data::{data, Data, DataField, FieldWrap, FnField, StaticField}, use_callback, use_context, use_drop, use_local_task, use_memo, use_mut, use_provider, use_ref, Cow, Map, RefMap, Scope, ScopeState, Signal, SignalMut,