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,
// …
}
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,
// …
}
// …
unsafe {
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,
}
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
}
assert_eq!(size_of::<u8>(), size_of::<Test>());
Attribute Macros§
- The code generator