Skip to content

Commit

Permalink
Merge pull request #46 from greyblake/derive-deref
Browse files Browse the repository at this point in the history
Support derive(Deref)
  • Loading branch information
greyblake authored Jun 30, 2023
2 parents e8bb819 + f52c308 commit fef281d
Show file tree
Hide file tree
Showing 19 changed files with 88 additions and 13 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### v0.3.1 - 2023-06-29
* Support deriving of `Deref`

### v0.3.0 - 2023-06-25
* [BREAKING] `min_len` and `max_len` validators run against number of characters in a string (`val.chars().count()`), not number of bytes (`val.len()`).
* Add `finite` validation for float types which checks against NaN and infinity.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ pub struct PhoneNumber(String);
### String derivable traits

The following traits can be derived for a string-based type:
`Debug`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `From`, `TryFrom`, `Into`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.
`Debug`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Deref`,
`From`, `TryFrom`, `Into`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.


## Integer
Expand All @@ -204,7 +205,8 @@ The integer inner types are: `u8`, `u16`,`u32`, `u64`, `u128`, `i8`, `i16`, `i32
### Integer derivable traits

The following traits can be derived for an integer-based type:
`Debug`, `Clone`, `Copy`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Into`, `From`, `TryFrom`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.
`Debug`, `Clone`, `Copy`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Deref`,
`Into`, `From`, `TryFrom`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.


## Float
Expand All @@ -229,7 +231,8 @@ The float inner types are: `f32`, `f64`.
### Float derivable traits

The following traits can be derived for a float-based type:
`Debug`, `Clone`, `Copy`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Into`, `From`, `TryFrom`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.
`Debug`, `Clone`, `Copy`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Deref`,
`Into`, `From`, `TryFrom`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.

It's also possible to derive `Eq` and `Ord` if the validation rules guarantee that `NaN` is excluded.
This can be done applying by `finite` validation. For example:
Expand Down
9 changes: 6 additions & 3 deletions nutype/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@
//! ### String derivable traits
//!
//! The following traits can be derived for a string-based type:
//! `Debug`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `From`, `TryFrom`, `Into`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.
//! `Debug`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Deref`,
//! `From`, `TryFrom`, `Into`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.
//!
//!
//! ## Integer
Expand All @@ -201,7 +202,8 @@
//! ### Integer derivable traits
//!
//! The following traits can be derived for an integer-based type:
//! `Debug`, `Clone`, `Copy`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Into`, `From`, `TryFrom`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.
//! `Debug`, `Clone`, `Copy`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Deref`,
//! `Into`, `From`, `TryFrom`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.
//!
//!
//! ## Float
Expand All @@ -226,7 +228,8 @@
//! ### Float derivable traits
//!
//! The following traits can be derived for a float-based type:
//! `Debug`, `Clone`, `Copy`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Into`, `From`, `TryFrom`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.
//! `Debug`, `Clone`, `Copy`, `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `FromStr`, `AsRef`, `Deref`,
//! `Into`, `From`, `TryFrom`, `Hash`, `Borrow`, `Display`, `Default`, `Serialize`, `Deserialize`.
//!
//! It's also possible to derive `Eq` and `Ord` if the validation rules guarantee that `NaN` is excluded.
//! This can be done by applying `finite` validation. For example:
Expand Down
12 changes: 12 additions & 0 deletions nutype_macros/src/common/gen/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ pub fn gen_impl_trait_as_ref(type_name: &TypeName, inner_type: impl ToTokens) ->
}
}

pub fn gen_impl_trait_deref(type_name: &TypeName, inner_type: impl ToTokens) -> TokenStream {
quote! {
impl ::core::ops::Deref for #type_name {
type Target = #inner_type;

fn deref(&self) -> &Self::Target {
&self.0
}
}
}
}

