Crate enum_repr

source ·
Expand description

Derive enum repr conversions compatible with type aliases.

Derive with #[derive(EnumRepr)]. The repr type is set by #[EnumReprType = "..."].

Functions fn repr(&self) -> EnumReprType and fn from_repr(x: EnumReprType) -> Option<Self> are generated. The real enum discriminant still remains isize.

The code generated does not require std.

Examples

#[macro_use] extern crate enum_repr;
extern crate libc;

use libc::*;

#[derive(Debug, PartialEq)]
#[derive(EnumRepr)]
#[EnumReprType = "c_int"]
pub enum IpProto {
    IP = IPPROTO_IP as isize,
    IPv6 = IPPROTO_IPV6 as isize,
    // …
}

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());
}
#[derive(EnumRepr)]
#[EnumReprType = "c_int"]
pub enum InetDomain {
    Inet = 2,
    // …
}

#[derive(EnumRepr)]
#[EnumReprType = "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.
#[derive(Debug, PartialEq)]
#[derive(EnumRepr)]
#[EnumReprType = "c_int"]
pub enum IpProto {
    IP = IPPROTO_IP as isize,
    IPv6 = IPPROTO_IPV6 as isize,
    // …
}

Limitations

No warnings are produced if out-of-bounds integer literals are specified. E.g, a variant like A = 65537 would compile with EnumReprType = "u16" silently:

#[derive(PartialEq)]
#[derive(EnumRepr)]
#[EnumReprType = "u16"]
enum En {
    A = 65537
}

The solution is to use the A = 65537u16 as isize form or a named constant. E.g.,

#![deny(overflowing_literals)]

#[derive(PartialEq)]
#[derive(EnumRepr)]
#[EnumReprType = "u16"]
enum En {
    A = 65537u16 as isize
}

fails to compile.

Derive Macros

The derivation function