├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE ├── README.md ├── tests ├── image.rs ├── omitted-discriminants.rs └── tests.rs └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | 3 | rust: 4 | - 1.0.0 5 | - stable 6 | - nightly 7 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "enum_primitive" 3 | version = "0.1.1" 4 | license = "MIT" 5 | description = "Macro to generate num::FromPrimitive instances for enum that works in Rust 1.0" 6 | authors = ["Anders Kaseorg "] 7 | documentation = "https://andersk.github.io/enum_primitive-rs/enum_primitive/" 8 | repository = "https://github.com/andersk/enum_primitive-rs.git" 9 | homepage = "https://github.com/andersk/enum_primitive-rs" 10 | readme = "README.md" 11 | 12 | [dependencies.num-traits] 13 | version = "0.1.32" 14 | default-features = false 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Anders Kaseorg 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | “Software”), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # enum_primitive [![Build Status](https://travis-ci.org/andersk/enum_primitive-rs.svg?branch=master)](https://travis-ci.org/andersk/enum_primitive-rs) 2 | 3 | This crate exports a macro `enum_from_primitive!` that wraps an 4 | `enum` declaration and automatically adds an implementation of 5 | `num::FromPrimitive` (reexported here), to allow conversion from 6 | primitive integers to the enum. It therefore provides an 7 | alternative to the built-in `#[derive(FromPrimitive)]`, which 8 | requires the unstable `std::num::FromPrimitive` and is disabled in 9 | Rust 1.0. 10 | 11 | ## Documentation 12 | 13 | https://andersk.github.io/enum_primitive-rs/enum_primitive/ 14 | 15 | ## Usage 16 | 17 | Add the following to your `Cargo.toml` file: 18 | 19 | ``` 20 | [dependencies] 21 | enum_primitive = "*" 22 | ``` 23 | 24 | Import the crate using `#[macro_use] extern crate enum_primitive`, and 25 | wrap your `enum` declaration inside the `enum_from_primitive!` macro. 26 | 27 | ## Example 28 | 29 | ```rust 30 | #[macro_use] extern crate enum_primitive; 31 | extern crate num; 32 | use num::FromPrimitive; 33 | 34 | enum_from_primitive! { 35 | #[derive(Debug, PartialEq)] 36 | enum FooBar { 37 | Foo = 17, 38 | Bar = 42, 39 | Baz, 40 | } 41 | } 42 | 43 | fn main() { 44 | assert_eq!(FooBar::from_i32(17), Some(FooBar::Foo)); 45 | assert_eq!(FooBar::from_i32(42), Some(FooBar::Bar)); 46 | assert_eq!(FooBar::from_i32(43), Some(FooBar::Baz)); 47 | assert_eq!(FooBar::from_i32(91), None); 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /tests/image.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] extern crate enum_primitive; 2 | 3 | mod gif { 4 | enum_from_primitive! { 5 | /// Known block types 6 | enum Block { 7 | Image = 0x2C, 8 | Extension = 0x21, 9 | Trailer = 0x3B 10 | } 11 | } 12 | 13 | enum_from_primitive! { 14 | /// Known GIF extensions 15 | enum Extension { 16 | Text = 0x01, 17 | Control = 0xF9, 18 | Comment = 0xFE, 19 | Application = 0xFF 20 | } 21 | } 22 | 23 | enum_from_primitive! { 24 | /// Method to dispose the image 25 | enum DisposalMethod { 26 | Undefined = 0, 27 | None = 1, 28 | Previous = 2, 29 | Background = 3 30 | } 31 | } 32 | } 33 | 34 | mod png { 35 | enum_from_primitive! { 36 | #[derive(Clone, Copy, Debug, PartialEq)] 37 | enum InterlaceMethod { 38 | None = 0, 39 | Adam7 = 1 40 | } 41 | } 42 | 43 | enum_from_primitive! { 44 | #[derive(Debug)] 45 | pub enum FilterType { 46 | NoFilter = 0, 47 | Sub = 1, 48 | Up = 2, 49 | Avg = 3, 50 | Paeth = 4 51 | } 52 | } 53 | } 54 | 55 | mod tiff { 56 | enum_from_primitive! { 57 | #[derive(Clone, Copy, Debug, PartialEq)] 58 | enum PhotometricInterpretation { 59 | WhiteIsZero = 0, 60 | BlackIsZero = 1, 61 | RGB = 2, 62 | RGBPalette = 3, 63 | TransparencyMask = 4, 64 | CMYK = 5, 65 | YCbCr = 6, 66 | CIELab = 8, 67 | } 68 | } 69 | 70 | enum_from_primitive! { 71 | #[derive(Clone, Copy, Debug)] 72 | enum CompressionMethod { 73 | None = 1, 74 | Huffman = 2, 75 | Fax3 = 3, 76 | Fax4 = 4, 77 | LZW = 5, 78 | JPEG = 6, 79 | PackBits = 32773 80 | } 81 | } 82 | 83 | enum_from_primitive! { 84 | #[derive(Clone, Copy, Debug)] 85 | enum PlanarConfiguration { 86 | Chunky = 1, 87 | Planar = 2 88 | } 89 | } 90 | 91 | enum_from_primitive! { 92 | #[derive(Clone, Copy, Debug)] 93 | enum Predictor { 94 | None = 1, 95 | Horizontal = 2 96 | } 97 | } 98 | 99 | enum_from_primitive! { 100 | #[derive(Clone, Copy, Debug)] 101 | pub enum Type { 102 | BYTE = 1, 103 | ASCII = 2, 104 | SHORT = 3, 105 | LONG = 4, 106 | RATIONAL = 5, 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /tests/omitted-discriminants.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] extern crate enum_primitive; 2 | 3 | enum_from_primitive! { enum E { } } 4 | enum_from_primitive! { enum E0 { V0 } } 5 | enum_from_primitive! { enum E0C { V0, } } 6 | enum_from_primitive! { enum E1 { V0 = 0 } } 7 | enum_from_primitive! { enum E1C { V0 = 0, } } 8 | enum_from_primitive! { enum E00 { V0, V1 } } 9 | enum_from_primitive! { enum E00C { V0, V1, } } 10 | enum_from_primitive! { enum E01 { V0, V1 = 1 } } 11 | enum_from_primitive! { enum E01C { V0, V1 = 1, } } 12 | enum_from_primitive! { enum E10 { V0 = 0, V1 } } 13 | enum_from_primitive! { enum E10C { V0 = 0, V1, } } 14 | enum_from_primitive! { enum E11 { V0 = 0, V1 = 1 } } 15 | enum_from_primitive! { enum E11C { V0 = 0, V1 = 1, } } 16 | enum_from_primitive! { enum E000 { V0, V1, V2 } } 17 | enum_from_primitive! { enum E000C { V0, V1, V2, } } 18 | enum_from_primitive! { enum E001 { V0, V1, V2 = 2 } } 19 | enum_from_primitive! { enum E001C { V0, V1, V2 = 2, } } 20 | enum_from_primitive! { enum E010 { V0, V1 = 1, V2 } } 21 | enum_from_primitive! { enum E010C { V0, V1 = 1, V2, } } 22 | enum_from_primitive! { enum E011 { V0, V1 = 1, V2 = 2 } } 23 | enum_from_primitive! { enum E011C { V0, V1 = 1, V2 = 2, } } 24 | enum_from_primitive! { enum E100 { V0 = 0, V1, V2 } } 25 | enum_from_primitive! { enum E100C { V0 = 0, V1, V2, } } 26 | enum_from_primitive! { enum E101 { V0 = 0, V1, V2 = 2 } } 27 | enum_from_primitive! { enum E101C { V0 = 0, V1, V2 = 2, } } 28 | enum_from_primitive! { enum E110 { V0 = 0, V1 = 1, V2 } } 29 | enum_from_primitive! { enum E110C { V0 = 0, V1 = 1, V2, } } 30 | enum_from_primitive! { enum E111 { V0 = 0, V1 = 1, V2 = 2 } } 31 | enum_from_primitive! { enum E111C { V0 = 0, V1 = 1, V2 = 2, } } 32 | enum_from_primitive! { enum E0000 { V0, V1, V2, V3 } } 33 | enum_from_primitive! { enum E0000C { V0, V1, V2, V3, } } 34 | enum_from_primitive! { enum E0001 { V0, V1, V2, V3 = 3 } } 35 | enum_from_primitive! { enum E0001C { V0, V1, V2, V3 = 3, } } 36 | enum_from_primitive! { enum E0010 { V0, V1, V2 = 2, V3 } } 37 | enum_from_primitive! { enum E0010C { V0, V1, V2 = 2, V3, } } 38 | enum_from_primitive! { enum E0011 { V0, V1, V2 = 2, V3 = 3 } } 39 | enum_from_primitive! { enum E0011C { V0, V1, V2 = 2, V3 = 3, } } 40 | enum_from_primitive! { enum E0100 { V0, V1 = 1, V2, V3 } } 41 | enum_from_primitive! { enum E0100C { V0, V1 = 1, V2, V3, } } 42 | enum_from_primitive! { enum E0101 { V0, V1 = 1, V2, V3 = 3 } } 43 | enum_from_primitive! { enum E0101C { V0, V1 = 1, V2, V3 = 3, } } 44 | enum_from_primitive! { enum E0110 { V0, V1 = 1, V2 = 2, V3 } } 45 | enum_from_primitive! { enum E0110C { V0, V1 = 1, V2 = 2, V3, } } 46 | enum_from_primitive! { enum E0111 { V0, V1 = 1, V2 = 2, V3 = 3 } } 47 | enum_from_primitive! { enum E0111C { V0, V1 = 1, V2 = 2, V3 = 3, } } 48 | enum_from_primitive! { enum E1000 { V0 = 0, V1, V2, V3 } } 49 | enum_from_primitive! { enum E1000C { V0 = 0, V1, V2, V3, } } 50 | enum_from_primitive! { enum E1001 { V0 = 0, V1, V2, V3 = 3 } } 51 | enum_from_primitive! { enum E1001C { V0 = 0, V1, V2, V3 = 3, } } 52 | enum_from_primitive! { enum E1010 { V0 = 0, V1, V2 = 2, V3 } } 53 | enum_from_primitive! { enum E1010C { V0 = 0, V1, V2 = 2, V3, } } 54 | enum_from_primitive! { enum E1011 { V0 = 0, V1, V2 = 2, V3 = 3 } } 55 | enum_from_primitive! { enum E1011C { V0 = 0, V1, V2 = 2, V3 = 3, } } 56 | enum_from_primitive! { enum E1100 { V0 = 0, V1 = 1, V2, V3 } } 57 | enum_from_primitive! { enum E1100C { V0 = 0, V1 = 1, V2, V3, } } 58 | enum_from_primitive! { enum E1101 { V0 = 0, V1 = 1, V2, V3 = 3 } } 59 | enum_from_primitive! { enum E1101C { V0 = 0, V1 = 1, V2, V3 = 3, } } 60 | enum_from_primitive! { enum E1110 { V0 = 0, V1 = 1, V2 = 2, V3 } } 61 | enum_from_primitive! { enum E1110C { V0 = 0, V1 = 1, V2 = 2, V3, } } 62 | enum_from_primitive! { enum E1111 { V0 = 0, V1 = 1, V2 = 2, V3 = 3 } } 63 | enum_from_primitive! { enum E1111C { V0 = 0, V1 = 1, V2 = 2, V3 = 3, } } 64 | -------------------------------------------------------------------------------- /tests/tests.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] extern crate enum_primitive as ep; 2 | 3 | enum_from_primitive! { 4 | enum Unused { 5 | A = 17, 6 | B = 42 7 | } 8 | } 9 | 10 | enum_from_primitive! { 11 | #[derive(Debug, PartialEq)] 12 | enum Empty { 13 | } 14 | } 15 | 16 | #[test] 17 | fn empty() { 18 | use ep::FromPrimitive; 19 | assert_eq!(Empty::from_i32(91), None); 20 | } 21 | 22 | enum_from_primitive! { 23 | #[derive(Debug, PartialEq)] 24 | enum One { 25 | A = 17 26 | } 27 | } 28 | 29 | #[test] 30 | fn one() { 31 | use ep::FromPrimitive; 32 | assert_eq!(One::from_isize(17), Some(One::A)); 33 | assert_eq!(One::from_isize(91), None); 34 | assert_eq!(One::from_i8(17), Some(One::A)); 35 | assert_eq!(One::from_i8(91), None); 36 | assert_eq!(One::from_i16(17), Some(One::A)); 37 | assert_eq!(One::from_i16(91), None); 38 | assert_eq!(One::from_i32(17), Some(One::A)); 39 | assert_eq!(One::from_i32(91), None); 40 | assert_eq!(One::from_i64(17), Some(One::A)); 41 | assert_eq!(One::from_i64(91), None); 42 | assert_eq!(One::from_usize(17), Some(One::A)); 43 | assert_eq!(One::from_usize(91), None); 44 | assert_eq!(One::from_u8(17), Some(One::A)); 45 | assert_eq!(One::from_u8(91), None); 46 | assert_eq!(One::from_u16(17), Some(One::A)); 47 | assert_eq!(One::from_u16(91), None); 48 | assert_eq!(One::from_u32(17), Some(One::A)); 49 | assert_eq!(One::from_u32(91), None); 50 | assert_eq!(One::from_u64(17), Some(One::A)); 51 | assert_eq!(One::from_u64(91), None); 52 | } 53 | 54 | enum_from_primitive! { 55 | #[derive(Debug, PartialEq)] 56 | enum OneComma { 57 | A = 17, 58 | } 59 | } 60 | 61 | #[test] 62 | fn one_comma() { 63 | use ep::FromPrimitive; 64 | assert_eq!(OneComma::from_i32(17), Some(OneComma::A)); 65 | assert_eq!(OneComma::from_i32(91), None); 66 | } 67 | 68 | enum_from_primitive! { 69 | #[derive(Debug, PartialEq)] 70 | enum Two { 71 | A = 17, 72 | B = 42 73 | } 74 | } 75 | 76 | #[test] 77 | fn two() { 78 | use ep::FromPrimitive; 79 | assert_eq!(PubTwo::from_i32(17), Some(PubTwo::A)); 80 | assert_eq!(PubTwo::from_i32(42), Some(PubTwo::B)); 81 | assert_eq!(PubTwo::from_i32(91), None); 82 | } 83 | 84 | enum_from_primitive! { 85 | #[derive(Debug, PartialEq)] 86 | enum TwoComma { 87 | A = 17, 88 | B = 42, 89 | } 90 | } 91 | 92 | #[test] 93 | fn two_comma() { 94 | use ep::FromPrimitive; 95 | assert_eq!(TwoComma::from_i32(17), Some(TwoComma::A)); 96 | assert_eq!(TwoComma::from_i32(42), Some(TwoComma::B)); 97 | assert_eq!(TwoComma::from_i32(91), None); 98 | } 99 | 100 | enum_from_primitive! { 101 | #[derive(Debug, PartialEq)] 102 | pub enum PubEmpty { 103 | } 104 | } 105 | 106 | #[test] 107 | fn pub_empty() { 108 | use ep::FromPrimitive; 109 | assert_eq!(PubEmpty::from_i32(91), None); 110 | } 111 | 112 | enum_from_primitive! { 113 | #[derive(Debug, PartialEq)] 114 | pub enum PubOne { 115 | A = 17 116 | } 117 | } 118 | 119 | #[test] 120 | fn pub_one() { 121 | use ep::FromPrimitive; 122 | assert_eq!(PubOne::from_i32(17), Some(PubOne::A)); 123 | assert_eq!(PubOne::from_i32(91), None); 124 | } 125 | 126 | enum_from_primitive! { 127 | #[derive(Debug, PartialEq)] 128 | pub enum PubOneComma { 129 | A = 17, 130 | } 131 | } 132 | 133 | #[test] 134 | fn pub_one_comma() { 135 | use ep::FromPrimitive; 136 | assert_eq!(PubOneComma::from_i32(17), Some(PubOneComma::A)); 137 | assert_eq!(PubOneComma::from_i32(91), None); 138 | } 139 | 140 | enum_from_primitive! { 141 | #[derive(Debug, PartialEq)] 142 | pub enum PubTwo { 143 | A = 17, 144 | B = 42 145 | } 146 | } 147 | 148 | #[test] 149 | fn pub_two() { 150 | use ep::FromPrimitive; 151 | assert_eq!(PubTwo::from_i32(17), Some(PubTwo::A)); 152 | assert_eq!(PubTwo::from_i32(42), Some(PubTwo::B)); 153 | assert_eq!(PubTwo::from_i32(91), None); 154 | } 155 | 156 | enum_from_primitive! { 157 | #[derive(Debug, PartialEq)] 158 | pub enum PubTwoComma { 159 | A = 17, 160 | B = 42, 161 | } 162 | } 163 | 164 | #[test] 165 | fn pub_two_comma() { 166 | use ep::FromPrimitive; 167 | assert_eq!(PubTwoComma::from_i32(17), Some(PubTwoComma::A)); 168 | assert_eq!(PubTwoComma::from_i32(42), Some(PubTwoComma::B)); 169 | assert_eq!(PubTwoComma::from_i32(91), None); 170 | } 171 | 172 | enum_from_primitive! { 173 | #[derive(Debug, PartialEq)] 174 | enum Negative { 175 | A = -17 176 | } 177 | } 178 | 179 | #[test] 180 | fn negative() { 181 | use ep::FromPrimitive; 182 | assert_eq!(Negative::from_isize(-17), Some(Negative::A)); 183 | assert_eq!(Negative::from_isize(-91), None); 184 | assert_eq!(Negative::from_i8(-17), Some(Negative::A)); 185 | assert_eq!(Negative::from_i8(-91), None); 186 | assert_eq!(Negative::from_i16(-17), Some(Negative::A)); 187 | assert_eq!(Negative::from_i16(-91), None); 188 | assert_eq!(Negative::from_i32(-17), Some(Negative::A)); 189 | assert_eq!(Negative::from_i32(-91), None); 190 | assert_eq!(Negative::from_i64(-17), Some(Negative::A)); 191 | assert_eq!(Negative::from_i64(-91), None); 192 | assert_eq!(Negative::from_usize(!16), Some(Negative::A)); 193 | assert_eq!(Negative::from_usize(!90), None); 194 | assert_eq!(Negative::from_u8(!16), None); 195 | assert_eq!(Negative::from_u8(!90), None); 196 | assert_eq!(Negative::from_u16(!16), None); 197 | assert_eq!(Negative::from_u16(!90), None); 198 | assert_eq!(Negative::from_u32(!16), None); 199 | assert_eq!(Negative::from_u32(!90), None); 200 | assert_eq!(Negative::from_u64(!16), Some(Negative::A)); 201 | assert_eq!(Negative::from_u64(!90), None); 202 | } 203 | 204 | #[test] 205 | fn in_local_mod() { 206 | mod local_mod { 207 | enum_from_primitive! { 208 | #[derive(Debug, PartialEq)] 209 | pub enum InLocalMod { 210 | A = 17, 211 | B = 42, 212 | } 213 | } 214 | } 215 | 216 | use ep::FromPrimitive; 217 | assert_eq!(local_mod::InLocalMod::from_i32(17), Some(local_mod::InLocalMod::A)); 218 | assert_eq!(local_mod::InLocalMod::from_i32(42), Some(local_mod::InLocalMod::B)); 219 | assert_eq!(local_mod::InLocalMod::from_i32(91), None); 220 | } 221 | 222 | enum_from_primitive! { 223 | #[derive(Debug, PartialEq)] 224 | #[doc = "Documented"] 225 | pub enum Documented { 226 | A = 17 227 | } 228 | } 229 | 230 | #[test] 231 | fn documented() { 232 | use ep::FromPrimitive; 233 | assert_eq!(Documented::from_i32(17), Some(Documented::A)); 234 | assert_eq!(Documented::from_i32(91), None); 235 | } 236 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Anders Kaseorg 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // “Software”), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | 14 | // THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 23 | //! This crate exports a macro `enum_from_primitive!` that wraps an 24 | //! `enum` declaration and automatically adds an implementation of 25 | //! `num::FromPrimitive` (reexported here), to allow conversion from 26 | //! primitive integers to the enum. It therefore provides an 27 | //! alternative to the built-in `#[derive(FromPrimitive)]`, which 28 | //! requires the unstable `std::num::FromPrimitive` and is disabled in 29 | //! Rust 1.0. 30 | //! 31 | //! # Example 32 | //! 33 | //! ``` 34 | //! #[macro_use] extern crate enum_primitive; 35 | //! extern crate num_traits; 36 | //! use num_traits::FromPrimitive; 37 | //! 38 | //! enum_from_primitive! { 39 | //! #[derive(Debug, PartialEq)] 40 | //! enum FooBar { 41 | //! Foo = 17, 42 | //! Bar = 42, 43 | //! Baz, 44 | //! } 45 | //! } 46 | //! 47 | //! fn main() { 48 | //! assert_eq!(FooBar::from_i32(17), Some(FooBar::Foo)); 49 | //! assert_eq!(FooBar::from_i32(42), Some(FooBar::Bar)); 50 | //! assert_eq!(FooBar::from_i32(43), Some(FooBar::Baz)); 51 | //! assert_eq!(FooBar::from_i32(91), None); 52 | //! } 53 | //! ``` 54 | 55 | 56 | extern crate num_traits; 57 | 58 | pub use std::option::Option; 59 | pub use num_traits::FromPrimitive; 60 | 61 | /// Helper macro for internal use by `enum_from_primitive!`. 62 | #[macro_export] 63 | macro_rules! enum_from_primitive_impl_ty { 64 | ($meth:ident, $ty:ty, $name:ident, $( $variant:ident )*) => { 65 | #[allow(non_upper_case_globals, unused)] 66 | fn $meth(n: $ty) -> $crate::Option { 67 | $( if n == $name::$variant as $ty { 68 | $crate::Option::Some($name::$variant) 69 | } else )* { 70 | $crate::Option::None 71 | } 72 | } 73 | }; 74 | } 75 | 76 | /// Helper macro for internal use by `enum_from_primitive!`. 77 | #[macro_export] 78 | #[macro_use(enum_from_primitive_impl_ty)] 79 | macro_rules! enum_from_primitive_impl { 80 | ($name:ident, $( $variant:ident )*) => { 81 | impl $crate::FromPrimitive for $name { 82 | enum_from_primitive_impl_ty! { from_i64, i64, $name, $( $variant )* } 83 | enum_from_primitive_impl_ty! { from_u64, u64, $name, $( $variant )* } 84 | } 85 | }; 86 | } 87 | 88 | /// Wrap this macro around an `enum` declaration to get an 89 | /// automatically generated implementation of `num::FromPrimitive`. 90 | #[macro_export] 91 | #[macro_use(enum_from_primitive_impl)] 92 | macro_rules! enum_from_primitive { 93 | ( 94 | $( #[$enum_attr:meta] )* 95 | enum $name:ident { 96 | $( $( #[$variant_attr:meta] )* $variant:ident ),+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )* 97 | } 98 | ) => { 99 | $( #[$enum_attr] )* 100 | enum $name { 101 | $( $( #[$variant_attr] )* $variant ),+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )* 102 | } 103 | enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* } 104 | }; 105 | 106 | ( 107 | $( #[$enum_attr:meta] )* 108 | enum $name:ident { 109 | $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),* 110 | } 111 | ) => { 112 | $( #[$enum_attr] )* 113 | enum $name { 114 | $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),* 115 | } 116 | enum_from_primitive_impl! { $name, $( $( $variant )+ )* } 117 | }; 118 | 119 | ( 120 | $( #[$enum_attr:meta] )* 121 | enum $name:ident { 122 | $( $( #[$variant_attr:meta] )* $variant:ident ),+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*, 123 | } 124 | ) => { 125 | $( #[$enum_attr] )* 126 | enum $name { 127 | $( $( #[$variant_attr] )* $variant ),+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*, 128 | } 129 | enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* } 130 | }; 131 | 132 | ( 133 | $( #[$enum_attr:meta] )* 134 | enum $name:ident { 135 | $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+, 136 | } 137 | ) => { 138 | $( #[$enum_attr] )* 139 | enum $name { 140 | $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+, 141 | } 142 | enum_from_primitive_impl! { $name, $( $( $variant )+ )+ } 143 | }; 144 | 145 | ( 146 | $( #[$enum_attr:meta] )* 147 | pub enum $name:ident { 148 | $( $( #[$variant_attr:meta] )* $variant:ident ),+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )* 149 | } 150 | ) => { 151 | $( #[$enum_attr] )* 152 | pub enum $name { 153 | $( $( #[$variant_attr] )* $variant ),+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )* 154 | } 155 | enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* } 156 | }; 157 | 158 | ( 159 | $( #[$enum_attr:meta] )* 160 | pub enum $name:ident { 161 | $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),* 162 | } 163 | ) => { 164 | $( #[$enum_attr] )* 165 | pub enum $name { 166 | $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),* 167 | } 168 | enum_from_primitive_impl! { $name, $( $( $variant )+ )* } 169 | }; 170 | 171 | ( 172 | $( #[$enum_attr:meta] )* 173 | pub enum $name:ident { 174 | $( $( #[$variant_attr:meta] )* $variant:ident ),+ $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*, 175 | } 176 | ) => { 177 | $( #[$enum_attr] )* 178 | pub enum $name { 179 | $( $( #[$variant_attr] )* $variant ),+ $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*, 180 | } 181 | enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* } 182 | }; 183 | 184 | ( 185 | $( #[$enum_attr:meta] )* 186 | pub enum $name:ident { 187 | $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+, 188 | } 189 | ) => { 190 | $( #[$enum_attr] )* 191 | pub enum $name { 192 | $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+, 193 | } 194 | enum_from_primitive_impl! { $name, $( $( $variant )+ )+ } 195 | }; 196 | } 197 | --------------------------------------------------------------------------------