Skip to content

Commit

Permalink
Example of generic From
Browse files Browse the repository at this point in the history
  • Loading branch information
greyblake committed Feb 25, 2024
1 parent fd09132 commit d73ddeb
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 15 deletions.
11 changes: 4 additions & 7 deletions dummy/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use nutype::nutype;

#[nutype(
validate(predicate = |v| v),
derive(Default),
default = true
)]
pub struct TestData(bool);
#[nutype(derive(Into, From))]
pub struct Amount(i32);

fn main() {}
fn main() {
}
22 changes: 19 additions & 3 deletions nutype_macros/src/common/gen/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ pub fn gen_impl_trait_into(type_name: &TypeName, inner_type: impl Into<InnerType
value.into_inner()
}
}

// Alt implementation for Into without From.
// That works, but it breaks the symmetry between Into and From.
//
// impl ::core::convert::Into<#inner_type> for #type_name {
// #[inline]
// fn into(self) -> #inner_type {
// self.0
// }
// }
}
}

Expand Down Expand Up @@ -123,11 +133,17 @@ pub fn gen_impl_trait_borrow(type_name: &TypeName, borrowed_type: impl ToTokens)
}

pub fn gen_impl_trait_from(type_name: &TypeName, inner_type: impl ToTokens) -> TokenStream {
dbg!(quote!(#inner_type).to_string());

quote! {
impl ::core::convert::From<#inner_type> for #type_name {
impl<T> ::core::convert::From<T> for #type_name
where
#inner_type: ::core::convert::From<T>
{
#[inline]
fn from(raw_value: #inner_type) -> Self {
Self::new(raw_value)
fn from(raw_value: T) -> Self {
let inner_value = #inner_type::from(raw_value);
Self::new(inner_value)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions nutype_macros/src/string/gen/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,11 @@ fn gen_impl_from_str(

fn gen_impl_from_str_and_string(type_name: &TypeName) -> TokenStream {
let impl_from_string = gen_impl_trait_from(type_name, quote!(String));
let impl_from_str = gen_impl_trait_from(type_name, quote!(&str));
// let impl_from_str = gen_impl_trait_from(type_name, quote!(&str));

quote! {
#impl_from_string
#impl_from_str
//#impl_from_str
}
}

Expand Down
12 changes: 9 additions & 3 deletions test_suite/tests/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,14 @@ mod types {
)]
struct Amount(isize);

assert_eq!(Amount::new(999), Err(AmountError::GreaterOrEqualViolated));
assert_eq!(Amount::new(2001), Err(AmountError::LessOrEqualViolated));
assert_eq!(
Amount::new(999isize),
Err(AmountError::GreaterOrEqualViolated)
);
assert_eq!(
Amount::new(2001isize),
Err(AmountError::LessOrEqualViolated)
);
assert!(Amount::new(1000).is_ok());
assert!(Amount::new(2000).is_ok());
}
Expand Down Expand Up @@ -532,7 +538,7 @@ mod traits {
#[nutype(derive(From))]
pub struct Amount(u32);

let amount = Amount::from(350);
let amount = Amount::from(350u32);
assert_eq!(amount.into_inner(), 350);
}

Expand Down

0 comments on commit d73ddeb

Please sign in to comment.