binding/src/c_enum.rs

105 lines
2.6 KiB
Rust
Raw Normal View History

2017-01-06 19:10:10 -05:00
/// Create a C exportable enum. These are useful for working with C FFIs.
///
/// As C has no idea about tuples or structs enums
/// using this macro must only contain Unit variants.
#[macro_export]
macro_rules! c_enum
{
{
$(#[$attribute: meta])* enum $name: ident : $fieldType: ty
{
$(
$(#[$variantAttribute: meta])*
variant $variant: ident = $value: expr
),*
}
} =>
{
$(#[$attribute])*
#[repr(C)]
pub enum $name
{
$($(#[$variantAttribute])* $variant = $value,)*
}
impl $name
{
/// Generate a variant of the enum from a given value.
///
/// This is not very performant. Becareful when using this
/// to not use this in a high performance loop.
pub fn from_value(val: $fieldType) -> Option<$name>
{
// This would be better as a match statement, but
// unfortunately, it needs to be a giant set of if
// statements since we only have the expression type
// to work with, not a pattern type.
/*
match val
{
$($value => {Some($name::$variant)})*
_ => {None}
}
*/
$(if val == $value {return Some($name::$variant);})*
// No variant was found.
None
}
/// 'true', if the given value matches a variant
/// of the enumeration; Otherwise, 'false'.
pub fn is_valid_value(val: $fieldType) -> bool
{
match $name::from_value(val)
{
Some(_) =>
{
true
}
None =>
{
false
}
}
}
/// Turn an enum variant into a value.
pub fn to_value(&self) -> $fieldType
{
match *self
{
$($name::$variant => {$value})*
}
}
/// Get a str representation of this variant.
pub fn to_str(&self) -> &'static str
{
match *self
{
$($name::$variant => {stringify!($variant)})*
}
}
}
impl ::std::fmt::Debug for $name
{
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
{
write!(f, "{}", self.to_str())
}
}
impl ::std::fmt::Display for $name
{
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
{
write!(f, "{}", self.to_str())
}
}
}
}