diff options
author | David Tolnay <dtolnay@chromium.org> | 2018-12-06 01:58:21 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-12-07 17:35:43 -0800 |
commit | f97991985d6921375eb5a533c49fd7df5a75d2cd (patch) | |
tree | 52278731797f91cb0d42b5c81ba545acaaae9b53 /enumn/Cargo.toml | |
parent | 1d4d44a8e229d63aa16d05615ed33100f949863e (diff) | |
download | crosvm-f97991985d6921375eb5a533c49fd7df5a75d2cd.tar crosvm-f97991985d6921375eb5a533c49fd7df5a75d2cd.tar.gz crosvm-f97991985d6921375eb5a533c49fd7df5a75d2cd.tar.bz2 crosvm-f97991985d6921375eb5a533c49fd7df5a75d2cd.tar.lz crosvm-f97991985d6921375eb5a533c49fd7df5a75d2cd.tar.xz crosvm-f97991985d6921375eb5a533c49fd7df5a75d2cd.tar.zst crosvm-f97991985d6921375eb5a533c49fd7df5a75d2cd.zip |
macros: Derive macro to generate integer to enum conversion
This CL adds a procedural macro to generate functions for converting a primitive integer into the corresponding variant of an enum. Loosely based on https://docs.rs/enum-primitive-derive but implemented against a newer version of Syn and without the dependency on num-traits. The generated function is named `n` and has the following signature: impl YourEnum { pub fn n(value: Repr) -> Option<Self>; } where `Repr` is an integer type of the right size as described in more detail below. EXAMPLE extern crate enumn; #[derive(PartialEq, Debug, enumn::N)] enum Status { LegendaryTriumph, QualifiedSuccess, FortuitousRevival, IndeterminateStalemate, RecoverableSetback, DireMisadventure, AbjectFailure, } fn main() { let s = Status::n(1); assert_eq!(s, Some(Status::QualifiedSuccess)); let s = Status::n(9); assert_eq!(s, None); } SIGNATURE The generated signature depends on whether the enum has a `#[repr(..)]` attribute. If a `repr` is specified, the input to `n` will be required to be of that type. #[derive(enumn::N)] #[repr(u8)] enum E { /* ... */ } // expands to: impl E { pub fn n(value: u8) -> Option<Self> { /* ... */ } } On the other hand if no `repr` is specified then we get a signature that is generic over a variety of possible types. impl E { pub fn n<REPR: Into<i64>>(value: REPR) -> Option<Self> { /* ... */ } } DISCRIMINANTS The conversion respects explictly specified enum discriminants. Consider this enum: #[derive(enumn::N)] enum Letter { A = 65, B = 66, } Here `Letter::n(65)` would return `Some(Letter::A)`. TEST=`cargo test` against the new crate Change-Id: I4286a816828c83507b35185fe497455ee30ae9e8 Reviewed-on: https://chromium-review.googlesource.com/1365114 Commit-Ready: David Tolnay <dtolnay@chromium.org> Tested-by: David Tolnay <dtolnay@chromium.org> Reviewed-by: Chirantan Ekbote <chirantan@chromium.org> Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'enumn/Cargo.toml')
-rw-r--r-- | enumn/Cargo.toml | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/enumn/Cargo.toml b/enumn/Cargo.toml new file mode 100644 index 0000000..84649ca --- /dev/null +++ b/enumn/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "enumn" +version = "0.1.0" +authors = ["The Chromium OS Authors"] + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "0.4" +quote = "0.6" +syn = "0.15" |