summaryrefslogtreecommitdiffstats
path: root/third_party/rust/num-derive
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/num-derive')
-rw-r--r--third_party/rust/num-derive/.cargo-checksum.json1
-rw-r--r--third_party/rust/num-derive/Cargo.toml55
-rw-r--r--third_party/rust/num-derive/LICENSE-APACHE201
-rw-r--r--third_party/rust/num-derive/LICENSE-MIT25
-rw-r--r--third_party/rust/num-derive/README.md69
-rw-r--r--third_party/rust/num-derive/RELEASES.md105
-rw-r--r--third_party/rust/num-derive/src/lib.rs958
-rw-r--r--third_party/rust/num-derive/src/test.rs31
-rw-r--r--third_party/rust/num-derive/tests/empty_enum.rs23
-rw-r--r--third_party/rust/num-derive/tests/issue-6.rs17
-rw-r--r--third_party/rust/num-derive/tests/issue-9.rs18
-rw-r--r--third_party/rust/num-derive/tests/newtype-2015.rs2
-rw-r--r--third_party/rust/num-derive/tests/newtype.rs89
-rw-r--r--third_party/rust/num-derive/tests/num_derive_without_num.rs20
-rw-r--r--third_party/rust/num-derive/tests/trivial-2015.rs2
-rw-r--r--third_party/rust/num-derive/tests/trivial.rs64
-rw-r--r--third_party/rust/num-derive/tests/with_custom_values.rs70
17 files changed, 1750 insertions, 0 deletions
diff --git a/third_party/rust/num-derive/.cargo-checksum.json b/third_party/rust/num-derive/.cargo-checksum.json
new file mode 100644
index 0000000000..fe87985b3c
--- /dev/null
+++ b/third_party/rust/num-derive/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"aeffa6070dd5f4311b70d4baf3723f48c58bf5895a529ddd3f2548042ecedce8","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"d772e283044982c8d132220666f831a2add33d2d891aee4faf61d6b1c8b81b6c","RELEASES.md":"a9031e1846496d2c19baea11378d038fc4c4789e224365c20f8e4f783a45fb23","src/lib.rs":"e0e97564d9e1ddb6bb70bc5e2a5b3825dbbfe689dacedd019d5e77cde8c56693","src/test.rs":"59cd2e3ab76bf4c4adae9bf9fe49d8c1f9e98d35f7c8ca47c8199b117bb13b22","tests/empty_enum.rs":"1b2312ec2fc9866fce7172e71e0aa2efcc3cb9d7659d0b633eb352bb1e080d53","tests/issue-6.rs":"b7fbbe86ff82933c15ec09fabadca02d2c70e184af30b9887cae83ed2f60367e","tests/issue-9.rs":"4c87f70a63e56c24480028fafa39a845d127620141df21bc0abfa23f84ff9bb7","tests/newtype-2015.rs":"163f76f0c139c3621ba7416cec5f9fb966c86c5ebed270df77196cf75d62402f","tests/newtype.rs":"bc1ff3fb3680935c2280cc91441c91ea104be24f525428987b49b86bc880217a","tests/num_derive_without_num.rs":"3ce528221a2cb752859e20c5423c4b474fec714b41d8c1b62f5614b165d7262b","tests/trivial-2015.rs":"1745e23dfafb8c717365e57d79323c61c7d4ceaa092d7399ed793fd4f2de8ff6","tests/trivial.rs":"a6b0faab04527f6835f43cd72317a00065a7a6cf4c506d04e77f898134f7a59b","tests/with_custom_values.rs":"9f15c4b732050a5498a9691c2b41902bd9172f0c7c5d3af152ea9bd4a272e885"},"package":"876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"} \ No newline at end of file
diff --git a/third_party/rust/num-derive/Cargo.toml b/third_party/rust/num-derive/Cargo.toml
new file mode 100644
index 0000000000..90c5d27238
--- /dev/null
+++ b/third_party/rust/num-derive/Cargo.toml
@@ -0,0 +1,55 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "num-derive"
+version = "0.3.3"
+authors = ["The Rust Project Developers"]
+exclude = ["/bors.toml", "/ci/*", "/.github/*"]
+description = "Numeric syntax extensions"
+homepage = "https://github.com/rust-num/num-derive"
+documentation = "https://docs.rs/num-derive"
+readme = "README.md"
+keywords = ["mathematics", "numerics"]
+categories = ["science"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/rust-num/num-derive"
+
+[lib]
+name = "num_derive"
+test = false
+proc-macro = true
+
+[[test]]
+name = "newtype-2015"
+edition = "2015"
+
+[[test]]
+name = "trivial-2015"
+edition = "2015"
+[dependencies.proc-macro2]
+version = "1"
+
+[dependencies.quote]
+version = "1"
+
+[dependencies.syn]
+version = "1"
+[dev-dependencies.num]
+version = "0.3"
+
+[dev-dependencies.num-traits]
+version = "0.2"
+
+[features]
+full-syntax = ["syn/full"]
diff --git a/third_party/rust/num-derive/LICENSE-APACHE b/third_party/rust/num-derive/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/num-derive/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/third_party/rust/num-derive/LICENSE-MIT b/third_party/rust/num-derive/LICENSE-MIT
new file mode 100644
index 0000000000..39d4bdb5ac
--- /dev/null
+++ b/third_party/rust/num-derive/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2014 The Rust Project Developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/third_party/rust/num-derive/README.md b/third_party/rust/num-derive/README.md
new file mode 100644
index 0000000000..9826cdfc76
--- /dev/null
+++ b/third_party/rust/num-derive/README.md
@@ -0,0 +1,69 @@
+# num-derive
+
+[![crate](https://img.shields.io/crates/v/num-derive.svg)](https://crates.io/crates/num-derive)
+[![documentation](https://docs.rs/num-derive/badge.svg)](https://docs.rs/num-derive)
+[![minimum rustc 1.31](https://img.shields.io/badge/rustc-1.31+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
+[![build status](https://github.com/rust-num/num-derive/workflows/master/badge.svg)](https://github.com/rust-num/num-derive/actions)
+
+Procedural macros to derive numeric traits in Rust.
+
+## Usage
+
+Add this to your `Cargo.toml`:
+
+```toml
+[dependencies]
+num-traits = "0.2"
+num-derive = "0.3"
+```
+
+and this to your crate root:
+
+```rust
+#[macro_use]
+extern crate num_derive;
+```
+
+Then you can derive traits on your own types:
+
+```rust
+#[derive(FromPrimitive, ToPrimitive)]
+enum Color {
+ Red,
+ Blue,
+ Green,
+}
+```
+
+## Optional features
+
+- **`full-syntax`** — Enables `num-derive` to handle enum discriminants
+ represented by complex expressions. Usually can be avoided by
+ [utilizing constants], so only use this feature if namespace pollution is
+ undesired and [compile time doubling] is acceptable.
+
+[utilizing constants]: https://github.com/rust-num/num-derive/pull/3#issuecomment-359044704
+[compile time doubling]: https://github.com/rust-num/num-derive/pull/3#issuecomment-359172588
+
+## Releases
+
+Release notes are available in [RELEASES.md](RELEASES.md).
+
+## Compatibility
+
+The `num-derive` crate is tested for rustc 1.31 and greater.
+
+## License
+
+Licensed under either of
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
diff --git a/third_party/rust/num-derive/RELEASES.md b/third_party/rust/num-derive/RELEASES.md
new file mode 100644
index 0000000000..c3e18cca00
--- /dev/null
+++ b/third_party/rust/num-derive/RELEASES.md
@@ -0,0 +1,105 @@
+# Release 0.3.3 (2020-10-29)
+
+- [Make `NumOps` work with `no_std`][41] -- thanks @jedrzejboczar!
+
+[41]: https://github.com/rust-num/num-derive/pull/41
+
+# Release 0.3.2 (2020-08-24)
+
+- [Add `#[inline]` to all derived functions][40] -- thanks @Amanieu!
+
+[40]: https://github.com/rust-num/num-derive/pull/40
+
+# Release 0.3.1 (2020-07-28)
+
+- [Add `num_traits` proc_macro helper for explicit import][35] - thanks @jean-airoldie!
+- [Provide nicer parse errors and suggest "full-syntax"][39]
+
+[35]: https://github.com/rust-num/num-derive/pull/35
+[39]: https://github.com/rust-num/num-derive/pull/39
+
+# Release 0.3.0 (2019-09-27)
+
+- [Updated the `proc-macro2`, `quote`, and `syn` dependencies to 1.0][28],
+ which raises the minimum supported rustc to 1.31.
+
+[28]: https://github.com/rust-num/num-derive/pull/28
+
+# Release 0.2.5 (2019-04-23)
+
+- [Improved the masking of lints in derived code][23].
+
+[23]: https://github.com/rust-num/num-derive/pull/23
+
+# Release 0.2.4 (2019-01-25)
+
+- [Adjusted dependencies to allow no-std targets][22].
+
+[22]: https://github.com/rust-num/num-derive/pull/22
+
+# Release 0.2.3 (2018-10-03)
+
+- [Added newtype deriving][17] for `FromPrimitive`, `ToPrimitive`,
+ `NumOps<Self, Self>`, `NumCast`, `Zero`, `One`, `Num`, and `Float`.
+ Thanks @asayers!
+
+[17]: https://github.com/rust-num/num-derive/pull/17
+
+# Release 0.2.2 (2018-05-22)
+
+- [Updated dependencies][14].
+
+[14]: https://github.com/rust-num/num-derive/pull/14
+
+# Release 0.2.1 (2018-05-09)
+
+- [Updated dependencies][12] -- thanks @spearman!
+
+[12]: https://github.com/rust-num/num-derive/pull/12
+
+# Release 0.2.0 (2018-02-21)
+
+- [Discriminant matching is now simplified][10], casting values directly by
+ name, rather than trying to compute offsets from known values manually.
+- **breaking change**: [Derivations now import the traits from `num-traits`][11]
+ instead of the full `num` crate. These are still compatible, but users need
+ to have an explicit `num-traits = "0.2"` dependency in their `Cargo.toml`.
+
+[10]: https://github.com/rust-num/num-derive/pull/10
+[11]: https://github.com/rust-num/num-derive/pull/11
+
+
+# Release 0.1.44 (2018-01-26)
+
+- [The derived code now explicitly allows `unused_qualifications`][9], so users
+ that globally deny that lint don't encounter an error.
+
+[9]: https://github.com/rust-num/num-derive/pull/9
+
+
+# Release 0.1.43 (2018-01-23)
+
+- [The derived code now explicitly allows `trivial_numeric_casts`][7], so users
+ that globally deny that lint don't encounter an error.
+
+[7]: https://github.com/rust-num/num-derive/pull/7
+
+
+# Release 0.1.42 (2018-01-22)
+
+- [num-derive now has its own source repository][num-356] at [rust-num/num-derive][home].
+- [The derivation macros have been updated][3] to using `syn` 0.12. Support for complex
+ expressions in enum values can be enabled with the `full-syntax` feature.
+
+Thanks to @cuviper and @hcpl for their contributions!
+
+[home]: https://github.com/rust-num/num-derive
+[num-356]: https://github.com/rust-num/num/pull/356
+[3]: https://github.com/rust-num/num-derive/pull/3
+
+
+# Prior releases
+
+No prior release notes were kept. Thanks all the same to the many
+contributors that have made this crate what it is!
+
diff --git a/third_party/rust/num-derive/src/lib.rs b/third_party/rust/num-derive/src/lib.rs
new file mode 100644
index 0000000000..ef55e4b0df
--- /dev/null
+++ b/third_party/rust/num-derive/src/lib.rs
@@ -0,0 +1,958 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "proc-macro"]
+#![doc(html_root_url = "https://docs.rs/num-derive/0.3")]
+#![recursion_limit = "512"]
+
+//! Procedural macros to derive numeric traits in Rust.
+//!
+//! ## Usage
+//!
+//! Add this to your `Cargo.toml`:
+//!
+//! ```toml
+//! [dependencies]
+//! num-traits = "0.2"
+//! num-derive = "0.3"
+//! ```
+//!
+//! Then you can derive traits on your own types:
+//!
+//! ```rust
+//! #[macro_use]
+//! extern crate num_derive;
+//!
+//! #[derive(FromPrimitive, ToPrimitive)]
+//! enum Color {
+//! Red,
+//! Blue,
+//! Green,
+//! }
+//! # fn main() {}
+//! ```
+//!
+//! ## Explicit import
+//!
+//! By default the `num_derive` procedural macros assume that the
+//! `num_traits` crate is a direct dependency. If `num_traits` is instead
+//! a transitive dependency, the `num_traits` helper attribute can be
+//! used to tell `num_derive` to use a specific identifier for its imports.
+//!
+//! ```rust
+//! #[macro_use]
+//! extern crate num_derive;
+//! // Lets pretend this is a transitive dependency from another crate
+//! // reexported as `some_other_ident`.
+//! extern crate num_traits as some_other_ident;
+//!
+//! #[derive(FromPrimitive, ToPrimitive)]
+//! #[num_traits = "some_other_ident"]
+//! enum Color {
+//! Red,
+//! Blue,
+//! Green,
+//! }
+//! # fn main() {}
+//! ```
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use proc_macro2::{Span, TokenStream as TokenStream2};
+use quote::quote;
+use syn::{Data, Fields, Ident};
+
+/// Try to parse the tokens, or else return a compilation error
+/// suggesting "full-syntax" if that's not already enabled.
+macro_rules! parse {
+ ($tokens:ident as $type:ty) => {
+ match syn::parse::<$type>($tokens) {
+ Ok(parsed) => parsed,
+ Err(mut error) => {
+ if cfg!(not(feature = "full-syntax")) {
+ let hint = syn::Error::new(
+ Span::call_site(),
+ r#"this might need the "full-syntax" feature of `num-derive`"#,
+ );
+ error.combine(hint);
+ }
+ return TokenStream::from(error.to_compile_error());
+ }
+ }
+ };
+}
+
+// Within `exp`, you can bring things into scope with `extern crate`.
+//
+// We don't want to assume that `num_traits::` is in scope - the user may have imported it under a
+// different name, or may have imported it in a non-toplevel module (common when putting impls
+// behind a feature gate).
+//
+// Solution: let's just generate `extern crate num_traits as _num_traits` and then refer to
+// `_num_traits` in the derived code. However, macros are not allowed to produce `extern crate`
+// statements at the toplevel.
+//
+// Solution: let's generate `mod _impl_foo` and import num_traits within that. However, now we
+// lose access to private members of the surrounding module. This is a problem if, for example,
+// we're deriving for a newtype, where the inner type is defined in the same module, but not
+// exported.
+//
+// Solution: use the dummy const trick. For some reason, `extern crate` statements are allowed
+// here, but everything from the surrounding module is in scope. This trick is taken from serde.
+fn dummy_const_trick(trait_: &str, name: &Ident, exp: TokenStream2) -> TokenStream2 {
+ let dummy_const = Ident::new(
+ &format!("_IMPL_NUM_{}_FOR_{}", trait_, unraw(name)),
+ Span::call_site(),
+ );
+ quote! {
+ #[allow(non_upper_case_globals, unused_qualifications)]
+ const #dummy_const: () = {
+ #[allow(clippy::useless_attribute)]
+ #[allow(rust_2018_idioms)]
+ extern crate num_traits as _num_traits;
+ #exp
+ };
+ }
+}
+
+fn unraw(ident: &Ident) -> String {
+ ident.to_string().trim_start_matches("r#").to_owned()
+}
+
+// If `data` is a newtype, return the type it's wrapping.
+fn newtype_inner(data: &syn::Data) -> Option<syn::Type> {
+ match *data {
+ Data::Struct(ref s) => {
+ match s.fields {
+ Fields::Unnamed(ref fs) => {
+ if fs.unnamed.len() == 1 {
+ Some(fs.unnamed[0].ty.clone())
+ } else {
+ None
+ }
+ }
+ Fields::Named(ref fs) => {
+ if fs.named.len() == 1 {
+ panic!("num-derive doesn't know how to handle newtypes with named fields yet. \
+ Please use a tuple-style newtype, or submit a PR!");
+ }
+ None
+ }
+ _ => None,
+ }
+ }
+ _ => None,
+ }
+}
+
+struct NumTraits {
+ import: Ident,
+ explicit: bool,
+}
+
+impl quote::ToTokens for NumTraits {
+ fn to_tokens(&self, tokens: &mut TokenStream2) {
+ self.import.to_tokens(tokens);
+ }
+}
+
+impl NumTraits {
+ fn new(ast: &syn::DeriveInput) -> Self {
+ // If there is a `num_traits` MetaNameValue attribute on the input,
+ // retrieve its value, and use it to create an `Ident` to be used
+ // to import the `num_traits` crate.
+ for attr in &ast.attrs {
+ if let Ok(syn::Meta::NameValue(mnv)) = attr.parse_meta() {
+ if mnv.path.is_ident("num_traits") {
+ if let syn::Lit::Str(lit_str) = mnv.lit {
+ return NumTraits {
+ import: syn::Ident::new(&lit_str.value(), lit_str.span()),
+ explicit: true,
+ };
+ } else {
+ panic!("#[num_traits] attribute value must be a str");
+ }
+ }
+ }
+ }
+
+ // Otherwise, we'll implicitly import our own.
+ NumTraits {
+ import: Ident::new("_num_traits", Span::call_site()),
+ explicit: false,
+ }
+ }
+
+ fn wrap(&self, trait_: &str, name: &Ident, output: TokenStream2) -> TokenStream2 {
+ if self.explicit {
+ output
+ } else {
+ dummy_const_trick(trait_, &name, output)
+ }
+ }
+}
+
+/// Derives [`num_traits::FromPrimitive`][from] for simple enums and newtypes.
+///
+/// [from]: https://docs.rs/num-traits/0.2/num_traits/cast/trait.FromPrimitive.html
+///
+/// # Examples
+///
+/// Simple enums can be derived:
+///
+/// ```rust
+/// # #[macro_use]
+/// # extern crate num_derive;
+///
+/// #[derive(FromPrimitive)]
+/// enum Color {
+/// Red,
+/// Blue,
+/// Green = 42,
+/// }
+/// # fn main() {}
+/// ```
+///
+/// Enums that contain data are not allowed:
+///
+/// ```compile_fail
+/// # #[macro_use]
+/// # extern crate num_derive;
+///
+/// #[derive(FromPrimitive)]
+/// enum Color {
+/// Rgb(u8, u8, u8),
+/// Hsv(u8, u8, u8),
+/// }
+/// # fn main() {}
+/// ```
+///
+/// Structs are not allowed:
+///
+/// ```compile_fail
+/// # #[macro_use]
+/// # extern crate num_derive;
+/// #[derive(FromPrimitive)]
+/// struct Color {
+/// r: u8,
+/// g: u8,
+/// b: u8,
+/// }
+/// # fn main() {}
+/// ```
+#[proc_macro_derive(FromPrimitive, attributes(num_traits))]
+pub fn from_primitive(input: TokenStream) -> TokenStream {
+ let ast = parse!(input as syn::DeriveInput);
+ let name = &ast.ident;
+
+ let import = NumTraits::new(&ast);
+
+ let impl_ = if let Some(inner_ty) = newtype_inner(&ast.data) {
+ quote! {
+ impl #import::FromPrimitive for #name {
+ #[inline]
+ fn from_i64(n: i64) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_i64(n).map(#name)
+ }
+ #[inline]
+ fn from_u64(n: u64) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_u64(n).map(#name)
+ }
+ #[inline]
+ fn from_isize(n: isize) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_isize(n).map(#name)
+ }
+ #[inline]
+ fn from_i8(n: i8) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_i8(n).map(#name)
+ }
+ #[inline]
+ fn from_i16(n: i16) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_i16(n).map(#name)
+ }
+ #[inline]
+ fn from_i32(n: i32) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_i32(n).map(#name)
+ }
+ #[inline]
+ fn from_i128(n: i128) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_i128(n).map(#name)
+ }
+ #[inline]
+ fn from_usize(n: usize) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_usize(n).map(#name)
+ }
+ #[inline]
+ fn from_u8(n: u8) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_u8(n).map(#name)
+ }
+ #[inline]
+ fn from_u16(n: u16) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_u16(n).map(#name)
+ }
+ #[inline]
+ fn from_u32(n: u32) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_u32(n).map(#name)
+ }
+ #[inline]
+ fn from_u128(n: u128) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_u128(n).map(#name)
+ }
+ #[inline]
+ fn from_f32(n: f32) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_f32(n).map(#name)
+ }
+ #[inline]
+ fn from_f64(n: f64) -> Option<Self> {
+ <#inner_ty as #import::FromPrimitive>::from_f64(n).map(#name)
+ }
+ }
+ }
+ } else {
+ let variants = match ast.data {
+ Data::Enum(ref data_enum) => &data_enum.variants,
+ _ => panic!(
+ "`FromPrimitive` can be applied only to enums and newtypes, {} is neither",
+ name
+ ),
+ };
+
+ let from_i64_var = quote! { n };
+ let clauses: Vec<_> = variants
+ .iter()
+ .map(|variant| {
+ let ident = &variant.ident;
+ match variant.fields {
+ Fields::Unit => (),
+ _ => panic!(
+ "`FromPrimitive` can be applied only to unitary enums and newtypes, \
+ {}::{} is either struct or tuple",
+ name, ident
+ ),
+ }
+
+ quote! {
+ if #from_i64_var == #name::#ident as i64 {
+ Some(#name::#ident)
+ }
+ }
+ })
+ .collect();
+
+ let from_i64_var = if clauses.is_empty() {
+ quote!(_)
+ } else {
+ from_i64_var
+ };
+
+ quote! {
+ impl #import::FromPrimitive for #name {
+ #[allow(trivial_numeric_casts)]
+ #[inline]
+ fn from_i64(#from_i64_var: i64) -> Option<Self> {
+ #(#clauses else)* {
+ None
+ }
+ }
+
+ #[inline]
+ fn from_u64(n: u64) -> Option<Self> {
+ Self::from_i64(n as i64)
+ }
+ }
+ }
+ };
+
+ import.wrap("FromPrimitive", &name, impl_).into()
+}
+
+/// Derives [`num_traits::ToPrimitive`][to] for simple enums and newtypes.
+///
+/// [to]: https://docs.rs/num-traits/0.2/num_traits/cast/trait.ToPrimitive.html
+///
+/// # Examples
+///
+/// Simple enums can be derived:
+///
+/// ```rust
+/// # #[macro_use]
+/// # extern crate num_derive;
+///
+/// #[derive(ToPrimitive)]
+/// enum Color {
+/// Red,
+/// Blue,
+/// Green = 42,
+/// }
+/// # fn main() {}
+/// ```
+///
+/// Enums that contain data are not allowed:
+///
+/// ```compile_fail
+/// # #[macro_use]
+/// # extern crate num_derive;
+///
+/// #[derive(ToPrimitive)]
+/// enum Color {
+/// Rgb(u8, u8, u8),
+/// Hsv(u8, u8, u8),
+/// }
+/// # fn main() {}
+/// ```
+///
+/// Structs are not allowed:
+///
+/// ```compile_fail
+/// # #[macro_use]
+/// # extern crate num_derive;
+/// #[derive(ToPrimitive)]
+/// struct Color {
+/// r: u8,
+/// g: u8,
+/// b: u8,
+/// }
+/// # fn main() {}
+/// ```
+#[proc_macro_derive(ToPrimitive, attributes(num_traits))]
+pub fn to_primitive(input: TokenStream) -> TokenStream {
+ let ast = parse!(input as syn::DeriveInput);
+ let name = &ast.ident;
+
+ let import = NumTraits::new(&ast);
+
+ let impl_ = if let Some(inner_ty) = newtype_inner(&ast.data) {
+ quote! {
+ impl #import::ToPrimitive for #name {
+ #[inline]
+ fn to_i64(&self) -> Option<i64> {
+ <#inner_ty as #import::ToPrimitive>::to_i64(&self.0)
+ }
+ #[inline]
+ fn to_u64(&self) -> Option<u64> {
+ <#inner_ty as #import::ToPrimitive>::to_u64(&self.0)
+ }
+ #[inline]
+ fn to_isize(&self) -> Option<isize> {
+ <#inner_ty as #import::ToPrimitive>::to_isize(&self.0)
+ }
+ #[inline]
+ fn to_i8(&self) -> Option<i8> {
+ <#inner_ty as #import::ToPrimitive>::to_i8(&self.0)
+ }
+ #[inline]
+ fn to_i16(&self) -> Option<i16> {
+ <#inner_ty as #import::ToPrimitive>::to_i16(&self.0)
+ }
+ #[inline]
+ fn to_i32(&self) -> Option<i32> {
+ <#inner_ty as #import::ToPrimitive>::to_i32(&self.0)
+ }
+ #[inline]
+ fn to_i128(&self) -> Option<i128> {
+ <#inner_ty as #import::ToPrimitive>::to_i128(&self.0)
+ }
+ #[inline]
+ fn to_usize(&self) -> Option<usize> {
+ <#inner_ty as #import::ToPrimitive>::to_usize(&self.0)
+ }
+ #[inline]
+ fn to_u8(&self) -> Option<u8> {
+ <#inner_ty as #import::ToPrimitive>::to_u8(&self.0)
+ }
+ #[inline]
+ fn to_u16(&self) -> Option<u16> {
+ <#inner_ty as #import::ToPrimitive>::to_u16(&self.0)
+ }
+ #[inline]
+ fn to_u32(&self) -> Option<u32> {
+ <#inner_ty as #import::ToPrimitive>::to_u32(&self.0)
+ }
+ #[inline]
+ fn to_u128(&self) -> Option<u128> {
+ <#inner_ty as #import::ToPrimitive>::to_u128(&self.0)
+ }
+ #[inline]
+ fn to_f32(&self) -> Option<f32> {
+ <#inner_ty as #import::ToPrimitive>::to_f32(&self.0)
+ }
+ #[inline]
+ fn to_f64(&self) -> Option<f64> {
+ <#inner_ty as #import::ToPrimitive>::to_f64(&self.0)
+ }
+ }
+ }
+ } else {
+ let variants = match ast.data {
+ Data::Enum(ref data_enum) => &data_enum.variants,
+ _ => panic!(
+ "`ToPrimitive` can be applied only to enums and newtypes, {} is neither",
+ name
+ ),
+ };
+
+ let variants: Vec<_> = variants
+ .iter()
+ .map(|variant| {
+ let ident = &variant.ident;
+ match variant.fields {
+ Fields::Unit => (),
+ _ => {
+ panic!("`ToPrimitive` can be applied only to unitary enums and newtypes, {}::{} is either struct or tuple", name, ident)
+ },
+ }
+
+ // NB: We have to check each variant individually, because we'll only have `&self`
+ // for the input. We can't move from that, and it might not be `Clone` or `Copy`.
+ // (Otherwise we could just do `*self as i64` without a `match` at all.)
+ quote!(#name::#ident => #name::#ident as i64)
+ })
+ .collect();
+
+ let match_expr = if variants.is_empty() {
+ // No variants found, so do not use Some to not to trigger `unreachable_code` lint
+ quote! {
+ match *self {}
+ }
+ } else {
+ quote! {
+ Some(match *self {
+ #(#variants,)*
+ })
+ }
+ };
+
+ quote! {
+ impl #import::ToPrimitive for #name {
+ #[inline]
+ #[allow(trivial_numeric_casts)]
+ fn to_i64(&self) -> Option<i64> {
+ #match_expr
+ }
+
+ #[inline]
+ fn to_u64(&self) -> Option<u64> {
+ self.to_i64().map(|x| x as u64)
+ }
+ }
+ }
+ };
+
+ import.wrap("ToPrimitive", &name, impl_).into()
+}
+
+const NEWTYPE_ONLY: &str = "This trait can only be derived for newtypes";
+
+/// Derives [`num_traits::NumOps`][num_ops] for newtypes. The inner type must already implement
+/// `NumOps`.
+///
+/// [num_ops]: https://docs.rs/num-traits/0.2/num_traits/trait.NumOps.html
+///
+/// Note that, since `NumOps` is really a trait alias for `Add + Sub + Mul + Div + Rem`, this macro
+/// generates impls for _those_ traits. Furthermore, in all generated impls, `RHS=Self` and
+/// `Output=Self`.
+#[proc_macro_derive(NumOps)]
+pub fn num_ops(input: TokenStream) -> TokenStream {
+ let ast = parse!(input as syn::DeriveInput);
+ let name = &ast.ident;
+ let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
+ let impl_ = quote! {
+ impl ::core::ops::Add for #name {
+ type Output = Self;
+ #[inline]
+ fn add(self, other: Self) -> Self {
+ #name(<#inner_ty as ::core::ops::Add>::add(self.0, other.0))
+ }
+ }
+ impl ::core::ops::Sub for #name {
+ type Output = Self;
+ #[inline]
+ fn sub(self, other: Self) -> Self {
+ #name(<#inner_ty as ::core::ops::Sub>::sub(self.0, other.0))
+ }
+ }
+ impl ::core::ops::Mul for #name {
+ type Output = Self;
+ #[inline]
+ fn mul(self, other: Self) -> Self {
+ #name(<#inner_ty as ::core::ops::Mul>::mul(self.0, other.0))
+ }
+ }
+ impl ::core::ops::Div for #name {
+ type Output = Self;
+ #[inline]
+ fn div(self, other: Self) -> Self {
+ #name(<#inner_ty as ::core::ops::Div>::div(self.0, other.0))
+ }
+ }
+ impl ::core::ops::Rem for #name {
+ type Output = Self;
+ #[inline]
+ fn rem(self, other: Self) -> Self {
+ #name(<#inner_ty as ::core::ops::Rem>::rem(self.0, other.0))
+ }
+ }
+ };
+ impl_.into()
+}
+
+/// Derives [`num_traits::NumCast`][num_cast] for newtypes. The inner type must already implement
+/// `NumCast`.
+///
+/// [num_cast]: https://docs.rs/num-traits/0.2/num_traits/cast/trait.NumCast.html
+#[proc_macro_derive(NumCast, attributes(num_traits))]
+pub fn num_cast(input: TokenStream) -> TokenStream {
+ let ast = parse!(input as syn::DeriveInput);
+ let name = &ast.ident;
+ let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
+
+ let import = NumTraits::new(&ast);
+
+ let impl_ = quote! {
+ impl #import::NumCast for #name {
+ #[inline]
+ fn from<T: #import::ToPrimitive>(n: T) -> Option<Self> {
+ <#inner_ty as #import::NumCast>::from(n).map(#name)
+ }
+ }
+ };
+
+ import.wrap("NumCast", &name, impl_).into()
+}
+
+/// Derives [`num_traits::Zero`][zero] for newtypes. The inner type must already implement `Zero`.
+///
+/// [zero]: https://docs.rs/num-traits/0.2/num_traits/identities/trait.Zero.html
+#[proc_macro_derive(Zero, attributes(num_traits))]
+pub fn zero(input: TokenStream) -> TokenStream {
+ let ast = parse!(input as syn::DeriveInput);
+ let name = &ast.ident;
+ let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
+
+ let import = NumTraits::new(&ast);
+
+ let impl_ = quote! {
+ impl #import::Zero for #name {
+ #[inline]
+ fn zero() -> Self {
+ #name(<#inner_ty as #import::Zero>::zero())
+ }
+ #[inline]
+ fn is_zero(&self) -> bool {
+ <#inner_ty as #import::Zero>::is_zero(&self.0)
+ }
+ }
+ };
+
+ import.wrap("Zero", &name, impl_).into()
+}
+
+/// Derives [`num_traits::One`][one] for newtypes. The inner type must already implement `One`.
+///
+/// [one]: https://docs.rs/num-traits/0.2/num_traits/identities/trait.One.html
+#[proc_macro_derive(One, attributes(num_traits))]
+pub fn one(input: TokenStream) -> TokenStream {
+ let ast = parse!(input as syn::DeriveInput);
+ let name = &ast.ident;
+ let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
+
+ let import = NumTraits::new(&ast);
+
+ let impl_ = quote! {
+ impl #import::One for #name {
+ #[inline]
+ fn one() -> Self {
+ #name(<#inner_ty as #import::One>::one())
+ }
+ #[inline]
+ fn is_one(&self) -> bool {
+ <#inner_ty as #import::One>::is_one(&self.0)
+ }
+ }
+ };
+
+ import.wrap("One", &name, impl_).into()
+}
+
+/// Derives [`num_traits::Num`][num] for newtypes. The inner type must already implement `Num`.
+///
+/// [num]: https://docs.rs/num-traits/0.2/num_traits/trait.Num.html
+#[proc_macro_derive(Num, attributes(num_traits))]
+pub fn num(input: TokenStream) -> TokenStream {
+ let ast = parse!(input as syn::DeriveInput);
+ let name = &ast.ident;
+ let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
+
+ let import = NumTraits::new(&ast);
+
+ let impl_ = quote! {
+ impl #import::Num for #name {
+ type FromStrRadixErr = <#inner_ty as #import::Num>::FromStrRadixErr;
+ #[inline]
+ fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
+ <#inner_ty as #import::Num>::from_str_radix(s, radix).map(#name)
+ }
+ }
+ };
+
+ import.wrap("Num", &name, impl_).into()
+}
+
+/// Derives [`num_traits::Float`][float] for newtypes. The inner type must already implement
+/// `Float`.
+///
+/// [float]: https://docs.rs/num-traits/0.2/num_traits/float/trait.Float.html
+#[proc_macro_derive(Float, attributes(num_traits))]
+pub fn float(input: TokenStream) -> TokenStream {
+ let ast = parse!(input as syn::DeriveInput);
+ let name = &ast.ident;
+ let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
+
+ let import = NumTraits::new(&ast);
+
+ let impl_ = quote! {
+ impl #import::Float for #name {
+ #[inline]
+ fn nan() -> Self {
+ #name(<#inner_ty as #import::Float>::nan())
+ }
+ #[inline]
+ fn infinity() -> Self {
+ #name(<#inner_ty as #import::Float>::infinity())
+ }
+ #[inline]
+ fn neg_infinity() -> Self {
+ #name(<#inner_ty as #import::Float>::neg_infinity())
+ }
+ #[inline]
+ fn neg_zero() -> Self {
+ #name(<#inner_ty as #import::Float>::neg_zero())
+ }
+ #[inline]
+ fn min_value() -> Self {
+ #name(<#inner_ty as #import::Float>::min_value())
+ }
+ #[inline]
+ fn min_positive_value() -> Self {
+ #name(<#inner_ty as #import::Float>::min_positive_value())
+ }
+ #[inline]
+ fn max_value() -> Self {
+ #name(<#inner_ty as #import::Float>::max_value())
+ }
+ #[inline]
+ fn is_nan(self) -> bool {
+ <#inner_ty as #import::Float>::is_nan(self.0)
+ }
+ #[inline]
+ fn is_infinite(self) -> bool {
+ <#inner_ty as #import::Float>::is_infinite(self.0)
+ }
+ #[inline]
+ fn is_finite(self) -> bool {
+ <#inner_ty as #import::Float>::is_finite(self.0)
+ }
+ #[inline]
+ fn is_normal(self) -> bool {
+ <#inner_ty as #import::Float>::is_normal(self.0)
+ }
+ #[inline]
+ fn classify(self) -> ::std::num::FpCategory {
+ <#inner_ty as #import::Float>::classify(self.0)
+ }
+ #[inline]
+ fn floor(self) -> Self {
+ #name(<#inner_ty as #import::Float>::floor(self.0))
+ }
+ #[inline]
+ fn ceil(self) -> Self {
+ #name(<#inner_ty as #import::Float>::ceil(self.0))
+ }
+ #[inline]
+ fn round(self) -> Self {
+ #name(<#inner_ty as #import::Float>::round(self.0))
+ }
+ #[inline]
+ fn trunc(self) -> Self {
+ #name(<#inner_ty as #import::Float>::trunc(self.0))
+ }
+ #[inline]
+ fn fract(self) -> Self {
+ #name(<#inner_ty as #import::Float>::fract(self.0))
+ }
+ #[inline]
+ fn abs(self) -> Self {
+ #name(<#inner_ty as #import::Float>::abs(self.0))
+ }
+ #[inline]
+ fn signum(self) -> Self {
+ #name(<#inner_ty as #import::Float>::signum(self.0))
+ }
+ #[inline]
+ fn is_sign_positive(self) -> bool {
+ <#inner_ty as #import::Float>::is_sign_positive(self.0)
+ }
+ #[inline]
+ fn is_sign_negative(self) -> bool {
+ <#inner_ty as #import::Float>::is_sign_negative(self.0)
+ }
+ #[inline]
+ fn mul_add(self, a: Self, b: Self) -> Self {
+ #name(<#inner_ty as #import::Float>::mul_add(self.0, a.0, b.0))
+ }
+ #[inline]
+ fn recip(self) -> Self {
+ #name(<#inner_ty as #import::Float>::recip(self.0))
+ }
+ #[inline]
+ fn powi(self, n: i32) -> Self {
+ #name(<#inner_ty as #import::Float>::powi(self.0, n))
+ }
+ #[inline]
+ fn powf(self, n: Self) -> Self {
+ #name(<#inner_ty as #import::Float>::powf(self.0, n.0))
+ }
+ #[inline]
+ fn sqrt(self) -> Self {
+ #name(<#inner_ty as #import::Float>::sqrt(self.0))
+ }
+ #[inline]
+ fn exp(self) -> Self {
+ #name(<#inner_ty as #import::Float>::exp(self.0))
+ }
+ #[inline]
+ fn exp2(self) -> Self {
+ #name(<#inner_ty as #import::Float>::exp2(self.0))
+ }
+ #[inline]
+ fn ln(self) -> Self {
+ #name(<#inner_ty as #import::Float>::ln(self.0))
+ }
+ #[inline]
+ fn log(self, base: Self) -> Self {
+ #name(<#inner_ty as #import::Float>::log(self.0, base.0))
+ }
+ #[inline]
+ fn log2(self) -> Self {
+ #name(<#inner_ty as #import::Float>::log2(self.0))
+ }
+ #[inline]
+ fn log10(self) -> Self {
+ #name(<#inner_ty as #import::Float>::log10(self.0))
+ }
+ #[inline]
+ fn max(self, other: Self) -> Self {
+ #name(<#inner_ty as #import::Float>::max(self.0, other.0))
+ }
+ #[inline]
+ fn min(self, other: Self) -> Self {
+ #name(<#inner_ty as #import::Float>::min(self.0, other.0))
+ }
+ #[inline]
+ fn abs_sub(self, other: Self) -> Self {
+ #name(<#inner_ty as #import::Float>::abs_sub(self.0, other.0))
+ }
+ #[inline]
+ fn cbrt(self) -> Self {
+ #name(<#inner_ty as #import::Float>::cbrt(self.0))
+ }
+ #[inline]
+ fn hypot(self, other: Self) -> Self {
+ #name(<#inner_ty as #import::Float>::hypot(self.0, other.0))
+ }
+ #[inline]
+ fn sin(self) -> Self {
+ #name(<#inner_ty as #import::Float>::sin(self.0))
+ }
+ #[inline]
+ fn cos(self) -> Self {
+ #name(<#inner_ty as #import::Float>::cos(self.0))
+ }
+ #[inline]
+ fn tan(self) -> Self {
+ #name(<#inner_ty as #import::Float>::tan(self.0))
+ }
+ #[inline]
+ fn asin(self) -> Self {
+ #name(<#inner_ty as #import::Float>::asin(self.0))
+ }
+ #[inline]
+ fn acos(self) -> Self {
+ #name(<#inner_ty as #import::Float>::acos(self.0))
+ }
+ #[inline]
+ fn atan(self) -> Self {
+ #name(<#inner_ty as #import::Float>::atan(self.0))
+ }
+ #[inline]
+ fn atan2(self, other: Self) -> Self {
+ #name(<#inner_ty as #import::Float>::atan2(self.0, other.0))
+ }
+ #[inline]
+ fn sin_cos(self) -> (Self, Self) {
+ let (x, y) = <#inner_ty as #import::Float>::sin_cos(self.0);
+ (#name(x), #name(y))
+ }
+ #[inline]
+ fn exp_m1(self) -> Self {
+ #name(<#inner_ty as #import::Float>::exp_m1(self.0))
+ }
+ #[inline]
+ fn ln_1p(self) -> Self {
+ #name(<#inner_ty as #import::Float>::ln_1p(self.0))
+ }
+ #[inline]
+ fn sinh(self) -> Self {
+ #name(<#inner_ty as #import::Float>::sinh(self.0))
+ }
+ #[inline]
+ fn cosh(self) -> Self {
+ #name(<#inner_ty as #import::Float>::cosh(self.0))
+ }
+ #[inline]
+ fn tanh(self) -> Self {
+ #name(<#inner_ty as #import::Float>::tanh(self.0))
+ }
+ #[inline]
+ fn asinh(self) -> Self {
+ #name(<#inner_ty as #import::Float>::asinh(self.0))
+ }
+ #[inline]
+ fn acosh(self) -> Self {
+ #name(<#inner_ty as #import::Float>::acosh(self.0))
+ }
+ #[inline]
+ fn atanh(self) -> Self {
+ #name(<#inner_ty as #import::Float>::atanh(self.0))
+ }
+ #[inline]
+ fn integer_decode(self) -> (u64, i16, i8) {
+ <#inner_ty as #import::Float>::integer_decode(self.0)
+ }
+ #[inline]
+ fn epsilon() -> Self {
+ #name(<#inner_ty as #import::Float>::epsilon())
+ }
+ #[inline]
+ fn to_degrees(self) -> Self {
+ #name(<#inner_ty as #import::Float>::to_degrees(self.0))
+ }
+ #[inline]
+ fn to_radians(self) -> Self {
+ #name(<#inner_ty as #import::Float>::to_radians(self.0))
+ }
+ }
+ };
+
+ import.wrap("Float", &name, impl_).into()
+}
+
+mod test;
diff --git a/third_party/rust/num-derive/src/test.rs b/third_party/rust/num-derive/src/test.rs
new file mode 100644
index 0000000000..c4cd7fe528
--- /dev/null
+++ b/third_party/rust/num-derive/src/test.rs
@@ -0,0 +1,31 @@
+//! This module uses doc-tests on modules for `compile_fail`
+
+// We need "syn/full" to parse macros.
+// Use `--nocapture` to check the quality of the error message.
+#[cfg(not(feature = "full-syntax"))]
+/// ```compile_fail
+/// macro_rules! get_an_isize {
+/// () => (0_isize)
+/// }
+///
+/// #[derive(num_derive::FromPrimitive)]
+/// pub enum CLikeEnum {
+/// VarA = get_an_isize!(), // error without "syn/full"
+/// VarB = 2,
+/// }
+/// ```
+mod issue16 {}
+
+#[cfg(feature = "full-syntax")]
+/// ```
+/// macro_rules! get_an_isize {
+/// () => (0_isize)
+/// }
+///
+/// #[derive(num_derive::FromPrimitive)]
+/// pub enum CLikeEnum {
+/// VarA = get_an_isize!(), // ok with "syn/full"
+/// VarB = 2,
+/// }
+/// ```
+mod issue16 {}
diff --git a/third_party/rust/num-derive/tests/empty_enum.rs b/third_party/rust/num-derive/tests/empty_enum.rs
new file mode 100644
index 0000000000..173996c8ed
--- /dev/null
+++ b/third_party/rust/num-derive/tests/empty_enum.rs
@@ -0,0 +1,23 @@
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate num as num_renamed;
+#[macro_use]
+extern crate num_derive;
+
+#[derive(Debug, PartialEq, FromPrimitive, ToPrimitive)]
+enum Color {}
+
+#[test]
+fn test_empty_enum() {
+ let v: [Option<Color>; 1] = [num_renamed::FromPrimitive::from_u64(0)];
+
+ assert_eq!(v, [None]);
+}
diff --git a/third_party/rust/num-derive/tests/issue-6.rs b/third_party/rust/num-derive/tests/issue-6.rs
new file mode 100644
index 0000000000..9eae7fb3f5
--- /dev/null
+++ b/third_party/rust/num-derive/tests/issue-6.rs
@@ -0,0 +1,17 @@
+#![deny(trivial_numeric_casts)]
+
+#[macro_use]
+extern crate num_derive;
+
+#[derive(FromPrimitive, ToPrimitive)]
+pub enum SomeEnum {
+ A = 1,
+}
+
+#[test]
+fn test_trivial_numeric_casts() {
+ use num::{FromPrimitive, ToPrimitive};
+ assert!(SomeEnum::from_u64(1).is_some());
+ assert!(SomeEnum::from_i64(-1).is_none());
+ assert_eq!(SomeEnum::A.to_u64(), Some(1));
+}
diff --git a/third_party/rust/num-derive/tests/issue-9.rs b/third_party/rust/num-derive/tests/issue-9.rs
new file mode 100644
index 0000000000..30c04d2f46
--- /dev/null
+++ b/third_party/rust/num-derive/tests/issue-9.rs
@@ -0,0 +1,18 @@
+#![deny(unused_qualifications)]
+
+#[macro_use]
+extern crate num_derive;
+use num::FromPrimitive;
+use num::ToPrimitive;
+
+#[derive(FromPrimitive, ToPrimitive)]
+pub enum SomeEnum {
+ A = 1,
+}
+
+#[test]
+fn test_unused_qualifications() {
+ assert!(SomeEnum::from_u64(1).is_some());
+ assert!(SomeEnum::from_i64(-1).is_none());
+ assert!(SomeEnum::A.to_i64().is_some());
+}
diff --git a/third_party/rust/num-derive/tests/newtype-2015.rs b/third_party/rust/num-derive/tests/newtype-2015.rs
new file mode 100644
index 0000000000..2b581907ec
--- /dev/null
+++ b/third_party/rust/num-derive/tests/newtype-2015.rs
@@ -0,0 +1,2 @@
+// Same source, just compiled for 2015 edition
+include!("newtype.rs");
diff --git a/third_party/rust/num-derive/tests/newtype.rs b/third_party/rust/num-derive/tests/newtype.rs
new file mode 100644
index 0000000000..6eafd0960b
--- /dev/null
+++ b/third_party/rust/num-derive/tests/newtype.rs
@@ -0,0 +1,89 @@
+extern crate num as num_renamed;
+#[macro_use]
+extern crate num_derive;
+
+use crate::num_renamed::{Float, FromPrimitive, Num, NumCast, One, ToPrimitive, Zero};
+use std::ops::Neg;
+
+#[derive(
+ Debug,
+ Clone,
+ Copy,
+ PartialEq,
+ PartialOrd,
+ ToPrimitive,
+ FromPrimitive,
+ NumOps,
+ NumCast,
+ One,
+ Zero,
+ Num,
+ Float,
+)]
+struct MyFloat(f64);
+
+impl Neg for MyFloat {
+ type Output = MyFloat;
+ fn neg(self) -> Self {
+ MyFloat(self.0.neg())
+ }
+}
+
+#[test]
+fn test_from_primitive() {
+ assert_eq!(MyFloat::from_u32(25), Some(MyFloat(25.0)));
+}
+
+#[test]
+fn test_from_primitive_128() {
+ assert_eq!(
+ MyFloat::from_i128(std::i128::MIN),
+ Some(MyFloat((-2.0).powi(127)))
+ );
+}
+
+#[test]
+fn test_to_primitive() {
+ assert_eq!(MyFloat(25.0).to_u32(), Some(25));
+}
+
+#[test]
+fn test_to_primitive_128() {
+ let f = MyFloat::from_f32(std::f32::MAX).unwrap();
+ assert_eq!(f.to_i128(), None);
+ assert_eq!(f.to_u128(), Some(0xffff_ff00_0000_0000_0000_0000_0000_0000));
+}
+
+#[test]
+fn test_num_ops() {
+ assert_eq!(MyFloat(25.0) + MyFloat(10.0), MyFloat(35.0));
+ assert_eq!(MyFloat(25.0) - MyFloat(10.0), MyFloat(15.0));
+ assert_eq!(MyFloat(25.0) * MyFloat(2.0), MyFloat(50.0));
+ assert_eq!(MyFloat(25.0) / MyFloat(10.0), MyFloat(2.5));
+ assert_eq!(MyFloat(25.0) % MyFloat(10.0), MyFloat(5.0));
+}
+
+#[test]
+fn test_num_cast() {
+ assert_eq!(<MyFloat as NumCast>::from(25u8), Some(MyFloat(25.0)));
+}
+
+#[test]
+fn test_zero() {
+ assert_eq!(MyFloat::zero(), MyFloat(0.0));
+}
+
+#[test]
+fn test_one() {
+ assert_eq!(MyFloat::one(), MyFloat(1.0));
+}
+
+#[test]
+fn test_num() {
+ assert_eq!(MyFloat::from_str_radix("25", 10).ok(), Some(MyFloat(25.0)));
+}
+
+#[test]
+fn test_float() {
+ assert_eq!(MyFloat(4.0).log(MyFloat(2.0)), MyFloat(2.0));
+}
diff --git a/third_party/rust/num-derive/tests/num_derive_without_num.rs b/third_party/rust/num-derive/tests/num_derive_without_num.rs
new file mode 100644
index 0000000000..edebbecbfa
--- /dev/null
+++ b/third_party/rust/num-derive/tests/num_derive_without_num.rs
@@ -0,0 +1,20 @@
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_use]
+extern crate num_derive;
+
+#[derive(Debug, FromPrimitive, ToPrimitive)]
+enum Direction {
+ Up,
+ Down,
+ Left,
+ Right,
+}
diff --git a/third_party/rust/num-derive/tests/trivial-2015.rs b/third_party/rust/num-derive/tests/trivial-2015.rs
new file mode 100644
index 0000000000..8309f0e889
--- /dev/null
+++ b/third_party/rust/num-derive/tests/trivial-2015.rs
@@ -0,0 +1,2 @@
+// Same source, just compiled for 2015 edition
+include!("trivial.rs");
diff --git a/third_party/rust/num-derive/tests/trivial.rs b/third_party/rust/num-derive/tests/trivial.rs
new file mode 100644
index 0000000000..d3b56b6a25
--- /dev/null
+++ b/third_party/rust/num-derive/tests/trivial.rs
@@ -0,0 +1,64 @@
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate num as num_renamed;
+#[macro_use]
+extern crate num_derive;
+
+#[derive(Debug, PartialEq, FromPrimitive, ToPrimitive)]
+enum Color {
+ Red,
+ Blue,
+ Green,
+}
+
+#[test]
+fn test_from_primitive_for_trivial_case() {
+ let v: [Option<Color>; 4] = [
+ num_renamed::FromPrimitive::from_u64(0),
+ num_renamed::FromPrimitive::from_u64(1),
+ num_renamed::FromPrimitive::from_u64(2),
+ num_renamed::FromPrimitive::from_u64(3),
+ ];
+
+ assert_eq!(
+ v,
+ [
+ Some(Color::Red),
+ Some(Color::Blue),
+ Some(Color::Green),
+ None
+ ]
+ );
+}
+
+#[test]
+fn test_to_primitive_for_trivial_case() {
+ let v: [Option<u64>; 3] = [
+ num_renamed::ToPrimitive::to_u64(&Color::Red),
+ num_renamed::ToPrimitive::to_u64(&Color::Blue),
+ num_renamed::ToPrimitive::to_u64(&Color::Green),
+ ];
+
+ assert_eq!(v, [Some(0), Some(1), Some(2)]);
+}
+
+#[test]
+fn test_reflexive_for_trivial_case() {
+ let before: [u64; 3] = [0, 1, 2];
+ let after: Vec<Option<u64>> = before
+ .iter()
+ .map(|&x| -> Option<Color> { num_renamed::FromPrimitive::from_u64(x) })
+ .map(|x| x.and_then(|x| num_renamed::ToPrimitive::to_u64(&x)))
+ .collect();
+ let before = before.iter().cloned().map(Some).collect::<Vec<_>>();
+
+ assert_eq!(before, after);
+}
diff --git a/third_party/rust/num-derive/tests/with_custom_values.rs b/third_party/rust/num-derive/tests/with_custom_values.rs
new file mode 100644
index 0000000000..94c84458be
--- /dev/null
+++ b/third_party/rust/num-derive/tests/with_custom_values.rs
@@ -0,0 +1,70 @@
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![cfg(feature = "full-syntax")]
+
+extern crate num as num_renamed;
+#[macro_use]
+extern crate num_derive;
+
+#[derive(Debug, PartialEq, FromPrimitive, ToPrimitive)]
+enum Color {
+ Red,
+ Blue = 5,
+ Green,
+ Alpha = (-3 - (-5isize)) - 10,
+}
+
+#[test]
+fn test_from_primitive_for_enum_with_custom_value() {
+ let v: [Option<Color>; 5] = [
+ num_renamed::FromPrimitive::from_u64(0),
+ num_renamed::FromPrimitive::from_u64(5),
+ num_renamed::FromPrimitive::from_u64(6),
+ num_renamed::FromPrimitive::from_u64(-8isize as u64),
+ num_renamed::FromPrimitive::from_u64(3),
+ ];
+
+ assert_eq!(
+ v,
+ [
+ Some(Color::Red),
+ Some(Color::Blue),
+ Some(Color::Green),
+ Some(Color::Alpha),
+ None
+ ]
+ );
+}
+
+#[test]
+fn test_to_primitive_for_enum_with_custom_value() {
+ let v: [Option<u64>; 4] = [
+ num_renamed::ToPrimitive::to_u64(&Color::Red),
+ num_renamed::ToPrimitive::to_u64(&Color::Blue),
+ num_renamed::ToPrimitive::to_u64(&Color::Green),
+ num_renamed::ToPrimitive::to_u64(&Color::Alpha),
+ ];
+
+ assert_eq!(v, [Some(0), Some(5), Some(6), Some(-8isize as u64)]);
+}
+
+#[test]
+fn test_reflexive_for_enum_with_custom_value() {
+ let before: [u64; 3] = [0, 5, 6];
+ let after: Vec<Option<u64>> = before
+ .iter()
+ .map(|&x| -> Option<Color> { num_renamed::FromPrimitive::from_u64(x) })
+ .map(|x| x.and_then(|x| num_renamed::ToPrimitive::to_u64(&x)))
+ .collect();
+ let before = before.iter().cloned().map(Some).collect::<Vec<_>>();
+
+ assert_eq!(before, after);
+}