From 37406d2ff628a17ba8fd2b7b4d09db2b4f23bcd4 Mon Sep 17 00:00:00 2001 From: Rex Magana Date: Sat, 23 Dec 2023 17:41:55 -0800 Subject: [PATCH] support generic actions --- derive/src/action.rs | 13 +++++++++---- tests/derive_action.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/derive/src/action.rs b/derive/src/action.rs index 4ebff9a..be7b020 100644 --- a/derive/src/action.rs +++ b/derive/src/action.rs @@ -10,14 +10,17 @@ pub fn action_builder_impl(input: proc_macro::TokenStream) -> proc_macro::TokenS let label = get_label(&input); let component_name = input.ident; + let generics = input.generics; + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let component_string = component_name.to_string(); - let build_method = build_method(&component_name); + let build_method = build_method(&component_name, &ty_generics); let label_method = label_method( label.unwrap_or_else(|| LitStr::new(&component_string, component_name.span())), ); let gen = quote! { - impl ::big_brain::actions::ActionBuilder for #component_name { + impl #impl_generics ::big_brain::actions::ActionBuilder for #component_name #ty_generics #where_clause { #build_method #label_method } @@ -48,10 +51,12 @@ fn get_label(input: &DeriveInput) -> Option { label } -fn build_method(component_name: &Ident) -> TokenStream { +fn build_method(component_name: &Ident, ty_generics: &syn::TypeGenerics) -> TokenStream { + let turbofish = ty_generics.as_turbofish(); + quote! { fn build(&self, cmd: &mut ::bevy::ecs::system::Commands, action: ::bevy::ecs::entity::Entity, _actor: ::bevy::ecs::entity::Entity) { - cmd.entity(action).insert(#component_name::clone(self)); + cmd.entity(action).insert(#component_name #turbofish::clone(self)); } } } diff --git a/tests/derive_action.rs b/tests/derive_action.rs index 585e79d..808cd50 100644 --- a/tests/derive_action.rs +++ b/tests/derive_action.rs @@ -10,3 +10,30 @@ fn check_macro() { let action = MyAction; assert_eq!(action.label(), Some("MyLabel")) } + +#[derive(Debug, Clone, Component, ActionBuilder)] +#[action_label = "MyGenericLabel"] +pub struct MyGenericAction { + pub value: T, +} + +#[test] +fn check_generic_macro() { + let action = MyGenericAction { value: 0 }; + assert_eq!(action.label(), Some("MyGenericLabel")) +} + +#[derive(Debug, Clone, Component, ActionBuilder)] +#[action_label = "MyGenericWhereLabel"] +pub struct MyGenericWhereAction +where + T: Clone + Send + Sync + std::fmt::Debug + 'static, +{ + pub value: T, +} + +#[test] +fn check_generic_where_macro() { + let action = MyGenericWhereAction { value: 0 }; + assert_eq!(action.label(), Some("MyGenericWhereLabel")) +}