1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 
11 #![crate_type = "proc-macro"]
12 #![doc(html_root_url = "https://docs.rs/num-derive/0.3")]
13 #![recursion_limit = "512"]
14 
15 //! Procedural macros to derive numeric traits in Rust.
16 //!
17 //! ## Usage
18 //!
19 //! Add this to your `Cargo.toml`:
20 //!
21 //! ```toml
22 //! [dependencies]
23 //! num-traits = "0.2"
24 //! num-derive = "0.3"
25 //! ```
26 //!
27 //! Then you can derive traits on your own types:
28 //!
29 //! ```rust
30 //! #[macro_use]
31 //! extern crate num_derive;
32 //!
33 //! #[derive(FromPrimitive, ToPrimitive)]
34 //! enum Color {
35 //!     Red,
36 //!     Blue,
37 //!     Green,
38 //! }
39 //! # fn main() {}
40 //! ```
41 //!
42 //! ## Explicit import
43 //!
44 //! By default the `num_derive` procedural macros assume that the
45 //! `num_traits` crate is a direct dependency. If `num_traits` is instead
46 //! a transitive dependency, the `num_traits` helper attribute can be
47 //! used to tell `num_derive` to use a specific identifier for its imports.
48 //!
49 //! ```rust
50 //! #[macro_use]
51 //! extern crate num_derive;
52 //! // Lets pretend this is a transitive dependency from another crate
53 //! // reexported as `some_other_ident`.
54 //! extern crate num_traits as some_other_ident;
55 //!
56 //! #[derive(FromPrimitive, ToPrimitive)]
57 //! #[num_traits = "some_other_ident"]
58 //! enum Color {
59 //!     Red,
60 //!     Blue,
61 //!     Green,
62 //! }
63 //! # fn main() {}
64 //! ```
65 
66 extern crate proc_macro;
67 
68 use proc_macro::TokenStream;
69 use proc_macro2::{Span, TokenStream as TokenStream2};
70 use quote::quote;
71 use syn::{Data, Fields, Ident};
72 
73 /// Try to parse the tokens, or else return a compilation error
74 /// suggesting "full-syntax" if that's not already enabled.
75 macro_rules! parse {
76     ($tokens:ident as $type:ty) => {
77         match syn::parse::<$type>($tokens) {
78             Ok(parsed) => parsed,
79             Err(mut error) => {
80                 if cfg!(not(feature = "full-syntax")) {
81                     let hint = syn::Error::new(
82                         Span::call_site(),
83                         r#"this might need the "full-syntax" feature of `num-derive`"#,
84                     );
85                     error.combine(hint);
86                 }
87                 return TokenStream::from(error.to_compile_error());
88             }
89         }
90     };
91 }
92 
93 // Within `exp`, you can bring things into scope with `extern crate`.
94 //
95 // We don't want to assume that `num_traits::` is in scope - the user may have imported it under a
96 // different name, or may have imported it in a non-toplevel module (common when putting impls
97 // behind a feature gate).
98 //
99 // Solution: let's just generate `extern crate num_traits as _num_traits` and then refer to
100 // `_num_traits` in the derived code.  However, macros are not allowed to produce `extern crate`
101 // statements at the toplevel.
102 //
103 // Solution: let's generate `mod _impl_foo` and import num_traits within that.  However, now we
104 // lose access to private members of the surrounding module.  This is a problem if, for example,
105 // we're deriving for a newtype, where the inner type is defined in the same module, but not
106 // exported.
107 //
108 // Solution: use the dummy const trick.  For some reason, `extern crate` statements are allowed
109 // here, but everything from the surrounding module is in scope.  This trick is taken from serde.
dummy_const_trick(trait_: &str, name: &Ident, exp: TokenStream2) -> TokenStream2110 fn dummy_const_trick(trait_: &str, name: &Ident, exp: TokenStream2) -> TokenStream2 {
111     let dummy_const = Ident::new(
112         &format!("_IMPL_NUM_{}_FOR_{}", trait_, unraw(name)),
113         Span::call_site(),
114     );
115     quote! {
116         #[allow(non_upper_case_globals, unused_qualifications)]
117         const #dummy_const: () = {
118             #[allow(clippy::useless_attribute)]
119             #[allow(rust_2018_idioms)]
120             extern crate num_traits as _num_traits;
121             #exp
122         };
123     }
124 }
125 
unraw(ident: &Ident) -> String126 fn unraw(ident: &Ident) -> String {
127     ident.to_string().trim_start_matches("r#").to_owned()
128 }
129 
130 // If `data` is a newtype, return the type it's wrapping.
newtype_inner(data: &syn::Data) -> Option<syn::Type>131 fn newtype_inner(data: &syn::Data) -> Option<syn::Type> {
132     match *data {
133         Data::Struct(ref s) => {
134             match s.fields {
135                 Fields::Unnamed(ref fs) => {
136                     if fs.unnamed.len() == 1 {
137                         Some(fs.unnamed[0].ty.clone())
138                     } else {
139                         None
140                     }
141                 }
142                 Fields::Named(ref fs) => {
143                     if fs.named.len() == 1 {
144                         panic!("num-derive doesn't know how to handle newtypes with named fields yet. \
145                            Please use a tuple-style newtype, or submit a PR!");
146                     }
147                     None
148                 }
149                 _ => None,
150             }
151         }
152         _ => None,
153     }
154 }
155 
156 struct NumTraits {
157     import: Ident,
158     explicit: bool,
159 }
160 
161 impl quote::ToTokens for NumTraits {
to_tokens(&self, tokens: &mut TokenStream2)162     fn to_tokens(&self, tokens: &mut TokenStream2) {
163         self.import.to_tokens(tokens);
164     }
165 }
166 
167 impl NumTraits {
new(ast: &syn::DeriveInput) -> Self168     fn new(ast: &syn::DeriveInput) -> Self {
169         // If there is a `num_traits` MetaNameValue attribute on the input,
170         // retrieve its value, and use it to create an `Ident` to be used
171         // to import the `num_traits` crate.
172         for attr in &ast.attrs {
173             if attr.path().is_ident("num_traits") {
174                 if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(ref lit_str), .. }) = attr.meta.require_name_value().unwrap().value {
175                   return NumTraits {
176                       import: syn::Ident::new(&lit_str.value(), lit_str.span()),
177                       explicit: true,
178                   }
179                 } else {
180                     panic!("#[num_traits] attribute value must be a str");
181                 }
182             }
183         }
184 
185         // Otherwise, we'll implicitly import our own.
186         NumTraits {
187             import: Ident::new("_num_traits", Span::call_site()),
188             explicit: false,
189         }
190     }
191 
wrap(&self, trait_: &str, name: &Ident, output: TokenStream2) -> TokenStream2192     fn wrap(&self, trait_: &str, name: &Ident, output: TokenStream2) -> TokenStream2 {
193         if self.explicit {
194             output
195         } else {
196             dummy_const_trick(trait_, &name, output)
197         }
198     }
199 }
200 
201 /// Derives [`num_traits::FromPrimitive`][from] for simple enums and newtypes.
202 ///
203 /// [from]: https://docs.rs/num-traits/0.2/num_traits/cast/trait.FromPrimitive.html
204 ///
205 /// # Examples
206 ///
207 /// Simple enums can be derived:
208 ///
209 /// ```rust
210 /// # #[macro_use]
211 /// # extern crate num_derive;
212 ///
213 /// #[derive(FromPrimitive)]
214 /// enum Color {
215 ///     Red,
216 ///     Blue,
217 ///     Green = 42,
218 /// }
219 /// # fn main() {}
220 /// ```
221 ///
222 /// Enums that contain data are not allowed:
223 ///
224 /// ```compile_fail
225 /// # #[macro_use]
226 /// # extern crate num_derive;
227 ///
228 /// #[derive(FromPrimitive)]
229 /// enum Color {
230 ///     Rgb(u8, u8, u8),
231 ///     Hsv(u8, u8, u8),
232 /// }
233 /// # fn main() {}
234 /// ```
235 ///
236 /// Structs are not allowed:
237 ///
238 /// ```compile_fail
239 /// # #[macro_use]
240 /// # extern crate num_derive;
241 /// #[derive(FromPrimitive)]
242 /// struct Color {
243 ///     r: u8,
244 ///     g: u8,
245 ///     b: u8,
246 /// }
247 /// # fn main() {}
248 /// ```
249 #[proc_macro_derive(FromPrimitive, attributes(num_traits))]
from_primitive(input: TokenStream) -> TokenStream250 pub fn from_primitive(input: TokenStream) -> TokenStream {
251     let ast = parse!(input as syn::DeriveInput);
252     let name = &ast.ident;
253 
254     let import = NumTraits::new(&ast);
255 
256     let impl_ = if let Some(inner_ty) = newtype_inner(&ast.data) {
257         quote! {
258             impl #import::FromPrimitive for #name {
259                 #[inline]
260                 fn from_i64(n: i64) -> Option<Self> {
261                     <#inner_ty as #import::FromPrimitive>::from_i64(n).map(#name)
262                 }
263                 #[inline]
264                 fn from_u64(n: u64) -> Option<Self> {
265                     <#inner_ty as #import::FromPrimitive>::from_u64(n).map(#name)
266                 }
267                 #[inline]
268                 fn from_isize(n: isize) -> Option<Self> {
269                     <#inner_ty as #import::FromPrimitive>::from_isize(n).map(#name)
270                 }
271                 #[inline]
272                 fn from_i8(n: i8) -> Option<Self> {
273                     <#inner_ty as #import::FromPrimitive>::from_i8(n).map(#name)
274                 }
275                 #[inline]
276                 fn from_i16(n: i16) -> Option<Self> {
277                     <#inner_ty as #import::FromPrimitive>::from_i16(n).map(#name)
278                 }
279                 #[inline]
280                 fn from_i32(n: i32) -> Option<Self> {
281                     <#inner_ty as #import::FromPrimitive>::from_i32(n).map(#name)
282                 }
283                 #[inline]
284                 fn from_i128(n: i128) -> Option<Self> {
285                     <#inner_ty as #import::FromPrimitive>::from_i128(n).map(#name)
286                 }
287                 #[inline]
288                 fn from_usize(n: usize) -> Option<Self> {
289                     <#inner_ty as #import::FromPrimitive>::from_usize(n).map(#name)
290                 }
291                 #[inline]
292                 fn from_u8(n: u8) -> Option<Self> {
293                     <#inner_ty as #import::FromPrimitive>::from_u8(n).map(#name)
294                 }
295                 #[inline]
296                 fn from_u16(n: u16) -> Option<Self> {
297                     <#inner_ty as #import::FromPrimitive>::from_u16(n).map(#name)
298                 }
299                 #[inline]
300                 fn from_u32(n: u32) -> Option<Self> {
301                     <#inner_ty as #import::FromPrimitive>::from_u32(n).map(#name)
302                 }
303                 #[inline]
304                 fn from_u128(n: u128) -> Option<Self> {
305                     <#inner_ty as #import::FromPrimitive>::from_u128(n).map(#name)
306                 }
307                 #[inline]
308                 fn from_f32(n: f32) -> Option<Self> {
309                     <#inner_ty as #import::FromPrimitive>::from_f32(n).map(#name)
310                 }
311                 #[inline]
312                 fn from_f64(n: f64) -> Option<Self> {
313                     <#inner_ty as #import::FromPrimitive>::from_f64(n).map(#name)
314                 }
315             }
316         }
317     } else {
318         let variants = match ast.data {
319             Data::Enum(ref data_enum) => &data_enum.variants,
320             _ => panic!(
321                 "`FromPrimitive` can be applied only to enums and newtypes, {} is neither",
322                 name
323             ),
324         };
325 
326         let from_i64_var = quote! { n };
327         let clauses: Vec<_> = variants
328             .iter()
329             .map(|variant| {
330                 let ident = &variant.ident;
331                 match variant.fields {
332                     Fields::Unit => (),
333                     _ => panic!(
334                         "`FromPrimitive` can be applied only to unitary enums and newtypes, \
335                          {}::{} is either struct or tuple",
336                         name, ident
337                     ),
338                 }
339 
340                 quote! {
341                     if #from_i64_var == #name::#ident as i64 {
342                         Some(#name::#ident)
343                     }
344                 }
345             })
346             .collect();
347 
348         let from_i64_var = if clauses.is_empty() {
349             quote!(_)
350         } else {
351             from_i64_var
352         };
353 
354         quote! {
355             impl #import::FromPrimitive for #name {
356                 #[allow(trivial_numeric_casts)]
357                 #[inline]
358                 fn from_i64(#from_i64_var: i64) -> Option<Self> {
359                     #(#clauses else)* {
360                         None
361                     }
362                 }
363 
364                 #[inline]
365                 fn from_u64(n: u64) -> Option<Self> {
366                     Self::from_i64(n as i64)
367                 }
368             }
369         }
370     };
371 
372     import.wrap("FromPrimitive", &name, impl_).into()
373 }
374 
375 /// Derives [`num_traits::ToPrimitive`][to] for simple enums and newtypes.
376 ///
377 /// [to]: https://docs.rs/num-traits/0.2/num_traits/cast/trait.ToPrimitive.html
378 ///
379 /// # Examples
380 ///
381 /// Simple enums can be derived:
382 ///
383 /// ```rust
384 /// # #[macro_use]
385 /// # extern crate num_derive;
386 ///
387 /// #[derive(ToPrimitive)]
388 /// enum Color {
389 ///     Red,
390 ///     Blue,
391 ///     Green = 42,
392 /// }
393 /// # fn main() {}
394 /// ```
395 ///
396 /// Enums that contain data are not allowed:
397 ///
398 /// ```compile_fail
399 /// # #[macro_use]
400 /// # extern crate num_derive;
401 ///
402 /// #[derive(ToPrimitive)]
403 /// enum Color {
404 ///     Rgb(u8, u8, u8),
405 ///     Hsv(u8, u8, u8),
406 /// }
407 /// # fn main() {}
408 /// ```
409 ///
410 /// Structs are not allowed:
411 ///
412 /// ```compile_fail
413 /// # #[macro_use]
414 /// # extern crate num_derive;
415 /// #[derive(ToPrimitive)]
416 /// struct Color {
417 ///     r: u8,
418 ///     g: u8,
419 ///     b: u8,
420 /// }
421 /// # fn main() {}
422 /// ```
423 #[proc_macro_derive(ToPrimitive, attributes(num_traits))]
to_primitive(input: TokenStream) -> TokenStream424 pub fn to_primitive(input: TokenStream) -> TokenStream {
425     let ast = parse!(input as syn::DeriveInput);
426     let name = &ast.ident;
427 
428     let import = NumTraits::new(&ast);
429 
430     let impl_ = if let Some(inner_ty) = newtype_inner(&ast.data) {
431         quote! {
432             impl #import::ToPrimitive for #name {
433                 #[inline]
434                 fn to_i64(&self) -> Option<i64> {
435                     <#inner_ty as #import::ToPrimitive>::to_i64(&self.0)
436                 }
437                 #[inline]
438                 fn to_u64(&self) -> Option<u64> {
439                     <#inner_ty as #import::ToPrimitive>::to_u64(&self.0)
440                 }
441                 #[inline]
442                 fn to_isize(&self) -> Option<isize> {
443                     <#inner_ty as #import::ToPrimitive>::to_isize(&self.0)
444                 }
445                 #[inline]
446                 fn to_i8(&self) -> Option<i8> {
447                     <#inner_ty as #import::ToPrimitive>::to_i8(&self.0)
448                 }
449                 #[inline]
450                 fn to_i16(&self) -> Option<i16> {
451                     <#inner_ty as #import::ToPrimitive>::to_i16(&self.0)
452                 }
453                 #[inline]
454                 fn to_i32(&self) -> Option<i32> {
455                     <#inner_ty as #import::ToPrimitive>::to_i32(&self.0)
456                 }
457                 #[inline]
458                 fn to_i128(&self) -> Option<i128> {
459                     <#inner_ty as #import::ToPrimitive>::to_i128(&self.0)
460                 }
461                 #[inline]
462                 fn to_usize(&self) -> Option<usize> {
463                     <#inner_ty as #import::ToPrimitive>::to_usize(&self.0)
464                 }
465                 #[inline]
466                 fn to_u8(&self) -> Option<u8> {
467                     <#inner_ty as #import::ToPrimitive>::to_u8(&self.0)
468                 }
469                 #[inline]
470                 fn to_u16(&self) -> Option<u16> {
471                     <#inner_ty as #import::ToPrimitive>::to_u16(&self.0)
472                 }
473                 #[inline]
474                 fn to_u32(&self) -> Option<u32> {
475                     <#inner_ty as #import::ToPrimitive>::to_u32(&self.0)
476                 }
477                 #[inline]
478                 fn to_u128(&self) -> Option<u128> {
479                     <#inner_ty as #import::ToPrimitive>::to_u128(&self.0)
480                 }
481                 #[inline]
482                 fn to_f32(&self) -> Option<f32> {
483                     <#inner_ty as #import::ToPrimitive>::to_f32(&self.0)
484                 }
485                 #[inline]
486                 fn to_f64(&self) -> Option<f64> {
487                     <#inner_ty as #import::ToPrimitive>::to_f64(&self.0)
488                 }
489             }
490         }
491     } else {
492         let variants = match ast.data {
493             Data::Enum(ref data_enum) => &data_enum.variants,
494             _ => panic!(
495                 "`ToPrimitive` can be applied only to enums and newtypes, {} is neither",
496                 name
497             ),
498         };
499 
500         let variants: Vec<_> = variants
501             .iter()
502             .map(|variant| {
503                 let ident = &variant.ident;
504                 match variant.fields {
505                     Fields::Unit => (),
506                     _ => {
507                         panic!("`ToPrimitive` can be applied only to unitary enums and newtypes, {}::{} is either struct or tuple", name, ident)
508                     },
509                 }
510 
511                 // NB: We have to check each variant individually, because we'll only have `&self`
512                 // for the input.  We can't move from that, and it might not be `Clone` or `Copy`.
513                 // (Otherwise we could just do `*self as i64` without a `match` at all.)
514                 quote!(#name::#ident => #name::#ident as i64)
515             })
516             .collect();
517 
518         let match_expr = if variants.is_empty() {
519             // No variants found, so do not use Some to not to trigger `unreachable_code` lint
520             quote! {
521                 match *self {}
522             }
523         } else {
524             quote! {
525                 Some(match *self {
526                     #(#variants,)*
527                 })
528             }
529         };
530 
531         quote! {
532             impl #import::ToPrimitive for #name {
533                 #[inline]
534                 #[allow(trivial_numeric_casts)]
535                 fn to_i64(&self) -> Option<i64> {
536                     #match_expr
537                 }
538 
539                 #[inline]
540                 fn to_u64(&self) -> Option<u64> {
541                     self.to_i64().map(|x| x as u64)
542                 }
543             }
544         }
545     };
546 
547     import.wrap("ToPrimitive", &name, impl_).into()
548 }
549 
550 const NEWTYPE_ONLY: &str = "This trait can only be derived for newtypes";
551 
552 /// Derives [`num_traits::NumOps`][num_ops] for newtypes.  The inner type must already implement
553 /// `NumOps`.
554 ///
555 /// [num_ops]: https://docs.rs/num-traits/0.2/num_traits/trait.NumOps.html
556 ///
557 /// Note that, since `NumOps` is really a trait alias for `Add + Sub + Mul + Div + Rem`, this macro
558 /// generates impls for _those_ traits.  Furthermore, in all generated impls, `RHS=Self` and
559 /// `Output=Self`.
560 #[proc_macro_derive(NumOps)]
num_ops(input: TokenStream) -> TokenStream561 pub fn num_ops(input: TokenStream) -> TokenStream {
562     let ast = parse!(input as syn::DeriveInput);
563     let name = &ast.ident;
564     let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
565     let impl_ = quote! {
566         impl ::core::ops::Add for #name {
567             type Output = Self;
568             #[inline]
569             fn add(self, other: Self) -> Self {
570                 #name(<#inner_ty as ::core::ops::Add>::add(self.0, other.0))
571             }
572         }
573         impl ::core::ops::Sub for #name {
574             type Output = Self;
575             #[inline]
576             fn sub(self, other: Self) -> Self {
577                 #name(<#inner_ty as ::core::ops::Sub>::sub(self.0, other.0))
578             }
579         }
580         impl ::core::ops::Mul for #name {
581             type Output = Self;
582             #[inline]
583             fn mul(self, other: Self) -> Self {
584                 #name(<#inner_ty as ::core::ops::Mul>::mul(self.0, other.0))
585             }
586         }
587         impl ::core::ops::Div for #name {
588             type Output = Self;
589             #[inline]
590             fn div(self, other: Self) -> Self {
591                 #name(<#inner_ty as ::core::ops::Div>::div(self.0, other.0))
592             }
593         }
594         impl ::core::ops::Rem for #name {
595             type Output = Self;
596             #[inline]
597             fn rem(self, other: Self) -> Self {
598                 #name(<#inner_ty as ::core::ops::Rem>::rem(self.0, other.0))
599             }
600         }
601     };
602     impl_.into()
603 }
604 
605 /// Derives [`num_traits::NumCast`][num_cast] for newtypes.  The inner type must already implement
606 /// `NumCast`.
607 ///
608 /// [num_cast]: https://docs.rs/num-traits/0.2/num_traits/cast/trait.NumCast.html
609 #[proc_macro_derive(NumCast, attributes(num_traits))]
num_cast(input: TokenStream) -> TokenStream610 pub fn num_cast(input: TokenStream) -> TokenStream {
611     let ast = parse!(input as syn::DeriveInput);
612     let name = &ast.ident;
613     let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
614 
615     let import = NumTraits::new(&ast);
616 
617     let impl_ = quote! {
618         impl #import::NumCast for #name {
619             #[inline]
620             fn from<T: #import::ToPrimitive>(n: T) -> Option<Self> {
621                 <#inner_ty as #import::NumCast>::from(n).map(#name)
622             }
623         }
624     };
625 
626     import.wrap("NumCast", &name, impl_).into()
627 }
628 
629 /// Derives [`num_traits::Zero`][zero] for newtypes.  The inner type must already implement `Zero`.
630 ///
631 /// [zero]: https://docs.rs/num-traits/0.2/num_traits/identities/trait.Zero.html
632 #[proc_macro_derive(Zero, attributes(num_traits))]
zero(input: TokenStream) -> TokenStream633 pub fn zero(input: TokenStream) -> TokenStream {
634     let ast = parse!(input as syn::DeriveInput);
635     let name = &ast.ident;
636     let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
637 
638     let import = NumTraits::new(&ast);
639 
640     let impl_ = quote! {
641         impl #import::Zero for #name {
642             #[inline]
643             fn zero() -> Self {
644                 #name(<#inner_ty as #import::Zero>::zero())
645             }
646             #[inline]
647             fn is_zero(&self) -> bool {
648                 <#inner_ty as #import::Zero>::is_zero(&self.0)
649             }
650         }
651     };
652 
653     import.wrap("Zero", &name, impl_).into()
654 }
655 
656 /// Derives [`num_traits::One`][one] for newtypes.  The inner type must already implement `One`.
657 ///
658 /// [one]: https://docs.rs/num-traits/0.2/num_traits/identities/trait.One.html
659 #[proc_macro_derive(One, attributes(num_traits))]
one(input: TokenStream) -> TokenStream660 pub fn one(input: TokenStream) -> TokenStream {
661     let ast = parse!(input as syn::DeriveInput);
662     let name = &ast.ident;
663     let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
664 
665     let import = NumTraits::new(&ast);
666 
667     let impl_ = quote! {
668         impl #import::One for #name {
669             #[inline]
670             fn one() -> Self {
671                 #name(<#inner_ty as #import::One>::one())
672             }
673             #[inline]
674             fn is_one(&self) -> bool {
675                 <#inner_ty as #import::One>::is_one(&self.0)
676             }
677         }
678     };
679 
680     import.wrap("One", &name, impl_).into()
681 }
682 
683 /// Derives [`num_traits::Num`][num] for newtypes.  The inner type must already implement `Num`.
684 ///
685 /// [num]: https://docs.rs/num-traits/0.2/num_traits/trait.Num.html
686 #[proc_macro_derive(Num, attributes(num_traits))]
num(input: TokenStream) -> TokenStream687 pub fn num(input: TokenStream) -> TokenStream {
688     let ast = parse!(input as syn::DeriveInput);
689     let name = &ast.ident;
690     let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
691 
692     let import = NumTraits::new(&ast);
693 
694     let impl_ = quote! {
695         impl #import::Num for #name {
696             type FromStrRadixErr = <#inner_ty as #import::Num>::FromStrRadixErr;
697             #[inline]
698             fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
699                 <#inner_ty as #import::Num>::from_str_radix(s, radix).map(#name)
700             }
701         }
702     };
703 
704     import.wrap("Num", &name, impl_).into()
705 }
706 
707 /// Derives [`num_traits::Float`][float] for newtypes.  The inner type must already implement
708 /// `Float`.
709 ///
710 /// [float]: https://docs.rs/num-traits/0.2/num_traits/float/trait.Float.html
711 #[proc_macro_derive(Float, attributes(num_traits))]
float(input: TokenStream) -> TokenStream712 pub fn float(input: TokenStream) -> TokenStream {
713     let ast = parse!(input as syn::DeriveInput);
714     let name = &ast.ident;
715     let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
716 
717     let import = NumTraits::new(&ast);
718 
719     let impl_ = quote! {
720         impl #import::Float for #name {
721             #[inline]
722             fn nan() -> Self {
723                 #name(<#inner_ty as #import::Float>::nan())
724             }
725             #[inline]
726             fn infinity() -> Self {
727                 #name(<#inner_ty as #import::Float>::infinity())
728             }
729             #[inline]
730             fn neg_infinity() -> Self {
731                 #name(<#inner_ty as #import::Float>::neg_infinity())
732             }
733             #[inline]
734             fn neg_zero() -> Self {
735                 #name(<#inner_ty as #import::Float>::neg_zero())
736             }
737             #[inline]
738             fn min_value() -> Self {
739                 #name(<#inner_ty as #import::Float>::min_value())
740             }
741             #[inline]
742             fn min_positive_value() -> Self {
743                 #name(<#inner_ty as #import::Float>::min_positive_value())
744             }
745             #[inline]
746             fn max_value() -> Self {
747                 #name(<#inner_ty as #import::Float>::max_value())
748             }
749             #[inline]
750             fn is_nan(self) -> bool {
751                 <#inner_ty as #import::Float>::is_nan(self.0)
752             }
753             #[inline]
754             fn is_infinite(self) -> bool {
755                 <#inner_ty as #import::Float>::is_infinite(self.0)
756             }
757             #[inline]
758             fn is_finite(self) -> bool {
759                 <#inner_ty as #import::Float>::is_finite(self.0)
760             }
761             #[inline]
762             fn is_normal(self) -> bool {
763                 <#inner_ty as #import::Float>::is_normal(self.0)
764             }
765             #[inline]
766             fn classify(self) -> ::std::num::FpCategory {
767                 <#inner_ty as #import::Float>::classify(self.0)
768             }
769             #[inline]
770             fn floor(self) -> Self {
771                 #name(<#inner_ty as #import::Float>::floor(self.0))
772             }
773             #[inline]
774             fn ceil(self) -> Self {
775                 #name(<#inner_ty as #import::Float>::ceil(self.0))
776             }
777             #[inline]
778             fn round(self) -> Self {
779                 #name(<#inner_ty as #import::Float>::round(self.0))
780             }
781             #[inline]
782             fn trunc(self) -> Self {
783                 #name(<#inner_ty as #import::Float>::trunc(self.0))
784             }
785             #[inline]
786             fn fract(self) -> Self {
787                 #name(<#inner_ty as #import::Float>::fract(self.0))
788             }
789             #[inline]
790             fn abs(self) -> Self {
791                 #name(<#inner_ty as #import::Float>::abs(self.0))
792             }
793             #[inline]
794             fn signum(self) -> Self {
795                 #name(<#inner_ty as #import::Float>::signum(self.0))
796             }
797             #[inline]
798             fn is_sign_positive(self) -> bool {
799                 <#inner_ty as #import::Float>::is_sign_positive(self.0)
800             }
801             #[inline]
802             fn is_sign_negative(self) -> bool {
803                 <#inner_ty as #import::Float>::is_sign_negative(self.0)
804             }
805             #[inline]
806             fn mul_add(self, a: Self, b: Self) -> Self {
807                 #name(<#inner_ty as #import::Float>::mul_add(self.0, a.0, b.0))
808             }
809             #[inline]
810             fn recip(self) -> Self {
811                 #name(<#inner_ty as #import::Float>::recip(self.0))
812             }
813             #[inline]
814             fn powi(self, n: i32) -> Self {
815                 #name(<#inner_ty as #import::Float>::powi(self.0, n))
816             }
817             #[inline]
818             fn powf(self, n: Self) -> Self {
819                 #name(<#inner_ty as #import::Float>::powf(self.0, n.0))
820             }
821             #[inline]
822             fn sqrt(self) -> Self {
823                 #name(<#inner_ty as #import::Float>::sqrt(self.0))
824             }
825             #[inline]
826             fn exp(self) -> Self {
827                 #name(<#inner_ty as #import::Float>::exp(self.0))
828             }
829             #[inline]
830             fn exp2(self) -> Self {
831                 #name(<#inner_ty as #import::Float>::exp2(self.0))
832             }
833             #[inline]
834             fn ln(self) -> Self {
835                 #name(<#inner_ty as #import::Float>::ln(self.0))
836             }
837             #[inline]
838             fn log(self, base: Self) -> Self {
839                 #name(<#inner_ty as #import::Float>::log(self.0, base.0))
840             }
841             #[inline]
842             fn log2(self) -> Self {
843                 #name(<#inner_ty as #import::Float>::log2(self.0))
844             }
845             #[inline]
846             fn log10(self) -> Self {
847                 #name(<#inner_ty as #import::Float>::log10(self.0))
848             }
849             #[inline]
850             fn max(self, other: Self) -> Self {
851                 #name(<#inner_ty as #import::Float>::max(self.0, other.0))
852             }
853             #[inline]
854             fn min(self, other: Self) -> Self {
855                 #name(<#inner_ty as #import::Float>::min(self.0, other.0))
856             }
857             #[inline]
858             fn abs_sub(self, other: Self) -> Self {
859                 #name(<#inner_ty as #import::Float>::abs_sub(self.0, other.0))
860             }
861             #[inline]
862             fn cbrt(self) -> Self {
863                 #name(<#inner_ty as #import::Float>::cbrt(self.0))
864             }
865             #[inline]
866             fn hypot(self, other: Self) -> Self {
867                 #name(<#inner_ty as #import::Float>::hypot(self.0, other.0))
868             }
869             #[inline]
870             fn sin(self) -> Self {
871                 #name(<#inner_ty as #import::Float>::sin(self.0))
872             }
873             #[inline]
874             fn cos(self) -> Self {
875                 #name(<#inner_ty as #import::Float>::cos(self.0))
876             }
877             #[inline]
878             fn tan(self) -> Self {
879                 #name(<#inner_ty as #import::Float>::tan(self.0))
880             }
881             #[inline]
882             fn asin(self) -> Self {
883                 #name(<#inner_ty as #import::Float>::asin(self.0))
884             }
885             #[inline]
886             fn acos(self) -> Self {
887                 #name(<#inner_ty as #import::Float>::acos(self.0))
888             }
889             #[inline]
890             fn atan(self) -> Self {
891                 #name(<#inner_ty as #import::Float>::atan(self.0))
892             }
893             #[inline]
894             fn atan2(self, other: Self) -> Self {
895                 #name(<#inner_ty as #import::Float>::atan2(self.0, other.0))
896             }
897             #[inline]
898             fn sin_cos(self) -> (Self, Self) {
899                 let (x, y) = <#inner_ty as #import::Float>::sin_cos(self.0);
900                 (#name(x), #name(y))
901             }
902             #[inline]
903             fn exp_m1(self) -> Self {
904                 #name(<#inner_ty as #import::Float>::exp_m1(self.0))
905             }
906             #[inline]
907             fn ln_1p(self) -> Self {
908                 #name(<#inner_ty as #import::Float>::ln_1p(self.0))
909             }
910             #[inline]
911             fn sinh(self) -> Self {
912                 #name(<#inner_ty as #import::Float>::sinh(self.0))
913             }
914             #[inline]
915             fn cosh(self) -> Self {
916                 #name(<#inner_ty as #import::Float>::cosh(self.0))
917             }
918             #[inline]
919             fn tanh(self) -> Self {
920                 #name(<#inner_ty as #import::Float>::tanh(self.0))
921             }
922             #[inline]
923             fn asinh(self) -> Self {
924                 #name(<#inner_ty as #import::Float>::asinh(self.0))
925             }
926             #[inline]
927             fn acosh(self) -> Self {
928                 #name(<#inner_ty as #import::Float>::acosh(self.0))
929             }
930             #[inline]
931             fn atanh(self) -> Self {
932                 #name(<#inner_ty as #import::Float>::atanh(self.0))
933             }
934             #[inline]
935             fn integer_decode(self) -> (u64, i16, i8) {
936                 <#inner_ty as #import::Float>::integer_decode(self.0)
937             }
938             #[inline]
939             fn epsilon() -> Self {
940                 #name(<#inner_ty as #import::Float>::epsilon())
941             }
942             #[inline]
943             fn to_degrees(self) -> Self {
944                 #name(<#inner_ty as #import::Float>::to_degrees(self.0))
945             }
946             #[inline]
947             fn to_radians(self) -> Self {
948                 #name(<#inner_ty as #import::Float>::to_radians(self.0))
949             }
950         }
951     };
952 
953     import.wrap("Float", &name, impl_).into()
954 }
955