1#![crate_type = "proc-macro"]
12#![recursion_limit = "512"]
13
14extern crate proc_macro;
66
67use proc_macro::TokenStream;
68use proc_macro2::{Span, TokenStream as TokenStream2};
69use quote::quote;
70use syn::{Data, Fields, Ident};
71
72macro_rules! parse {
74 ($tokens:ident as $type:ty) => {
75 match syn::parse::<$type>($tokens) {
76 Ok(parsed) => parsed,
77 Err(error) => {
78 return TokenStream::from(error.to_compile_error());
79 }
80 }
81 };
82}
83
84fn anon_const_trick(exp: TokenStream2) -> TokenStream2 {
102 quote! {
103 #[allow(non_upper_case_globals, unused_qualifications)]
104 const _: () = {
105 #[allow(clippy::useless_attribute)]
106 #[allow(rust_2018_idioms)]
107 extern crate num_traits as _num_traits;
108 #exp
109 };
110 }
111}
112
113fn newtype_inner(data: &syn::Data) -> Option<syn::Type> {
115 match *data {
116 Data::Struct(ref s) => {
117 match s.fields {
118 Fields::Unnamed(ref fs) => {
119 if fs.unnamed.len() == 1 {
120 Some(fs.unnamed[0].ty.clone())
121 } else {
122 None
123 }
124 }
125 Fields::Named(ref fs) => {
126 if fs.named.len() == 1 {
127 panic!("num-derive doesn't know how to handle newtypes with named fields yet. \
128 Please use a tuple-style newtype, or submit a PR!");
129 }
130 None
131 }
132 _ => None,
133 }
134 }
135 _ => None,
136 }
137}
138
139struct NumTraits {
140 import: Ident,
141 explicit: bool,
142}
143
144impl quote::ToTokens for NumTraits {
145 fn to_tokens(&self, tokens: &mut TokenStream2) {
146 self.import.to_tokens(tokens);
147 }
148}
149
150impl NumTraits {
151 fn new(ast: &syn::DeriveInput) -> Self {
152 for attr in &ast.attrs {
156 if attr.path().is_ident("num_traits") {
157 if let Ok(syn::MetaNameValue {
158 value:
159 syn::Expr::Lit(syn::ExprLit {
160 lit: syn::Lit::Str(ref lit_str),
161 ..
162 }),
163 ..
164 }) = attr.meta.require_name_value()
165 {
166 return NumTraits {
167 import: syn::Ident::new(&lit_str.value(), lit_str.span()),
168 explicit: true,
169 };
170 } else {
171 panic!("#[num_traits] attribute value must be a str");
172 }
173 }
174 }
175
176 NumTraits {
178 import: Ident::new("_num_traits", Span::call_site()),
179 explicit: false,
180 }
181 }
182
183 fn wrap(&self, output: TokenStream2) -> TokenStream2 {
184 if self.explicit {
185 output
186 } else {
187 anon_const_trick(output)
188 }
189 }
190}
191
192#[proc_macro_derive(FromPrimitive, attributes(num_traits))]
241pub fn from_primitive(input: TokenStream) -> TokenStream {
242 let ast = parse!(input as syn::DeriveInput);
243 let name = &ast.ident;
244
245 let import = NumTraits::new(&ast);
246
247 let impl_ = if let Some(inner_ty) = newtype_inner(&ast.data) {
248 quote! {
249 impl #import::FromPrimitive for #name {
250 #[inline]
251 fn from_i64(n: i64) -> ::core::option::Option<Self> {
252 <#inner_ty as #import::FromPrimitive>::from_i64(n).map(#name)
253 }
254 #[inline]
255 fn from_u64(n: u64) -> ::core::option::Option<Self> {
256 <#inner_ty as #import::FromPrimitive>::from_u64(n).map(#name)
257 }
258 #[inline]
259 fn from_isize(n: isize) -> ::core::option::Option<Self> {
260 <#inner_ty as #import::FromPrimitive>::from_isize(n).map(#name)
261 }
262 #[inline]
263 fn from_i8(n: i8) -> ::core::option::Option<Self> {
264 <#inner_ty as #import::FromPrimitive>::from_i8(n).map(#name)
265 }
266 #[inline]
267 fn from_i16(n: i16) -> ::core::option::Option<Self> {
268 <#inner_ty as #import::FromPrimitive>::from_i16(n).map(#name)
269 }
270 #[inline]
271 fn from_i32(n: i32) -> ::core::option::Option<Self> {
272 <#inner_ty as #import::FromPrimitive>::from_i32(n).map(#name)
273 }
274 #[inline]
275 fn from_i128(n: i128) -> ::core::option::Option<Self> {
276 <#inner_ty as #import::FromPrimitive>::from_i128(n).map(#name)
277 }
278 #[inline]
279 fn from_usize(n: usize) -> ::core::option::Option<Self> {
280 <#inner_ty as #import::FromPrimitive>::from_usize(n).map(#name)
281 }
282 #[inline]
283 fn from_u8(n: u8) -> ::core::option::Option<Self> {
284 <#inner_ty as #import::FromPrimitive>::from_u8(n).map(#name)
285 }
286 #[inline]
287 fn from_u16(n: u16) -> ::core::option::Option<Self> {
288 <#inner_ty as #import::FromPrimitive>::from_u16(n).map(#name)
289 }
290 #[inline]
291 fn from_u32(n: u32) -> ::core::option::Option<Self> {
292 <#inner_ty as #import::FromPrimitive>::from_u32(n).map(#name)
293 }
294 #[inline]
295 fn from_u128(n: u128) -> ::core::option::Option<Self> {
296 <#inner_ty as #import::FromPrimitive>::from_u128(n).map(#name)
297 }
298 #[inline]
299 fn from_f32(n: f32) -> ::core::option::Option<Self> {
300 <#inner_ty as #import::FromPrimitive>::from_f32(n).map(#name)
301 }
302 #[inline]
303 fn from_f64(n: f64) -> ::core::option::Option<Self> {
304 <#inner_ty as #import::FromPrimitive>::from_f64(n).map(#name)
305 }
306 }
307 }
308 } else {
309 let variants = match ast.data {
310 Data::Enum(ref data_enum) => &data_enum.variants,
311 _ => panic!(
312 "`FromPrimitive` can be applied only to enums and newtypes, {} is neither",
313 name
314 ),
315 };
316
317 let from_i64_var = quote! { n };
318 let clauses: Vec<_> = variants
319 .iter()
320 .map(|variant| {
321 let ident = &variant.ident;
322 match variant.fields {
323 Fields::Unit => (),
324 _ => panic!(
325 "`FromPrimitive` can be applied only to unitary enums and newtypes, \
326 {}::{} is either struct or tuple",
327 name, ident
328 ),
329 }
330
331 quote! {
332 if #from_i64_var == #name::#ident as i64 {
333 ::core::option::Option::Some(#name::#ident)
334 }
335 }
336 })
337 .collect();
338
339 let from_i64_var = if clauses.is_empty() {
340 quote!(_)
341 } else {
342 from_i64_var
343 };
344
345 quote! {
346 impl #import::FromPrimitive for #name {
347 #[allow(trivial_numeric_casts)]
348 #[inline]
349 fn from_i64(#from_i64_var: i64) -> ::core::option::Option<Self> {
350 #(#clauses else)* {
351 ::core::option::Option::None
352 }
353 }
354
355 #[inline]
356 fn from_u64(n: u64) -> ::core::option::Option<Self> {
357 Self::from_i64(n as i64)
358 }
359 }
360 }
361 };
362
363 import.wrap(impl_).into()
364}
365
366#[proc_macro_derive(ToPrimitive, attributes(num_traits))]
415pub fn to_primitive(input: TokenStream) -> TokenStream {
416 let ast = parse!(input as syn::DeriveInput);
417 let name = &ast.ident;
418
419 let import = NumTraits::new(&ast);
420
421 let impl_ = if let Some(inner_ty) = newtype_inner(&ast.data) {
422 quote! {
423 impl #import::ToPrimitive for #name {
424 #[inline]
425 fn to_i64(&self) -> ::core::option::Option<i64> {
426 <#inner_ty as #import::ToPrimitive>::to_i64(&self.0)
427 }
428 #[inline]
429 fn to_u64(&self) -> ::core::option::Option<u64> {
430 <#inner_ty as #import::ToPrimitive>::to_u64(&self.0)
431 }
432 #[inline]
433 fn to_isize(&self) -> ::core::option::Option<isize> {
434 <#inner_ty as #import::ToPrimitive>::to_isize(&self.0)
435 }
436 #[inline]
437 fn to_i8(&self) -> ::core::option::Option<i8> {
438 <#inner_ty as #import::ToPrimitive>::to_i8(&self.0)
439 }
440 #[inline]
441 fn to_i16(&self) -> ::core::option::Option<i16> {
442 <#inner_ty as #import::ToPrimitive>::to_i16(&self.0)
443 }
444 #[inline]
445 fn to_i32(&self) -> ::core::option::Option<i32> {
446 <#inner_ty as #import::ToPrimitive>::to_i32(&self.0)
447 }
448 #[inline]
449 fn to_i128(&self) -> ::core::option::Option<i128> {
450 <#inner_ty as #import::ToPrimitive>::to_i128(&self.0)
451 }
452 #[inline]
453 fn to_usize(&self) -> ::core::option::Option<usize> {
454 <#inner_ty as #import::ToPrimitive>::to_usize(&self.0)
455 }
456 #[inline]
457 fn to_u8(&self) -> ::core::option::Option<u8> {
458 <#inner_ty as #import::ToPrimitive>::to_u8(&self.0)
459 }
460 #[inline]
461 fn to_u16(&self) -> ::core::option::Option<u16> {
462 <#inner_ty as #import::ToPrimitive>::to_u16(&self.0)
463 }
464 #[inline]
465 fn to_u32(&self) -> ::core::option::Option<u32> {
466 <#inner_ty as #import::ToPrimitive>::to_u32(&self.0)
467 }
468 #[inline]
469 fn to_u128(&self) -> ::core::option::Option<u128> {
470 <#inner_ty as #import::ToPrimitive>::to_u128(&self.0)
471 }
472 #[inline]
473 fn to_f32(&self) -> ::core::option::Option<f32> {
474 <#inner_ty as #import::ToPrimitive>::to_f32(&self.0)
475 }
476 #[inline]
477 fn to_f64(&self) -> ::core::option::Option<f64> {
478 <#inner_ty as #import::ToPrimitive>::to_f64(&self.0)
479 }
480 }
481 }
482 } else {
483 let variants = match ast.data {
484 Data::Enum(ref data_enum) => &data_enum.variants,
485 _ => panic!(
486 "`ToPrimitive` can be applied only to enums and newtypes, {} is neither",
487 name
488 ),
489 };
490
491 let variants: Vec<_> = variants
492 .iter()
493 .map(|variant| {
494 let ident = &variant.ident;
495 match variant.fields {
496 Fields::Unit => (),
497 _ => {
498 panic!("`ToPrimitive` can be applied only to unitary enums and newtypes, {}::{} is either struct or tuple", name, ident)
499 },
500 }
501
502 quote!(#name::#ident => #name::#ident as i64)
506 })
507 .collect();
508
509 let match_expr = if variants.is_empty() {
510 quote! {
512 match *self {}
513 }
514 } else {
515 quote! {
516 ::core::option::Option::Some(match *self {
517 #(#variants,)*
518 })
519 }
520 };
521
522 quote! {
523 impl #import::ToPrimitive for #name {
524 #[inline]
525 #[allow(trivial_numeric_casts)]
526 fn to_i64(&self) -> ::core::option::Option<i64> {
527 #match_expr
528 }
529
530 #[inline]
531 fn to_u64(&self) -> ::core::option::Option<u64> {
532 self.to_i64().map(|x| x as u64)
533 }
534 }
535 }
536 };
537
538 import.wrap(impl_).into()
539}
540
541const NEWTYPE_ONLY: &str = "This trait can only be derived for newtypes";
542
543#[proc_macro_derive(NumOps)]
552pub fn num_ops(input: TokenStream) -> TokenStream {
553 let ast = parse!(input as syn::DeriveInput);
554 let name = &ast.ident;
555 let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
556 let impl_ = quote! {
557 impl ::core::ops::Add for #name {
558 type Output = Self;
559 #[inline]
560 fn add(self, other: Self) -> Self {
561 #name(<#inner_ty as ::core::ops::Add>::add(self.0, other.0))
562 }
563 }
564 impl ::core::ops::Sub for #name {
565 type Output = Self;
566 #[inline]
567 fn sub(self, other: Self) -> Self {
568 #name(<#inner_ty as ::core::ops::Sub>::sub(self.0, other.0))
569 }
570 }
571 impl ::core::ops::Mul for #name {
572 type Output = Self;
573 #[inline]
574 fn mul(self, other: Self) -> Self {
575 #name(<#inner_ty as ::core::ops::Mul>::mul(self.0, other.0))
576 }
577 }
578 impl ::core::ops::Div for #name {
579 type Output = Self;
580 #[inline]
581 fn div(self, other: Self) -> Self {
582 #name(<#inner_ty as ::core::ops::Div>::div(self.0, other.0))
583 }
584 }
585 impl ::core::ops::Rem for #name {
586 type Output = Self;
587 #[inline]
588 fn rem(self, other: Self) -> Self {
589 #name(<#inner_ty as ::core::ops::Rem>::rem(self.0, other.0))
590 }
591 }
592 };
593 impl_.into()
594}
595
596#[proc_macro_derive(NumCast, attributes(num_traits))]
601pub fn num_cast(input: TokenStream) -> TokenStream {
602 let ast = parse!(input as syn::DeriveInput);
603 let name = &ast.ident;
604 let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
605
606 let import = NumTraits::new(&ast);
607
608 let impl_ = quote! {
609 impl #import::NumCast for #name {
610 #[inline]
611 fn from<T: #import::ToPrimitive>(n: T) -> ::core::option::Option<Self> {
612 <#inner_ty as #import::NumCast>::from(n).map(#name)
613 }
614 }
615 };
616
617 import.wrap(impl_).into()
618}
619
620#[proc_macro_derive(Zero, attributes(num_traits))]
624pub fn zero(input: TokenStream) -> TokenStream {
625 let ast = parse!(input as syn::DeriveInput);
626 let name = &ast.ident;
627 let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
628
629 let import = NumTraits::new(&ast);
630
631 let impl_ = quote! {
632 impl #import::Zero for #name {
633 #[inline]
634 fn zero() -> Self {
635 #name(<#inner_ty as #import::Zero>::zero())
636 }
637 #[inline]
638 fn is_zero(&self) -> bool {
639 <#inner_ty as #import::Zero>::is_zero(&self.0)
640 }
641 }
642 };
643
644 import.wrap(impl_).into()
645}
646
647#[proc_macro_derive(One, attributes(num_traits))]
651pub fn one(input: TokenStream) -> TokenStream {
652 let ast = parse!(input as syn::DeriveInput);
653 let name = &ast.ident;
654 let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
655
656 let import = NumTraits::new(&ast);
657
658 let impl_ = quote! {
659 impl #import::One for #name {
660 #[inline]
661 fn one() -> Self {
662 #name(<#inner_ty as #import::One>::one())
663 }
664 #[inline]
665 fn is_one(&self) -> bool {
666 <#inner_ty as #import::One>::is_one(&self.0)
667 }
668 }
669 };
670
671 import.wrap(impl_).into()
672}
673
674#[proc_macro_derive(Num, attributes(num_traits))]
678pub fn num(input: TokenStream) -> TokenStream {
679 let ast = parse!(input as syn::DeriveInput);
680 let name = &ast.ident;
681 let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
682
683 let import = NumTraits::new(&ast);
684
685 let impl_ = quote! {
686 impl #import::Num for #name {
687 type FromStrRadixErr = <#inner_ty as #import::Num>::FromStrRadixErr;
688 #[inline]
689 fn from_str_radix(s: &str, radix: u32) -> ::core::result::Result<Self, Self::FromStrRadixErr> {
690 <#inner_ty as #import::Num>::from_str_radix(s, radix).map(#name)
691 }
692 }
693 };
694
695 import.wrap(impl_).into()
696}
697
698#[proc_macro_derive(Float, attributes(num_traits))]
703pub fn float(input: TokenStream) -> TokenStream {
704 let ast = parse!(input as syn::DeriveInput);
705 let name = &ast.ident;
706 let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
707
708 let import = NumTraits::new(&ast);
709
710 let impl_ = quote! {
711 impl #import::Float for #name {
712 #[inline]
713 fn nan() -> Self {
714 #name(<#inner_ty as #import::Float>::nan())
715 }
716 #[inline]
717 fn infinity() -> Self {
718 #name(<#inner_ty as #import::Float>::infinity())
719 }
720 #[inline]
721 fn neg_infinity() -> Self {
722 #name(<#inner_ty as #import::Float>::neg_infinity())
723 }
724 #[inline]
725 fn neg_zero() -> Self {
726 #name(<#inner_ty as #import::Float>::neg_zero())
727 }
728 #[inline]
729 fn min_value() -> Self {
730 #name(<#inner_ty as #import::Float>::min_value())
731 }
732 #[inline]
733 fn min_positive_value() -> Self {
734 #name(<#inner_ty as #import::Float>::min_positive_value())
735 }
736 #[inline]
737 fn max_value() -> Self {
738 #name(<#inner_ty as #import::Float>::max_value())
739 }
740 #[inline]
741 fn is_nan(self) -> bool {
742 <#inner_ty as #import::Float>::is_nan(self.0)
743 }
744 #[inline]
745 fn is_infinite(self) -> bool {
746 <#inner_ty as #import::Float>::is_infinite(self.0)
747 }
748 #[inline]
749 fn is_finite(self) -> bool {
750 <#inner_ty as #import::Float>::is_finite(self.0)
751 }
752 #[inline]
753 fn is_normal(self) -> bool {
754 <#inner_ty as #import::Float>::is_normal(self.0)
755 }
756 #[inline]
757 fn classify(self) -> ::core::num::FpCategory {
758 <#inner_ty as #import::Float>::classify(self.0)
759 }
760 #[inline]
761 fn floor(self) -> Self {
762 #name(<#inner_ty as #import::Float>::floor(self.0))
763 }
764 #[inline]
765 fn ceil(self) -> Self {
766 #name(<#inner_ty as #import::Float>::ceil(self.0))
767 }
768 #[inline]
769 fn round(self) -> Self {
770 #name(<#inner_ty as #import::Float>::round(self.0))
771 }
772 #[inline]
773 fn trunc(self) -> Self {
774 #name(<#inner_ty as #import::Float>::trunc(self.0))
775 }
776 #[inline]
777 fn fract(self) -> Self {
778 #name(<#inner_ty as #import::Float>::fract(self.0))
779 }
780 #[inline]
781 fn abs(self) -> Self {
782 #name(<#inner_ty as #import::Float>::abs(self.0))
783 }
784 #[inline]
785 fn signum(self) -> Self {
786 #name(<#inner_ty as #import::Float>::signum(self.0))
787 }
788 #[inline]
789 fn is_sign_positive(self) -> bool {
790 <#inner_ty as #import::Float>::is_sign_positive(self.0)
791 }
792 #[inline]
793 fn is_sign_negative(self) -> bool {
794 <#inner_ty as #import::Float>::is_sign_negative(self.0)
795 }
796 #[inline]
797 fn mul_add(self, a: Self, b: Self) -> Self {
798 #name(<#inner_ty as #import::Float>::mul_add(self.0, a.0, b.0))
799 }
800 #[inline]
801 fn recip(self) -> Self {
802 #name(<#inner_ty as #import::Float>::recip(self.0))
803 }
804 #[inline]
805 fn powi(self, n: i32) -> Self {
806 #name(<#inner_ty as #import::Float>::powi(self.0, n))
807 }
808 #[inline]
809 fn powf(self, n: Self) -> Self {
810 #name(<#inner_ty as #import::Float>::powf(self.0, n.0))
811 }
812 #[inline]
813 fn sqrt(self) -> Self {
814 #name(<#inner_ty as #import::Float>::sqrt(self.0))
815 }
816 #[inline]
817 fn exp(self) -> Self {
818 #name(<#inner_ty as #import::Float>::exp(self.0))
819 }
820 #[inline]
821 fn exp2(self) -> Self {
822 #name(<#inner_ty as #import::Float>::exp2(self.0))
823 }
824 #[inline]
825 fn ln(self) -> Self {
826 #name(<#inner_ty as #import::Float>::ln(self.0))
827 }
828 #[inline]
829 fn log(self, base: Self) -> Self {
830 #name(<#inner_ty as #import::Float>::log(self.0, base.0))
831 }
832 #[inline]
833 fn log2(self) -> Self {
834 #name(<#inner_ty as #import::Float>::log2(self.0))
835 }
836 #[inline]
837 fn log10(self) -> Self {
838 #name(<#inner_ty as #import::Float>::log10(self.0))
839 }
840 #[inline]
841 fn max(self, other: Self) -> Self {
842 #name(<#inner_ty as #import::Float>::max(self.0, other.0))
843 }
844 #[inline]
845 fn min(self, other: Self) -> Self {
846 #name(<#inner_ty as #import::Float>::min(self.0, other.0))
847 }
848 #[inline]
849 fn abs_sub(self, other: Self) -> Self {
850 #name(<#inner_ty as #import::Float>::abs_sub(self.0, other.0))
851 }
852 #[inline]
853 fn cbrt(self) -> Self {
854 #name(<#inner_ty as #import::Float>::cbrt(self.0))
855 }
856 #[inline]
857 fn hypot(self, other: Self) -> Self {
858 #name(<#inner_ty as #import::Float>::hypot(self.0, other.0))
859 }
860 #[inline]
861 fn sin(self) -> Self {
862 #name(<#inner_ty as #import::Float>::sin(self.0))
863 }
864 #[inline]
865 fn cos(self) -> Self {
866 #name(<#inner_ty as #import::Float>::cos(self.0))
867 }
868 #[inline]
869 fn tan(self) -> Self {
870 #name(<#inner_ty as #import::Float>::tan(self.0))
871 }
872 #[inline]
873 fn asin(self) -> Self {
874 #name(<#inner_ty as #import::Float>::asin(self.0))
875 }
876 #[inline]
877 fn acos(self) -> Self {
878 #name(<#inner_ty as #import::Float>::acos(self.0))
879 }
880 #[inline]
881 fn atan(self) -> Self {
882 #name(<#inner_ty as #import::Float>::atan(self.0))
883 }
884 #[inline]
885 fn atan2(self, other: Self) -> Self {
886 #name(<#inner_ty as #import::Float>::atan2(self.0, other.0))
887 }
888 #[inline]
889 fn sin_cos(self) -> (Self, Self) {
890 let (x, y) = <#inner_ty as #import::Float>::sin_cos(self.0);
891 (#name(x), #name(y))
892 }
893 #[inline]
894 fn exp_m1(self) -> Self {
895 #name(<#inner_ty as #import::Float>::exp_m1(self.0))
896 }
897 #[inline]
898 fn ln_1p(self) -> Self {
899 #name(<#inner_ty as #import::Float>::ln_1p(self.0))
900 }
901 #[inline]
902 fn sinh(self) -> Self {
903 #name(<#inner_ty as #import::Float>::sinh(self.0))
904 }
905 #[inline]
906 fn cosh(self) -> Self {
907 #name(<#inner_ty as #import::Float>::cosh(self.0))
908 }
909 #[inline]
910 fn tanh(self) -> Self {
911 #name(<#inner_ty as #import::Float>::tanh(self.0))
912 }
913 #[inline]
914 fn asinh(self) -> Self {
915 #name(<#inner_ty as #import::Float>::asinh(self.0))
916 }
917 #[inline]
918 fn acosh(self) -> Self {
919 #name(<#inner_ty as #import::Float>::acosh(self.0))
920 }
921 #[inline]
922 fn atanh(self) -> Self {
923 #name(<#inner_ty as #import::Float>::atanh(self.0))
924 }
925 #[inline]
926 fn integer_decode(self) -> (u64, i16, i8) {
927 <#inner_ty as #import::Float>::integer_decode(self.0)
928 }
929 #[inline]
930 fn epsilon() -> Self {
931 #name(<#inner_ty as #import::Float>::epsilon())
932 }
933 #[inline]
934 fn to_degrees(self) -> Self {
935 #name(<#inner_ty as #import::Float>::to_degrees(self.0))
936 }
937 #[inline]
938 fn to_radians(self) -> Self {
939 #name(<#inner_ty as #import::Float>::to_radians(self.0))
940 }
941 }
942 };
943
944 import.wrap(impl_).into()
945}
946
947#[proc_macro_derive(Signed, attributes(num_traits))]
952pub fn signed(input: TokenStream) -> TokenStream {
953 let ast = parse!(input as syn::DeriveInput);
954 let name = &ast.ident;
955 let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
956
957 let import = NumTraits::new(&ast);
958
959 let impl_ = quote! {
960 impl #import::Signed for #name {
961 #[inline]
962 fn abs(&self) -> Self {
963 #name(<#inner_ty as #import::Signed>::abs(&self.0))
964 }
965 #[inline]
966 fn abs_sub(&self, other: &Self) -> Self {
967 #name(<#inner_ty as #import::Signed>::abs_sub(&self.0, &other.0))
968 }
969 #[inline]
970 fn signum(&self) -> Self {
971 #name(<#inner_ty as #import::Signed>::signum(&self.0))
972 }
973 #[inline]
974 fn is_positive(&self) -> bool {
975 <#inner_ty as #import::Signed>::is_positive(&self.0)
976 }
977 #[inline]
978 fn is_negative(&self) -> bool {
979 <#inner_ty as #import::Signed>::is_negative(&self.0)
980 }
981 }
982 };
983
984 import.wrap(impl_).into()
985}
986
987#[proc_macro_derive(Unsigned, attributes(num_traits))]
992pub fn unsigned(input: TokenStream) -> TokenStream {
993 let ast = parse!(input as syn::DeriveInput);
994 let name = &ast.ident;
995
996 let import = NumTraits::new(&ast);
997
998 let impl_ = quote! {
999 impl #import::Unsigned for #name {}
1000 };
1001
1002 import.wrap(impl_).into()
1003}