Skip to content

Commit b099900

Browse files
committed
Derive Zero and One for newtypes
1 parent e4d40fe commit b099900

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

src/lib.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,3 +515,45 @@ pub fn num_cast(input: TokenStream) -> TokenStream {
515515
}
516516
}).into()
517517
}
518+
519+
/// Derives [`num_traits::Zero`][zero] for newtypes. The inner type must already implement `Zero`.
520+
///
521+
/// [zero]: https://docs.rs/num-traits/0.2/num_traits/identities/trait.Zero.html
522+
#[proc_macro_derive(Zero)]
523+
pub fn zero(input: TokenStream) -> TokenStream {
524+
let ast: syn::DeriveInput = syn::parse(input).unwrap();
525+
let name = &ast.ident;
526+
let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
527+
dummy_const_trick("Zero", &name, quote! {
528+
extern crate num_traits as _num_traits;
529+
impl _num_traits::Zero for #name {
530+
fn zero() -> Self {
531+
#name(<#inner_ty as _num_traits::Zero>::zero())
532+
}
533+
fn is_zero(&self) -> bool {
534+
<#inner_ty as _num_traits::Zero>::is_zero(&self.0)
535+
}
536+
}
537+
}).into()
538+
}
539+
540+
/// Derives [`num_traits::One`][one] for newtypes. The inner type must already implement `One`.
541+
///
542+
/// [one]: https://docs.rs/num-traits/0.2/num_traits/identities/trait.One.html
543+
#[proc_macro_derive(One)]
544+
pub fn one(input: TokenStream) -> TokenStream {
545+
let ast: syn::DeriveInput = syn::parse(input).unwrap();
546+
let name = &ast.ident;
547+
let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
548+
dummy_const_trick("One", &name, quote! {
549+
extern crate num_traits as _num_traits;
550+
impl _num_traits::One for #name {
551+
fn one() -> Self {
552+
#name(<#inner_ty as _num_traits::One>::one())
553+
}
554+
fn is_one(&self) -> bool {
555+
<#inner_ty as _num_traits::One>::is_one(&self.0)
556+
}
557+
}
558+
}).into()
559+
}

tests/newtype.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ extern crate num as num_renamed;
22
#[macro_use]
33
extern crate num_derive;
44

5-
use num_renamed::{FromPrimitive, ToPrimitive, NumCast};
5+
use num_renamed::{FromPrimitive, ToPrimitive, NumCast, One, Zero};
66

77
#[derive(
88
Debug,
@@ -14,6 +14,8 @@ use num_renamed::{FromPrimitive, ToPrimitive, NumCast};
1414
FromPrimitive,
1515
NumOps,
1616
NumCast,
17+
One,
18+
Zero,
1719
)]
1820
struct MyFloat(f64);
1921

@@ -40,3 +42,13 @@ fn test_num_ops() {
4042
fn test_num_cast() {
4143
assert_eq!(<MyFloat as NumCast>::from(25u8), Some(MyFloat(25.0)));
4244
}
45+
46+
#[test]
47+
fn test_zero() {
48+
assert_eq!(MyFloat::zero(), MyFloat(0.0));
49+
}
50+
51+
#[test]
52+
fn test_one() {
53+
assert_eq!(MyFloat::one(), MyFloat(1.0));
54+
}

0 commit comments

Comments
 (0)