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