pub fn gen_impl_trait_dislpay(type_name: &TypeName) -> TokenStream {
quote! {
impl ::core::fmt::Display for #type_name {
Expand Down
1 change: 1 addition & 0 deletions nutype_macros/src/common/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ pub enum NormalDeriveTrait {
Borrow,
Display,
Default,
Deref,

// External crates
//
Expand Down
1 change: 1 addition & 0 deletions nutype_macros/src/common/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ fn parse_ident_into_derive_trait(ident: Ident) -> Result<SpannedDeriveTrait, syn
"Ord" => NormalDeriveTrait::Ord,
"FromStr" => NormalDeriveTrait::FromStr,
"AsRef" => NormalDeriveTrait::AsRef,
"Deref" => NormalDeriveTrait::Deref,
"TryFrom" => NormalDeriveTrait::TryFrom,
"From" => NormalDeriveTrait::From,
"Into" => NormalDeriveTrait::Into,
Expand Down
5 changes: 4 additions & 1 deletion nutype_macros/src/float/gen/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
GeneratableTrait, GeneratableTraits, GeneratedTraits,
},
common::{
gen::traits::gen_impl_trait_default,
gen::traits::{gen_impl_trait_default, gen_impl_trait_deref},
models::{ErrorTypeName, FloatInnerType, TypeName},
},
float::models::FloatDeriveTrait,
Expand All @@ -36,6 +36,7 @@ enum FloatTransparentTrait {
enum FloatIrregularTrait {
FromStr,
AsRef,
Deref,
Into,
From,
Eq,
Expand Down Expand Up @@ -72,6 +73,7 @@ impl From<FloatDeriveTrait> for FloatGeneratableTrait {
FloatGeneratableTrait::Irregular(FloatIrregularTrait::FromStr)
}
FloatDeriveTrait::AsRef => FloatGeneratableTrait::Irregular(FloatIrregularTrait::AsRef),
FloatDeriveTrait::Deref => FloatGeneratableTrait::Irregular(FloatIrregularTrait::Deref),
FloatDeriveTrait::From => FloatGeneratableTrait::Irregular(FloatIrregularTrait::From),
FloatDeriveTrait::Into => FloatGeneratableTrait::Irregular(FloatIrregularTrait::Into),
FloatDeriveTrait::TryFrom => {
Expand Down Expand Up @@ -156,6 +158,7 @@ fn gen_implemented_traits(
.iter()
.map(|t| match t {
FloatIrregularTrait::AsRef => gen_impl_trait_as_ref(type_name, inner_type),
FloatIrregularTrait::Deref => gen_impl_trait_deref(type_name, inner_type),
FloatIrregularTrait::FromStr => {
gen_impl_trait_from_str(type_name, inner_type, maybe_error_type_name.as_ref())
}
Expand Down
1 change: 1 addition & 0 deletions nutype_macros/src/float/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub enum FloatDeriveTrait {
Borrow,
Display,
Default,
Deref,

// External crates
SerdeSerialize,
Expand Down
1 change: 1 addition & 0 deletions nutype_macros/src/float/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ fn to_float_derive_trait(
}
NormalDeriveTrait::FromStr => Ok(FloatDeriveTrait::FromStr),
NormalDeriveTrait::AsRef => Ok(FloatDeriveTrait::AsRef),
NormalDeriveTrait::Deref => Ok(FloatDeriveTrait::Deref),
NormalDeriveTrait::Hash => Err(syn::Error::new(
span,
"#[nutype] cannot derive `Hash` trait for float types.",
Expand Down
13 changes: 9 additions & 4 deletions nutype_macros/src/integer/gen/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use crate::{
common::{
gen::traits::{
gen_impl_trait_as_ref, gen_impl_trait_borrow, gen_impl_trait_default,
gen_impl_trait_dislpay, gen_impl_trait_from, gen_impl_trait_from_str,
gen_impl_trait_into, gen_impl_trait_serde_deserialize, gen_impl_trait_serde_serialize,
gen_impl_trait_try_from, split_into_generatable_traits, GeneratableTrait,
GeneratableTraits, GeneratedTraits,
gen_impl_trait_deref, gen_impl_trait_dislpay, gen_impl_trait_from,
gen_impl_trait_from_str, gen_impl_trait_into, gen_impl_trait_serde_deserialize,
gen_impl_trait_serde_serialize, gen_impl_trait_try_from, split_into_generatable_traits,
GeneratableTrait, GeneratableTraits, GeneratedTraits,
},
models::{ErrorTypeName, IntegerInnerType, TypeName},
},
Expand Down Expand Up @@ -84,6 +84,9 @@ impl From<IntegerDeriveTrait> for IntegerGeneratableTrait {
IntegerDeriveTrait::AsRef => {
IntegerGeneratableTrait::Irregular(IntegerIrregularTrait::AsRef)
}
IntegerDeriveTrait::Deref => {
IntegerGeneratableTrait::Irregular(IntegerIrregularTrait::Deref)
}
IntegerDeriveTrait::Into => {
IntegerGeneratableTrait::Irregular(IntegerIrregularTrait::Into)
}
Expand Down Expand Up @@ -135,6 +138,7 @@ enum IntegerTransparentTrait {
enum IntegerIrregularTrait {
FromStr,
AsRef,
Deref,
From,
TryFrom,
Borrow,
Expand Down Expand Up @@ -173,6 +177,7 @@ fn gen_implemented_traits(
.iter()
.map(|t| match t {
IntegerIrregularTrait::AsRef => gen_impl_trait_as_ref(type_name, inner_type),
IntegerIrregularTrait::Deref => gen_impl_trait_deref(type_name, inner_type),
IntegerIrregularTrait::FromStr => {
gen_impl_trait_from_str(type_name, inner_type, maybe_error_type_name.as_ref())
}
Expand Down
1 change: 1 addition & 0 deletions nutype_macros/src/integer/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ pub enum IntegerDeriveTrait {
Borrow,
Display,
Default,
Deref,

// // External crates
SerdeSerialize,
Expand Down
1 change: 1 addition & 0 deletions nutype_macros/src/integer/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ fn to_integer_derive_trait(
NormalDeriveTrait::Into => Ok(IntegerDeriveTrait::Into),
NormalDeriveTrait::FromStr => Ok(IntegerDeriveTrait::FromStr),
NormalDeriveTrait::AsRef => Ok(IntegerDeriveTrait::AsRef),
NormalDeriveTrait::Deref => Ok(IntegerDeriveTrait::Deref),
NormalDeriveTrait::Hash => Ok(IntegerDeriveTrait::Hash),
NormalDeriveTrait::Borrow => Ok(IntegerDeriveTrait::Borrow),
NormalDeriveTrait::Copy => Ok(IntegerDeriveTrait::Copy),
Expand Down
7 changes: 6 additions & 1 deletion nutype_macros/src/string/gen/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
common::{
gen::traits::{
gen_impl_trait_as_ref, gen_impl_trait_borrow, gen_impl_trait_default,
gen_impl_trait_dislpay, gen_impl_trait_from, gen_impl_trait_into,
gen_impl_trait_deref, gen_impl_trait_dislpay, gen_impl_trait_from, gen_impl_trait_into,
gen_impl_trait_serde_deserialize, gen_impl_trait_serde_serialize,
gen_impl_trait_try_from, split_into_generatable_traits, GeneratableTrait,
GeneratableTraits, GeneratedTraits,
Expand Down Expand Up @@ -38,6 +38,7 @@ enum StringTransparentTrait {
enum StringIrregularTrait {
FromStr,
AsRef,
Deref,
Into,
From,
TryFrom,
Expand Down Expand Up @@ -78,6 +79,9 @@ impl From<StringDeriveTrait> for StringGeneratableTrait {
StringDeriveTrait::AsRef => {
StringGeneratableTrait::Irregular(StringIrregularTrait::AsRef)
}
StringDeriveTrait::Deref => {
StringGeneratableTrait::Irregular(StringIrregularTrait::Deref)
}
StringDeriveTrait::Into => {
StringGeneratableTrait::Irregular(StringIrregularTrait::Into)
}
Expand Down Expand Up @@ -167,6 +171,7 @@ fn gen_implemented_traits(
.iter()
.map(|t| match t {
StringIrregularTrait::AsRef => gen_impl_trait_as_ref(type_name, quote!(str)),
StringIrregularTrait::Deref => gen_impl_trait_deref(type_name, quote!(String)),
StringIrregularTrait::FromStr => {
gen_impl_from_str(type_name, maybe_error_type_name.as_ref())
}
Expand Down
1 change: 1 addition & 0 deletions nutype_macros/src/string/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ pub enum StringDeriveTrait {
Borrow,
Display,
Default,
Deref,

// // External crates
//
Expand Down
1 change: 1 addition & 0 deletions nutype_macros/src/string/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ fn to_string_derive_trait(
NormalDeriveTrait::Ord => Ok(StringDeriveTrait::Ord),
NormalDeriveTrait::FromStr => Ok(StringDeriveTrait::FromStr),
NormalDeriveTrait::AsRef => Ok(StringDeriveTrait::AsRef),
NormalDeriveTrait::Deref => Ok(StringDeriveTrait::Deref),
NormalDeriveTrait::Hash => Ok(StringDeriveTrait::Hash),
NormalDeriveTrait::Borrow => Ok(StringDeriveTrait::Borrow),
NormalDeriveTrait::Into => Ok(StringDeriveTrait::Into),
Expand Down
10 changes: 10 additions & 0 deletions test_suite/tests/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,16 @@ mod traits {
assert_eq!(weight_ref, &72.650);
}

#[test]
fn test_trait_deref() {
#[nutype]
#[derive(Deref)]
pub struct Number(f64);

let magic = Number::new(42.0);
assert_eq!(*magic, 42.0);
}

#[test]
fn test_trait_borrow() {
use std::borrow::Borrow;
Expand Down
10 changes: 10 additions & 0 deletions test_suite/tests/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,16 @@ mod traits {
assert_eq!(age_ref, &32);
}

#[test]
fn test_trait_deref() {
#[nutype]
#[derive(Deref)]
pub struct Number(i16);

let magic = Number::new(42);
assert_eq!(*magic, 42);
}

#[test]
fn test_trait_borrow() {
use std::borrow::Borrow;
Expand Down
13 changes: 13 additions & 0 deletions test_suite/tests/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,19 @@ mod derives {
assert_eq!(name_ref, "Anna")
}

#[test]
fn test_trait_deref() {
#[nutype]
#[derive(Deref)]
pub struct Name(String);

let name = Name::new("Anna");

// Let's do something with deref-coercion:
assert_eq!(name.len(), 4);
assert_eq!(name.is_empty(), false);
}

#[test]
fn test_trait_borrow_str() {
use std::borrow::Borrow;
Expand Down

0 comments on commit fef281d

Please sign in to comment.