From 3cd0aa4f55c7255f07088824817de535566c8771 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Wed, 25 Sep 2019 00:19:04 -0400 Subject: [PATCH] Add in Rust-y bindings for some of the `#define` constants --- aeron_driver-sys/bindings.h | 3 ++- aeron_driver-sys/build.rs | 1 + aeron_driver-sys/src/lib.rs | 50 +++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/aeron_driver-sys/bindings.h b/aeron_driver-sys/bindings.h index 39072ee..686e2df 100644 --- a/aeron_driver-sys/bindings.h +++ b/aeron_driver-sys/bindings.h @@ -1,3 +1,4 @@ #include -#include #include +#include +#include diff --git a/aeron_driver-sys/build.rs b/aeron_driver-sys/build.rs index 33643f4..451b4b2 100644 --- a/aeron_driver-sys/build.rs +++ b/aeron_driver-sys/build.rs @@ -97,6 +97,7 @@ pub fn main() { .header("bindings.h") .whitelist_function("aeron_.*") .whitelist_type("aeron_.*") + .whitelist_var("AERON_.*") .constified_enum_module("aeron_.*_enum") .generate() .expect("Unable to generate aeron_driver bindings"); diff --git a/aeron_driver-sys/src/lib.rs b/aeron_driver-sys/src/lib.rs index 9f6426e..cefe986 100644 --- a/aeron_driver-sys/src/lib.rs +++ b/aeron_driver-sys/src/lib.rs @@ -4,8 +4,50 @@ #![allow(clippy::all)] include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +/// Construct a C-compatible enum out of a set of constants. +/// Commonly used for types in Aeron that have fixed values via `#define`, +/// but aren't actually enums (e.g. AERON_COMMAND_.*, AERON_ERROR_CODE_.*). +/// Behavior is ultimately very similar to `num::FromPrimitive`. +macro_rules! define_enum { + ($(#[$outer:meta])*, $name:ident, [$(($left:ident, $right:expr)),*]) => { + #[repr(u32)] + #[derive(Debug, PartialEq)] + $(#[$outer])* + pub enum $name { + $($left = $right),* + } + + impl ::std::convert::TryFrom for $name { + type Error = (); + fn try_from(val: u32) -> Result<$name, ()> { + match val { + $(v if v == $name::$left as u32 => Ok($name::$left)),*, + _ => Err(()) + } + } + } + } +} + +define_enum!( + #[doc = "Command codes used when interacting with the Media Driver"], + AeronCommand, [ + (AddPublication, AERON_COMMAND_ADD_PUBLICATION), + (RemovePublication, AERON_COMMAND_REMOVE_PUBLICATION) + ] +); + +define_enum!( + #[doc = "Command codes used when interacting with the Media Driver"], + AeronErrorCode, [ + (GenericError, AERON_ERROR_CODE_GENERIC_ERROR) + ] +); + #[cfg(test)] mod tests { + use crate::*; + use std::convert::TryInto; #[test] fn version_check() { @@ -16,4 +58,12 @@ mod tests { assert_eq!(minor, 21); assert_eq!(patch, 2); } + + #[test] + fn define_enum_try() { + assert_eq!( + Ok(AeronCommand::AddPublication), + AERON_COMMAND_ADD_PUBLICATION.try_into() + ); + } }