Expand description
Generate enum repr conversions compatible with type aliases.
Generate with #[EnumRepr(type = "TYPE")].
Functions generated are
fn repr(&self) -> EnumReprType
fn from_repr(x: EnumReprType) -> Option<Self>The real enum discriminant is usually forced to be #[repr(isize)].
If u* or i* types are used for the discriminant, the actual enum
representation is made to be #[repr(that_type_specified)].
The list of types recognized as u* and i* currently is as follows:
i8, i16, i32, i64, i128, u8, u16, u32, u64, u128.
If the type is specified through a type alias, #[repr(isize)] is used.
Inability to specify type aliases as enum representations is this crate’s
reason to exist.
The code generated does not require std.
Examples
extern crate enum_repr;
extern crate libc;
use libc::*;
use enum_repr::EnumRepr;
#[EnumRepr(type = "c_int")]
#[derive(Debug, PartialEq)]
pub enum IpProto {
IP = IPPROTO_IP,
IPv6 = IPPROTO_IPV6,
// …
}
fn main() {
assert_eq!(IpProto::IP.repr(), IPPROTO_IP);
assert_eq!(IpProto::from_repr(IPPROTO_IPV6), Some(IpProto::IPv6));
assert!(IpProto::from_repr(12345).is_none());
}#[EnumRepr(type = "c_int")]
pub enum InetDomain {
Inet = 2,
// …
}
#[EnumRepr(type = "c_int")]
pub enum SocketType {
Stream = 1,
// …
}
// …
assert!(
socket(InetDomain::Inet.repr(), SocketType::Stream.repr(), 0) != -1
);// compatible with documentation and other attributes
/// Represents a layer 3 network protocol.
#[EnumRepr(type = "c_int")]
#[derive(Debug, PartialEq)]
pub enum IpProto {
IP = IPPROTO_IP,
IPv6 = IPPROTO_IPV6,
// …
}Discriminants can be implicit if implicit = true:
#[EnumRepr(type = "c_int", implicit = true)]
#[derive(Debug, PartialEq)]
pub enum Test {
A,
B,
C = 5,
D,
}
fn main() {
assert_eq!(Test::B.repr(), 1);
assert_eq!(Test::from_repr(6), Some(Test::D));
assert!(Test::from_repr(2).is_none());
}Using implicit discriminants without setting the flag is an error:
#[EnumRepr(type = "c_int")]
pub enum Test {
A,
B = 3
}Take extra care to avoid collisions when using implicit discriminants:
#[EnumRepr(type = "u8", implicit = true)]
enum Test {
A = 1,
B,
C,
D = 3,
}Out of bound discriminants fail to compile:
#[EnumRepr(type = "u8")]
enum Test {
A = 256
}Even if they are implicit:
#[EnumRepr(type = "u8", implicit = true)]
enum Test {
A = 255,
B
}Discriminants of a wrong type fail to compile as well:
const C: u16 = 256;
#[EnumRepr(type = "u8")]
enum Test {
A = C
}Using the actual enum discriminant representation:
#[EnumRepr(type = "u8")]
#[derive(Debug, PartialEq)]
enum Test {
A = 1
}
fn main() {
assert_eq!(size_of::<u8>(), size_of::<Test>());
}