From c40fcf9c482733775d718849cde51763e4529ed2 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Mon, 30 Oct 2023 05:33:36 +0100 Subject: [PATCH 1/3] Allow implicitly cloning arguments instead of referencing --- src/lib.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e404229..7755b14 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,19 +86,22 @@ pub fn autoprops_component( let mut fields = Vec::new(); let mut arg_types = Vec::new(); + let mut clones = Vec::new(); for input in function.sig.inputs.iter() { if let FnArg::Typed(PatType { pat, ty, attrs, .. }) = input { - let Type::Reference(ty) = ty.as_ref() else { - panic!( - "Invalid argument: {} (must be a reference)", - input.to_token_stream() - ); - }; + let mut end_ty = ty; + + if let Type::Reference(ty_ref) = ty.as_ref() { + end_ty = &ty_ref.elem; + } else { + clones.push(quote! { + let #pat = #pat.clone(); + }); + } - let ty = &ty.elem; fields.push(quote! { #(#attrs)* - pub #pat: #ty + pub #pat: #end_ty }); arg_types.push(ty.clone()); } else { @@ -137,6 +140,7 @@ pub fn autoprops_component( #[::yew::function_component(#component_name)] #[allow(non_snake_case)] #visibility fn #fn_name #impl_generics (#destructure: &#struct_name #ty_generics) -> ::yew::Html #where_clause { + #(#clones)* #function_block } }; From 3a5f022aea929781df4e079434159c9d755805d9 Mon Sep 17 00:00:00 2001 From: Valentin Golev Date: Mon, 30 Oct 2023 12:44:48 +0100 Subject: [PATCH 2/3] refs are now allowed --- tests/cases/{require-refs-fail.rs => allow-refs-pass.rs} | 1 + tests/cases/require-refs-fail.stderr | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) rename tests/cases/{require-refs-fail.rs => allow-refs-pass.rs} (91%) delete mode 100644 tests/cases/require-refs-fail.stderr diff --git a/tests/cases/require-refs-fail.rs b/tests/cases/allow-refs-pass.rs similarity index 91% rename from tests/cases/require-refs-fail.rs rename to tests/cases/allow-refs-pass.rs index fead603..6de445c 100644 --- a/tests/cases/require-refs-fail.rs +++ b/tests/cases/allow-refs-pass.rs @@ -1,3 +1,4 @@ +use yew::prelude::*; use yew_autoprops::autoprops_component; #[autoprops_component] diff --git a/tests/cases/require-refs-fail.stderr b/tests/cases/require-refs-fail.stderr deleted file mode 100644 index fb6369d..0000000 --- a/tests/cases/require-refs-fail.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: custom attribute panicked - --> tests/cases/require-refs-fail.rs:3:1 - | -3 | #[autoprops_component] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = help: message: Invalid argument: test : i8 (must be a reference) From cfec07fd97c48ae5576bd2b1ab33e07ab3eeaa31 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Mon, 30 Oct 2023 13:26:25 +0100 Subject: [PATCH 3/3] fix issue with generics --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7755b14..1c48569 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,6 +87,7 @@ pub fn autoprops_component( let mut fields = Vec::new(); let mut arg_types = Vec::new(); let mut clones = Vec::new(); + let mut partial_eq_constraints = Vec::new(); for input in function.sig.inputs.iter() { if let FnArg::Typed(PatType { pat, ty, attrs, .. }) = input { let mut end_ty = ty; @@ -104,13 +105,12 @@ pub fn autoprops_component( pub #pat: #end_ty }); arg_types.push(ty.clone()); + partial_eq_constraints.push(quote! { #end_ty: PartialEq, }); } else { panic!("Invalid argument"); } } - let partial_eq_constraints = arg_types.iter().map(|ty| quote! { #ty: PartialEq }); - let struct_name = syn::Ident::new(&format!("{}Props", fn_name), Span::call_site().into()); let (impl_generics, ty_generics, _) = generics.split_for_impl(); let bounds = generics.where_clause.clone(); @@ -120,8 +120,8 @@ pub fn autoprops_component( } else { quote! { where - #(#partial_eq_constraints),* - #bounds, + #(#partial_eq_constraints)* + #bounds } };