Skip to content

Commit

Permalink
Merge pull request #143 from greyblake/generics-derive-as-ref
Browse files Browse the repository at this point in the history
Derive AsRef on newtypes with generics
  • Loading branch information
greyblake authored Jun 2, 2024
2 parents 0f79e72 + 5dd4efd commit 67ecaa5
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 8 deletions.
2 changes: 1 addition & 1 deletion examples/any_generics/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ struct NotEmpty<T>(Vec<T>);
From,
Deref,
Borrow,
AsRef,
// TODO
// AsRef,
// FromStr,
// TryFrom,
// Default,
Expand Down
2 changes: 1 addition & 1 deletion nutype_macros/src/any/gen/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ fn gen_implemented_traits(
impl_traits
.iter()
.map(|t| match t {
AnyIrregularTrait::AsRef => Ok(gen_impl_trait_as_ref(type_name, inner_type)),
AnyIrregularTrait::AsRef => Ok(gen_impl_trait_as_ref(type_name, generics, inner_type)),
AnyIrregularTrait::From => Ok(gen_impl_trait_from(type_name, generics, inner_type)),
AnyIrregularTrait::Into => Ok(gen_impl_trait_into(type_name, generics, inner_type.clone())),
AnyIrregularTrait::Display => Ok(gen_impl_trait_display(type_name, generics)),
Expand Down
8 changes: 6 additions & 2 deletions nutype_macros/src/common/gen/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,13 @@ pub fn gen_impl_trait_into(
}
}

pub fn gen_impl_trait_as_ref(type_name: &TypeName, inner_type: impl ToTokens) -> TokenStream {
pub fn gen_impl_trait_as_ref(
type_name: &TypeName,
generics: &Generics,
inner_type: impl ToTokens,
) -> TokenStream {
quote! {
impl ::core::convert::AsRef<#inner_type> for #type_name {
impl #generics ::core::convert::AsRef<#inner_type> for #type_name #generics {
#[inline]
fn as_ref(&self) -> &#inner_type {
&self.0
Expand Down
2 changes: 1 addition & 1 deletion nutype_macros/src/float/gen/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ fn gen_implemented_traits<T: ToTokens>(
impl_traits
.iter()
.map(|t| match t {
FloatIrregularTrait::AsRef => Ok(gen_impl_trait_as_ref(type_name, inner_type)),
FloatIrregularTrait::AsRef => Ok(gen_impl_trait_as_ref(type_name, generics, inner_type)),
FloatIrregularTrait::Deref => Ok(gen_impl_trait_deref(type_name, generics, inner_type)),
FloatIrregularTrait::FromStr => {
Ok(gen_impl_trait_from_str(type_name, inner_type, maybe_error_type_name.as_ref()))
Expand Down
2 changes: 1 addition & 1 deletion nutype_macros/src/integer/gen/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ fn gen_implemented_traits<T: ToTokens>(
impl_traits
.iter()
.map(|t| match t {
IntegerIrregularTrait::AsRef => Ok(gen_impl_trait_as_ref(type_name, inner_type)),
IntegerIrregularTrait::AsRef => Ok(gen_impl_trait_as_ref(type_name, generics, inner_type)),
IntegerIrregularTrait::Deref => Ok(gen_impl_trait_deref(type_name, generics, inner_type)),
IntegerIrregularTrait::FromStr => {
Ok(gen_impl_trait_from_str(type_name, inner_type, maybe_error_type_name.as_ref()))
Expand Down
2 changes: 1 addition & 1 deletion nutype_macros/src/string/gen/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ fn gen_implemented_traits(
impl_traits
.iter()
.map(|t| match t {
StringIrregularTrait::AsRef => Ok(gen_impl_trait_as_ref(type_name, quote!(str))),
StringIrregularTrait::AsRef => Ok(gen_impl_trait_as_ref(type_name, generics, quote!(str))),
StringIrregularTrait::Deref => Ok(gen_impl_trait_deref(type_name, generics, quote!(String))),
StringIrregularTrait::FromStr => {
Ok(gen_impl_from_str(type_name, maybe_error_type_name.as_ref()))
Expand Down
30 changes: 29 additions & 1 deletion test_suite/tests/any.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use nutype::nutype;
use std::borrow::Cow;
use std::collections::HashMap;
use test_suite::test_helpers::traits::*;

// Inner custom type, which is unknown to nutype
Expand Down Expand Up @@ -488,7 +489,7 @@ mod with_generics {
fn test_generic_with_lifetime_cow() {
#[nutype(
validate(predicate = |s| s.len() >= 3),
derive(Debug, Display, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Into, Deref, Borrow, TryFrom)
derive(Debug, Display, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Into, Deref, Borrow, TryFrom, AsRef)
)]
struct Clarabelle<'a>(Cow<'a, str>);

Expand All @@ -500,4 +501,31 @@ mod with_generics {
assert_eq!(muu.to_string(), "Muu");
}
}

#[test]
fn test_derive_as_ref_with_generic() {
#[nutype(derive(AsRef))]
struct SquareMap<K, V>(HashMap<K, V>);

let mut inner_map = HashMap::new();
inner_map.insert(4, 16);
inner_map.insert(5, 25);
let squares = SquareMap::new(inner_map.clone());
assert_eq!(squares.as_ref(), &inner_map);
}

#[test]
fn test_derive_as_ref_with_generic_and_validation() {
#[nutype(
validate(predicate = |map| map.len() > 1),
derive(AsRef)
)]
struct NonEmptyMap<K, V>(HashMap<K, V>);

let mut inner_map = HashMap::new();
inner_map.insert(4, 16);
inner_map.insert(5, 25);
let squares = NonEmptyMap::new(inner_map.clone()).unwrap();
assert_eq!(squares.as_ref(), &inner_map);
}
}

0 comments on commit 67ecaa5

Please sign in to comment.