use std::any::Any; use std::boxed::Box; use engine::{EvalError, Engine}; pub trait FnRegister { fn register(self, engine: &mut Engine, name: &str); } impl FnRegister for fn(&mut T, U)->V { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box, &mut Box)->Result, EvalError>> = Box::new( move |x: &mut Box, y: &mut Box| { let inside1 = (*x).downcast_mut() as Option<&mut T>; let inside2 = (*y).downcast_mut() as Option<&mut U>; match (inside1, inside2) { (Some(b), Some(c)) => Ok(Box::new(self(b, c.clone())) as Box), _ => Err(EvalError::FunctionArgMismatch) } } ); let ent = engine.fns_arity_2.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(wrapped); } } impl FnRegister for fn(T, U)->V { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box, &mut Box)->Result, EvalError>> = Box::new( move |x: &mut Box, y: &mut Box| { let inside1 = (*x).downcast_mut() as Option<&mut T>; let inside2 = (*y).downcast_mut() as Option<&mut U>; match (inside1, inside2) { (Some(b), Some(c)) => Ok(Box::new(self(b.clone(), c.clone())) as Box), _ => Err(EvalError::FunctionArgMismatch) } } ); let ent = engine.fns_arity_2.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(wrapped); } } impl FnRegister for fn(&mut T)->U { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box)->Result, EvalError>> = Box::new( move |x: &mut Box| { let inside = (*x).downcast_mut() as Option<&mut T>; match inside { Some(b) => Ok(Box::new(self(b)) as Box), None => Err(EvalError::FunctionArgMismatch) } } ); let ent = engine.fns_arity_1.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(wrapped); } } impl FnRegister for fn(T)->U { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box)->Result, EvalError>> = Box::new( move |x: &mut Box| { let inside = (*x).downcast_mut() as Option<&mut T>; match inside { Some(b) => Ok(Box::new(self(b.clone())) as Box), None => Err(EvalError::FunctionArgMismatch) } } ); let ent = engine.fns_arity_1.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(wrapped); } } impl FnRegister for fn()->T { fn register(self, engine: &mut Engine, name: &str) { let wrapped : BoxResult, EvalError>> = Box::new( move || { Ok(Box::new(self()) as Box) } ); let ent = engine.fns_arity_0.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(wrapped); } }