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)->W { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box, &mut Box, &mut Box)->Result, EvalError>> = Box::new( move |x: &mut Box, y: &mut Box, z: &mut Box| { let inside1 = (*x).downcast_mut() as Option<&mut T>; let inside2 = (*y).downcast_mut() as Option<&mut U>; let inside3 = (*z).downcast_mut() as Option<&mut V>; match (inside1, inside2, inside3) { (Some(b), Some(c), Some(d)) => Ok(Box::new(self(b, c.clone(), d.clone())) as Box), _ => Err(EvalError::FunctionArgMismatch) } } ); let ent = engine.fns_arity_3.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(wrapped); } } impl FnRegister for fn(T, U, V)->W { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box, &mut Box, &mut Box)->Result, EvalError>> = Box::new( move |x: &mut Box, y: &mut Box, z: &mut Box| { let inside1 = (*x).downcast_mut() as Option<&mut T>; let inside2 = (*y).downcast_mut() as Option<&mut U>; let inside3 = (*z).downcast_mut() as Option<&mut V>; match (inside1, inside2, inside3) { (Some(b), Some(c), Some(d)) => Ok(Box::new(self(b.clone(), c.clone(), d.clone())) as Box), _ => Err(EvalError::FunctionArgMismatch) } } ); let ent = engine.fns_arity_3.entry(name.to_string()).or_insert(Vec::new()); (*ent).push(wrapped); } } 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); } }