4 releases (2 breaking)
0.3.1 | Apr 16, 2024 |
---|---|
0.3.0 | Aug 19, 2021 |
0.2.0 | Jul 17, 2021 |
0.1.0 | Nov 24, 2020 |
#342 in Procedural macros
903 downloads per month
Used in 7 crates
(3 directly)
31KB
448 lines
enumber
enumber
is a procedural macro crate which helps you to work with enums whose
purpose it is to represent numbers (for example when parsing complex binary
logs) or strange wire protocols.
#[enumber::convert]
pub enum Flags {
EnableCompression = 1,
EnableTLS = 2,
Other(usize),
}
lib.rs
:
Numerical enumerations
The enumber
crate provides a mechanism for deriving a lot of useful helpers
for your enumerations which are sets of numbers. Its main purpose is to
provide convenience implementations of a number of useful traits for your
enumerations automatically.
See the [convert
][macro@convert] macro and [into
][macro@into]
macro for details, however here is a basic example:
#[enumber::convert]
#[repr(usize)]
enum Simple {
Foo = 1,
Bar = 2,
}
use std::convert::TryFrom;
// You can use try_from() to go from a suitable number to an instance of
// your enumeration.
assert!(matches!(Simple::try_from(1), Ok(Simple::Foo)));
// You can convert from instances of your enumeration to a number.
assert_eq!(2 as usize, Simple::Bar.into());
// You can render instances of your enumeration to strings.
assert_eq!(&format!("{}", Simple::Foo), "Foo");
// And you can convert from a string to your enumeration, using the names
// of the enumeration items (case insensitively) or by number. If the
// name or number is invalid, you'll get an error.
use std::str::FromStr;
assert!(matches!(Simple::from_str("Foo"), Ok(Simple::Foo)));
assert!(matches!(Simple::from_str("bAr"), Ok(Simple::Bar)));
assert!(matches!(Simple::from_str("1"), Ok(Simple::Foo)));
assert!(matches!(Simple::from_str("0x02"), Ok(Simple::Bar)));
assert!(matches!(Simple::from_str("3"), Err(ParseSimpleError::UnknownValue(_))));
assert!(matches!(Simple::from_str("wibble"), Err(ParseSimpleError::UnknownName(_))));
The [into
][macro@into] macro only implements From
. But,
unlike the [convert
][macro@convert] macro, it is able to convert
variants with data to a value. (It can't convert values to
variants, because the data is missing.) This is helpful, for
instance, for converting rich error types to simple error codes at
an FFI boundary.
#[enumber::into]
#[repr(usize)]
enum Errors {
Success = 0,
#[value(0x10)] NotDefined(String),
InvalidArg(String, String) = 0x20,
OpNotSupported = 0x30,
}
// You can convert from instances of your enumeration to a number.
assert_eq!(0 as usize, Errors::Success.into());
assert_eq!(0x10 as usize, Errors::NotDefined("a".into()).into());
assert_eq!(0x10 as usize, Errors::NotDefined("123".into()).into());
assert_eq!(0x20 as usize, Errors::InvalidArg("a".into(), "123".into()).into());
assert_eq!(0x30 as usize, Errors::OpNotSupported.into());
Dependencies
~225–660KB
~16K SLoC