summaryrefslogtreecommitdiffstats
path: root/third_party/rust/enum-primitive-derive
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/enum-primitive-derive')
-rw-r--r--third_party/rust/enum-primitive-derive/.cargo-checksum.json1
-rw-r--r--third_party/rust/enum-primitive-derive/CHANGELOG.md33
-rw-r--r--third_party/rust/enum-primitive-derive/Cargo.toml37
-rw-r--r--third_party/rust/enum-primitive-derive/LICENSE20
-rw-r--r--third_party/rust/enum-primitive-derive/README.md110
-rw-r--r--third_party/rust/enum-primitive-derive/src/lib.rs278
6 files changed, 479 insertions, 0 deletions
diff --git a/third_party/rust/enum-primitive-derive/.cargo-checksum.json b/third_party/rust/enum-primitive-derive/.cargo-checksum.json
new file mode 100644
index 0000000000..fda1620185
--- /dev/null
+++ b/third_party/rust/enum-primitive-derive/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"75976e8cf25b724bd1db6d176d3bd98ad19554a2d64a57aaffa1b14c64a55f7a","Cargo.toml":"3d3e91b17cb7b10e130d8db6ebcfff05f37d799a8d5039d67aca802998501ae7","LICENSE":"819e0555b295079201b0670bb3302855303bdbbcc739f3819b13e1b3d2ec03bb","README.md":"a0d505b975f799d351e539720d26ed64f2022adcc8257d63c343c32a0c88f5de","src/lib.rs":"3751e744d351269d320cdc58e7fefd0f4bf657ed3a09b0fca68205696a1927c0"},"package":"c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e"} \ No newline at end of file
diff --git a/third_party/rust/enum-primitive-derive/CHANGELOG.md b/third_party/rust/enum-primitive-derive/CHANGELOG.md
new file mode 100644
index 0000000000..33ad10c31e
--- /dev/null
+++ b/third_party/rust/enum-primitive-derive/CHANGELOG.md
@@ -0,0 +1,33 @@
+# ChangeLog
+
+## 0.2.2
+### Changed
+- Switch to using core instead of std for no-std support
+
+## 0.2.1
+### Added
+- support TryFrom
+
+## 0.2.0 (yanked)
+### Changed
+- Upgrade [syn](https://crates.io/crates/syn) and [quote](https://crates.io/crates/quote) to 1.0
+- add a better diagnostic for the case where a discriminant isn't specified for
+ an enum
+- Move unnecessary [`num-traits`](https://crates.io/crates/num-traits) dependency to `dev-dependencies`
+- Migrate to Rust 2018 edition
+
+## 0.1.2
+
+### Changed
+
+- drop `extern crate core;` as core is unused
+
+## 0.1.1
+
+### Added
+
+- Support for more casts on discriminants
+
+## 0.1.0
+
+Initial version
diff --git a/third_party/rust/enum-primitive-derive/Cargo.toml b/third_party/rust/enum-primitive-derive/Cargo.toml
new file mode 100644
index 0000000000..96a901e6cc
--- /dev/null
+++ b/third_party/rust/enum-primitive-derive/Cargo.toml
@@ -0,0 +1,37 @@
+# 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 are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "enum-primitive-derive"
+version = "0.2.2"
+authors = ["Doug Goldstein <cardoe@cardoe.com>"]
+description = "enum_primitive implementation using procedural macros to have a custom derive"
+homepage = "https://gitlab.com/cardoe/enum-primitive-derive"
+readme = "README.md"
+keywords = ["derive", "enum", "fromprimitive", "primitive", "ffi"]
+categories = ["rust-patterns"]
+license = "MIT"
+repository = "https://gitlab.com/cardoe/enum-primitive-derive.git"
+
+[lib]
+proc-macro = true
+[dependencies.num-traits]
+version = "0.2"
+default-features = false
+
+[dependencies.quote]
+version = "1"
+
+[dependencies.syn]
+version = "1"
+[badges.gitlab]
+repository = "cardoe/enum-primitive-derive"
diff --git a/third_party/rust/enum-primitive-derive/LICENSE b/third_party/rust/enum-primitive-derive/LICENSE
new file mode 100644
index 0000000000..94486be7da
--- /dev/null
+++ b/third_party/rust/enum-primitive-derive/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2017 Doug Goldstein <cardoe@cardoe.com>
+
+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/enum-primitive-derive/README.md b/third_party/rust/enum-primitive-derive/README.md
new file mode 100644
index 0000000000..795af9f501
--- /dev/null
+++ b/third_party/rust/enum-primitive-derive/README.md
@@ -0,0 +1,110 @@
+[![Build status](https://gitlab.com/cardoe/enum-primitive-derive/badges/master/pipeline.svg)](https://gitlab.com/cardoe/enum-primitive-derive/commits/master)
+[![Rust version]( https://img.shields.io/badge/rust-1.34+-blue.svg)]()
+[![Documentation](https://docs.rs/enum-primitive-derive/badge.svg)](https://docs.rs/enum-primitive-derive)
+[![Latest version](https://img.shields.io/crates/v/enum-primitive-derive.svg)](https://crates.io/crates/enum-primitive-derive)
+[![All downloads](https://img.shields.io/crates/d/enum-primitive-derive.svg)](https://crates.io/crates/enum-primitive-derive)
+[![Downloads of latest version](https://img.shields.io/crates/dv/enum-primitive-derive.svg)](https://crates.io/crates/enum-primitive-derive)
+
+This is a custom derive, using procedural macros, implementation of
+[enum_primitive](https://crates.io/crates/enum_primitive).
+
+MSRV is 1.34.0
+
+## Documentation
+
+[https://docs.rs/enum-primitive-derive/](https://docs.rs/enum-primitive-derive/)
+
+## Usage
+
+Add the following to `Cargo.toml`:
+
+```
+[dependencies]
+enum-primitive-derive = "^0.1"
+num-traits = "^0.1"
+```
+
+Then to your code add:
+
+```rust
+#[macro_use]
+extern crate enum_primitive_derive;
+extern crate num_traits;
+
+#[derive(Primitive)]
+enum Variant {
+ Value = 1,
+ Another = 2,
+}
+```
+
+To be really useful you need `use num_traits::FromPrimitive` or
+`use num_traits::ToPrimitive` or both. You will then be able to
+use
+[num_traits::FromPrimitive](https://rust-num.github.io/num/num/trait.FromPrimitive.html)
+and/or
+[num_traits::ToPrimitive](https://rust-num.github.io/num/num/trait.ToPrimitive.html)
+on your enum.
+
+## Full Example
+
+```rust
+#[macro_use]
+extern crate enum_primitive_derive;
+extern crate num_traits;
+
+use num_traits::{FromPrimitive, ToPrimitive};
+
+#[derive(Primitive)]
+enum Foo {
+ Bar = 32,
+ Dead = 42,
+ Beef = 50,
+}
+
+fn main() {
+ assert_eq!(Foo::from_i32(32), Some(Foo::Bar));
+ assert_eq!(Foo::from_i32(42), Some(Foo::Dead));
+ assert_eq!(Foo::from_i64(50), Some(Foo::Beef));
+ assert_eq!(Foo::from_isize(17), None);
+
+ let bar = Foo::Bar;
+ assert_eq!(bar.to_i32(), Some(32));
+
+ let dead = Foo::Dead;
+ assert_eq!(dead.to_isize(), Some(42));
+}
+```
+
+# Complex Example
+
+In this case we attempt to use values created by
+[bindgen](https://crates.io/crates/bindgen).
+
+```rust
+#[macro_use]
+extern crate enum_primitive_derive;
+extern crate num_traits;
+
+use num_traits::{FromPrimitive, ToPrimitive};
+
+pub const ABC: ::std::os::raw::c_uint = 1;
+pub const DEF: ::std::os::raw::c_uint = 2;
+pub const GHI: ::std::os::raw::c_uint = 4;
+
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Primitive)]
+enum BindGenLike {
+ ABC = ABC as isize,
+ DEF = DEF as isize,
+ GHI = GHI as isize,
+}
+
+fn main() {
+ assert_eq!(BindGenLike::from_isize(4), Some(BindGenLike::GHI));
+ assert_eq!(BindGenLike::from_u32(2), Some(BindGenLike::DEF));
+ assert_eq!(BindGenLike::from_u32(8), None);
+
+ let abc = BindGenLike::ABC;
+ assert_eq!(abc.to_u32(), Some(1));
+}
+```
diff --git a/third_party/rust/enum-primitive-derive/src/lib.rs b/third_party/rust/enum-primitive-derive/src/lib.rs
new file mode 100644
index 0000000000..135f6164c7
--- /dev/null
+++ b/third_party/rust/enum-primitive-derive/src/lib.rs
@@ -0,0 +1,278 @@
+// Copyright (c) 2017 Doug Goldstein <cardoe@cardoe.com>
+
+// 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.
+
+//! This crate provides a custom derive `Primitive` that helps people
+//! providing native Rust bindings to C code by allowing a C-like `enum`
+//! declaration to convert to its primitve values and back from them. You
+//! can selectively include `num_traits::ToPrimitive` and
+//! `num_traits::FromPrimitive` to get these features.
+//!
+//! # Example
+//!
+//! ```rust
+//! use enum_primitive_derive::Primitive;
+//! use num_traits::{FromPrimitive, ToPrimitive};
+//!
+//! #[derive(Debug, Eq, PartialEq, Primitive)]
+//! enum Foo {
+//! Bar = 32,
+//! Dead = 42,
+//! Beef = 50,
+//! }
+//!
+//! fn main() {
+//! assert_eq!(Foo::from_i32(32), Some(Foo::Bar));
+//! assert_eq!(Foo::from_i32(42), Some(Foo::Dead));
+//! assert_eq!(Foo::from_i64(50), Some(Foo::Beef));
+//! assert_eq!(Foo::from_isize(17), None);
+//!
+//! let bar = Foo::Bar;
+//! assert_eq!(bar.to_i32(), Some(32));
+//!
+//! let dead = Foo::Dead;
+//! assert_eq!(dead.to_isize(), Some(42));
+//! }
+//! ```
+//!
+//! # Complex Example
+//!
+//! ```rust
+//! use enum_primitive_derive::Primitive;
+//! use num_traits::{FromPrimitive, ToPrimitive};
+//!
+//! pub const ABC: ::std::os::raw::c_uint = 1;
+//! pub const DEF: ::std::os::raw::c_uint = 2;
+//! pub const GHI: ::std::os::raw::c_uint = 4;
+//!
+//! #[derive(Clone, Copy, Debug, Eq, PartialEq, Primitive)]
+//! enum BindGenLike {
+//! ABC = ABC as isize,
+//! DEF = DEF as isize,
+//! GHI = GHI as isize,
+//! }
+//!
+//! fn main() {
+//! assert_eq!(BindGenLike::from_isize(4), Some(BindGenLike::GHI));
+//! assert_eq!(BindGenLike::from_u32(2), Some(BindGenLike::DEF));
+//! assert_eq!(BindGenLike::from_u32(8), None);
+//!
+//! let abc = BindGenLike::ABC;
+//! assert_eq!(abc.to_u32(), Some(1));
+//! }
+//! ```
+//!
+//! # TryFrom Example
+//!
+//! ```rust
+//! use enum_primitive_derive::Primitive;
+//! use core::convert::TryFrom;
+//!
+//! #[derive(Debug, Eq, PartialEq, Primitive)]
+//! enum Foo {
+//! Bar = 32,
+//! Dead = 42,
+//! Beef = 50,
+//! }
+//!
+//! fn main() {
+//! let bar = Foo::try_from(32);
+//! assert_eq!(bar, Ok(Foo::Bar));
+//!
+//! let dead = Foo::try_from(42);
+//! assert_eq!(dead, Ok(Foo::Dead));
+//!
+//! let unknown = Foo::try_from(12);
+//! assert!(unknown.is_err());
+//! }
+//! ```
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+/// Provides implementation of `num_traits::ToPrimitive` and
+/// `num_traits::FromPrimitive`
+#[proc_macro_derive(Primitive)]
+pub fn primitive(input: TokenStream) -> TokenStream {
+ let ast = syn::parse_macro_input!(input as syn::DeriveInput);
+ impl_primitive(&ast)
+}
+
+fn impl_primitive(ast: &syn::DeriveInput) -> TokenStream {
+ let name = &ast.ident;
+
+ // Check if derive(Primitive) was specified for a struct
+ if let syn::Data::Enum(ref variant) = ast.data {
+ let (var_u64, dis_u64): (Vec<_>, Vec<_>) = variant
+ .variants
+ .iter()
+ .map(|v| {
+ match v.fields {
+ syn::Fields::Unit => (),
+ _ => panic!("#[derive(Primitive) can only operate on C-like enums"),
+ }
+ if v.discriminant.is_none() {
+ panic!(
+ "#[derive(Primitive) requires C-like enums with \
+ discriminants for all enum variants"
+ );
+ }
+
+ let discrim = match v.discriminant.clone().map(|(_eq, expr)| expr).unwrap() {
+ syn::Expr::Cast(real) => *real.expr,
+ orig => orig,
+ };
+ (v.ident.clone(), discrim)
+ })
+ .unzip();
+
+ // quote!{} needs this to be a vec since its in #( )*
+ let enum_u64 = vec![name.clone(); variant.variants.len()];
+
+ // can't reuse variables in quote!{} body
+ let var_i64 = var_u64.clone();
+ let dis_i64 = dis_u64.clone();
+ let enum_i64 = enum_u64.clone();
+
+ let to_name = name.clone();
+ let to_enum_u64 = enum_u64.clone();
+ let to_var_u64 = var_u64.clone();
+ let to_dis_u64 = dis_u64.clone();
+
+ let to_enum_i64 = enum_u64.clone();
+ let to_var_i64 = var_u64.clone();
+ let to_dis_i64 = dis_u64.clone();
+
+ TokenStream::from(quote::quote! {
+ impl ::num_traits::FromPrimitive for #name {
+ fn from_u64(val: u64) -> Option<Self> {
+ match val as _ {
+ #( #dis_u64 => Some(#enum_u64::#var_u64), )*
+ _ => None,
+ }
+ }
+
+ fn from_i64(val: i64) -> Option<Self> {
+ match val as _ {
+ #( #dis_i64 => Some(#enum_i64::#var_i64), )*
+ _ => None,
+ }
+ }
+ }
+
+ impl ::num_traits::ToPrimitive for #to_name {
+ fn to_u64(&self) -> Option<u64> {
+ match *self {
+ #( #to_enum_u64::#to_var_u64 => Some(#to_dis_u64 as u64), )*
+ }
+ }
+
+ fn to_i64(&self) -> Option<i64> {
+ match *self {
+ #( #to_enum_i64::#to_var_i64 => Some(#to_dis_i64 as i64), )*
+ }
+ }
+ }
+
+ impl ::core::convert::TryFrom<u64> for #to_name {
+ type Error = &'static str;
+
+ fn try_from(value: u64) -> ::core::result::Result<Self, Self::Error> {
+ use ::num_traits::FromPrimitive;
+
+ #to_name::from_u64(value).ok_or_else(|| "Unknown variant")
+ }
+ }
+
+ impl ::core::convert::TryFrom<u32> for #to_name {
+ type Error = &'static str;
+
+ fn try_from(value: u32) -> ::core::result::Result<Self, Self::Error> {
+ use ::num_traits::FromPrimitive;
+
+ #to_name::from_u32(value).ok_or_else(|| "Unknown variant")
+ }
+ }
+
+ impl ::core::convert::TryFrom<u16> for #to_name {
+ type Error = &'static str;
+
+ fn try_from(value: u16) -> ::core::result::Result<Self, Self::Error> {
+ use ::num_traits::FromPrimitive;
+
+ #to_name::from_u16(value).ok_or_else(|| "Unknown variant")
+ }
+ }
+
+ impl ::core::convert::TryFrom<u8> for #to_name {
+ type Error = &'static str;
+
+ fn try_from(value: u8) -> ::core::result::Result<Self, Self::Error> {
+ use ::num_traits::FromPrimitive;
+
+ #to_name::from_u8(value).ok_or_else(|| "Unknown variant")
+ }
+ }
+
+ impl ::core::convert::TryFrom<i64> for #name {
+ type Error = &'static str;
+
+ fn try_from(value: i64) -> ::core::result::Result<Self, Self::Error> {
+ use ::num_traits::FromPrimitive;
+
+ #to_name::from_i64(value).ok_or_else(|| "Unknown variant")
+ }
+ }
+
+ impl ::core::convert::TryFrom<i32> for #name {
+ type Error = &'static str;
+
+ fn try_from(value: i32) -> ::core::result::Result<Self, Self::Error> {
+ use ::num_traits::FromPrimitive;
+
+ #to_name::from_i32(value).ok_or_else(|| "Unknown variant")
+ }
+ }
+
+ impl ::core::convert::TryFrom<i16> for #name {
+ type Error = &'static str;
+
+ fn try_from(value: i16) -> ::core::result::Result<Self, Self::Error> {
+ use ::num_traits::FromPrimitive;
+
+ #to_name::from_i16(value).ok_or_else(|| "Unknown variant")
+ }
+ }
+
+ impl ::core::convert::TryFrom<i8> for #name {
+ type Error = &'static str;
+
+ fn try_from(value: i8) -> ::core::result::Result<Self, Self::Error> {
+ use ::num_traits::FromPrimitive;
+
+ #to_name::from_i8(value).ok_or_else(|| "Unknown variant")
+ }
+ }
+ })
+ } else {
+ panic!("#[derive(Primitive)] is only valid for C-like enums");
+ }
+}