macro_rules! register_funcs {
(
($main_func_type_ident: ident, $main_func_ident: ident) {
$(
$current_func_type_ident: ident {
$current_func_none_ident: ident,
$current_func_input_ident: ident,
$current_func_output_ident: ident,
$current_func_input_output_ident: ident
}
),+
}
) => {
#[derive(Clone)]
pub enum $main_func_ident {
$(
$current_func_none_ident($current_func_none_ident),
$current_func_input_ident($current_func_input_ident),
$current_func_output_ident($current_func_output_ident),
$current_func_input_output_ident($current_func_input_output_ident)
),+
}
impl $main_func_ident {
pub unsafe fn new(dll: &LibArc, symbol: &String, func_type: $main_func_type_ident, has_input: bool, has_output: bool) -> Result<Self> {
match func_type {
$(
$main_func_type_ident::$current_func_type_ident => {
let result =
if has_input {
if has_output {
let func = try!($current_func_input_output_ident::new(dll, symbol));
$main_func_ident::from(func)
} else {
let func = try!($current_func_input_ident::new(dll, symbol));
$main_func_ident::from(func)
}
} else if has_output {
let func = try!($current_func_output_ident::new(dll, symbol));
$main_func_ident::from(func)
} else {
let func = try!($current_func_none_ident::new(dll, symbol));
$main_func_ident::from(func)
};
Ok(result)
}
),+
}
}
pub fn enum_to_string(&self) -> &'static str {
match self {
$(
&$main_func_ident::$current_func_none_ident(_) => {
stringify!($main_func_ident::$current_func_none_ident)
},
&$main_func_ident::$current_func_input_ident(_) => {
stringify!($main_func_ident::$current_func_input_ident)
},
&$main_func_ident::$current_func_output_ident(_) => {
stringify!($main_func_ident::$current_func_output_ident)
},
&$main_func_ident::$current_func_input_output_ident(_) => {
stringify!($main_func_ident::$current_func_input_output_ident)
}
),+
}
}
}
$(
impl From<$current_func_none_ident> for $main_func_ident {
fn from(func: $current_func_none_ident) -> $main_func_ident {
$main_func_ident::$current_func_none_ident(func)
}
}
impl From<$current_func_input_ident> for $main_func_ident {
fn from(func: $current_func_input_ident) -> $main_func_ident {
$main_func_ident::$current_func_input_ident(func)
}
}
impl From<$current_func_output_ident> for $main_func_ident {
fn from(func: $current_func_output_ident) -> $main_func_ident {
$main_func_ident::$current_func_output_ident(func)
}
}
impl From<$current_func_input_output_ident> for $main_func_ident {
fn from(func: $current_func_input_output_ident) -> $main_func_ident {
$main_func_ident::$current_func_input_output_ident(func)
}
}
impl From<$main_func_ident> for Result<$current_func_none_ident> {
fn from(func: $main_func_ident) -> Result<$current_func_none_ident> {
match func {
$main_func_ident::$current_func_none_ident(func) => Ok(func),
func => {
Err(
ErrorKind::FuncConversionFailure(
func.enum_to_string().to_string(),
stringify!($main_func_ident::$current_func_none_ident).to_string(),
).into()
)
},
}
}
}
impl From<$main_func_ident> for Result<$current_func_input_ident> {
fn from(func: $main_func_ident) -> Result<$current_func_input_ident> {
match func {
$main_func_ident::$current_func_input_ident(func) => Ok(func),
func => {
Err(
ErrorKind::FuncConversionFailure(
func.enum_to_string().to_string(),
stringify!($main_func_ident::$current_func_input_ident).to_string(),
).into()
)
},
}
}
}
impl From<$main_func_ident> for Result<$current_func_output_ident> {
fn from(func: $main_func_ident) -> Result<$current_func_output_ident> {
match func {
$main_func_ident::$current_func_output_ident(func) => Ok(func),
func => {
Err(
ErrorKind::FuncConversionFailure(
func.enum_to_string().to_string(),
stringify!($main_func_ident::$current_func_output_ident).to_string(),
).into()
)
},
}
}
}
impl From<$main_func_ident> for Result<$current_func_input_output_ident> {
fn from(func: $main_func_ident) -> Result<$current_func_input_output_ident> {
match func {
$main_func_ident::$current_func_input_output_ident(func) => Ok(func),
func => {
Err(
ErrorKind::FuncConversionFailure(
func.enum_to_string().to_string(),
stringify!($main_func_ident::$current_func_input_output_ident).to_string(),
).into()
)
},
}
}
}
)+
}
}