From b0ed3e29d46efe785682d327c21e7002154530d1 Mon Sep 17 00:00:00 2001 From: Serhii Potapov Date: Sat, 1 Jun 2024 16:07:12 +0200 Subject: [PATCH] Make it possible to derive TryFrom for an inner type with generics --- examples/any_generics/src/main.rs | 2 +- nutype_macros/src/any/gen/traits/mod.rs | 2 +- nutype_macros/src/common/gen/traits.rs | 9 +++++---- nutype_macros/src/float/gen/traits/mod.rs | 2 +- nutype_macros/src/integer/gen/traits/mod.rs | 2 +- nutype_macros/src/string/gen/traits/mod.rs | 6 ++++-- test_suite/tests/any.rs | 3 +-- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/examples/any_generics/src/main.rs b/examples/any_generics/src/main.rs index bed214a..fbd979b 100644 --- a/examples/any_generics/src/main.rs +++ b/examples/any_generics/src/main.rs @@ -20,12 +20,12 @@ struct NotEmpty(Vec); // TODO // AsRef, + // FromStr, Into, From, Deref, Borrow, - // FromStr, // TryFrom, // Default, diff --git a/nutype_macros/src/any/gen/traits/mod.rs b/nutype_macros/src/any/gen/traits/mod.rs index f7133b6..0c80950 100644 --- a/nutype_macros/src/any/gen/traits/mod.rs +++ b/nutype_macros/src/any/gen/traits/mod.rs @@ -163,7 +163,7 @@ fn gen_implemented_traits( gen_impl_trait_from_str(type_name, inner_type, maybe_error_type_name.as_ref()) ), AnyIrregularTrait::TryFrom => Ok( - gen_impl_trait_try_from(type_name, inner_type, maybe_error_type_name.as_ref()) + gen_impl_trait_try_from(type_name, generics, inner_type, maybe_error_type_name.as_ref()) ), AnyIrregularTrait::Default => match maybe_default_value { Some(ref default_value) => { diff --git a/nutype_macros/src/common/gen/traits.rs b/nutype_macros/src/common/gen/traits.rs index 5c912e3..2ece351 100644 --- a/nutype_macros/src/common/gen/traits.rs +++ b/nutype_macros/src/common/gen/traits.rs @@ -152,6 +152,7 @@ pub fn gen_impl_trait_from( pub fn gen_impl_trait_try_from( type_name: &TypeName, + generics: &Generics, inner_type: impl ToTokens, maybe_error_type_name: Option<&ErrorTypeName>, ) -> TokenStream { @@ -160,11 +161,11 @@ pub fn gen_impl_trait_try_from( // The case when there are validation // quote! { - impl ::core::convert::TryFrom<#inner_type> for #type_name { + impl #generics ::core::convert::TryFrom<#inner_type> for #type_name #generics { type Error = #error_type_name; #[inline] - fn try_from(raw_value: #inner_type) -> Result<#type_name, Self::Error> { + fn try_from(raw_value: #inner_type) -> Result<#type_name #generics, Self::Error> { Self::new(raw_value) } } @@ -174,11 +175,11 @@ pub fn gen_impl_trait_try_from( // The case when there are no validation // quote! { - impl ::core::convert::TryFrom<#inner_type> for #type_name { + impl #generics ::core::convert::TryFrom<#inner_type> for #type_name #generics { type Error = ::core::convert::Infallible; #[inline] - fn try_from(raw_value: #inner_type) -> Result<#type_name, Self::Error> { + fn try_from(raw_value: #inner_type) -> Result<#type_name #generics, Self::Error> { Ok(Self::new(raw_value)) } } diff --git a/nutype_macros/src/float/gen/traits/mod.rs b/nutype_macros/src/float/gen/traits/mod.rs index 9ef402f..20bca68 100644 --- a/nutype_macros/src/float/gen/traits/mod.rs +++ b/nutype_macros/src/float/gen/traits/mod.rs @@ -177,7 +177,7 @@ fn gen_implemented_traits( FloatIrregularTrait::From => Ok(gen_impl_trait_from(type_name, generics, inner_type)), FloatIrregularTrait::Into => Ok(gen_impl_trait_into(type_name, generics, inner_type)), FloatIrregularTrait::TryFrom => { - Ok(gen_impl_trait_try_from(type_name, inner_type, maybe_error_type_name.as_ref())) + Ok(gen_impl_trait_try_from(type_name, generics, inner_type, maybe_error_type_name.as_ref())) } FloatIrregularTrait::Borrow => Ok(gen_impl_trait_borrow(type_name, generics, inner_type)), FloatIrregularTrait::Display => Ok(gen_impl_trait_display(type_name, generics)), diff --git a/nutype_macros/src/integer/gen/traits/mod.rs b/nutype_macros/src/integer/gen/traits/mod.rs index 3bb25b8..c7fe088 100644 --- a/nutype_macros/src/integer/gen/traits/mod.rs +++ b/nutype_macros/src/integer/gen/traits/mod.rs @@ -197,7 +197,7 @@ fn gen_implemented_traits( IntegerIrregularTrait::From => Ok(gen_impl_trait_from(type_name, generics, inner_type)), IntegerIrregularTrait::Into => Ok(gen_impl_trait_into(type_name, generics, inner_type)), IntegerIrregularTrait::TryFrom => { - Ok(gen_impl_trait_try_from(type_name, inner_type, maybe_error_type_name.as_ref())) + Ok(gen_impl_trait_try_from(type_name, generics, inner_type, maybe_error_type_name.as_ref())) } IntegerIrregularTrait::Borrow => Ok(gen_impl_trait_borrow(type_name, generics, inner_type)), IntegerIrregularTrait::Display => Ok(gen_impl_trait_display(type_name, generics)), diff --git a/nutype_macros/src/string/gen/traits/mod.rs b/nutype_macros/src/string/gen/traits/mod.rs index a1e3741..4896945 100644 --- a/nutype_macros/src/string/gen/traits/mod.rs +++ b/nutype_macros/src/string/gen/traits/mod.rs @@ -267,9 +267,11 @@ fn gen_impl_try_from( type_name: &TypeName, maybe_error_type_name: Option<&ErrorTypeName>, ) -> TokenStream { + let generics = Generics::default(); let impl_try_from_string = - gen_impl_trait_try_from(type_name, quote!(String), maybe_error_type_name); - let impl_try_from_str = gen_impl_trait_try_from(type_name, quote!(&str), maybe_error_type_name); + gen_impl_trait_try_from(type_name, &generics, quote!(String), maybe_error_type_name); + let impl_try_from_str = + gen_impl_trait_try_from(type_name, &generics, quote!(&str), maybe_error_type_name); quote! { #impl_try_from_string diff --git a/test_suite/tests/any.rs b/test_suite/tests/any.rs index e8b67ac..a30555d 100644 --- a/test_suite/tests/any.rs +++ b/test_suite/tests/any.rs @@ -488,8 +488,7 @@ mod with_generics { fn test_generic_with_lifetime_cow() { #[nutype( validate(predicate = |s| s.len() >= 3), - // TODO: derive TryFrom - derive(Debug, Display, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Into, Deref) + derive(Debug, Display, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Into, Deref, Borrow, TryFrom) )] struct Clarabelle<'a>(Cow<'a, str>);