// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!! very unstable, use at your own risk !!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! use super::prelude::*; use std::ops::Fn; #[allow(non_upper_case_globals)] pub const void: () = (); pub struct Callback { function: FunctionType, } impl Callback { pub fn new(function: F) -> Callback where F: Fn(Args) -> (), F: 'static, FunctionType: FunctionTypeCreator, { Callback { function: FunctionType::new(function), } } pub fn execute(&self, arguments: Args) where FunctionType: FunctionTypeExecutorOneArg, { display_error!(self.function.execute(arguments)); } } pub trait FunctionTypeCreator () + 'static, Args> { fn new(function: F) -> FunctionType; } pub trait FunctionTypeExecutorOneArg { fn execute(&self, execute: Args) -> VerboseResult<()>; } macro_rules! build_function_type { ($struct_name: ident, $($ty: ty, $name: ident), *) => { pub enum $struct_name { $($name(Box)),* } $( impl () + 'static> FunctionTypeCreator for $struct_name { fn new(function: F) -> FunctionType { $struct_name::$name(Box::new(function)) } } impl FunctionTypeExecutorOneArg<$ty> for $struct_name { fn execute(&self, args: $ty) -> VerboseResult<()> { match self { FunctionType::$name(ref function) => { (function)(args); Ok(()) } _ => { create_error!("wrong argument type for this callback"); }, } } } ) * } } #[rustfmt::skip] build_function_type!( FunctionType, String, String, i32, I32, u32, U32, f32, F32, (), Void );