1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
use super::Value; use downcast_rs::Downcast; #[typetag::serde(tag = "StackVmObject")] pub trait StackVmObject: StackVmObjectClone + std::fmt::Debug + std::fmt::Display + Downcast { fn add(&self, r: Value) -> Result<Value, String>; } downcast_rs::impl_downcast!(StackVmObject); pub trait StackVmObjectClone { fn clone_box(&self) -> Box<dyn StackVmObject>; } impl<T> StackVmObjectClone for T where T: 'static + StackVmObject + Clone, { fn clone_box(&self) -> Box<dyn StackVmObject> { Box::new(self.clone()) } } impl Clone for Box<dyn StackVmObject> { fn clone(&self) -> Box<dyn StackVmObject> { self.clone_box() } } #[typetag::serde] impl StackVmObject for String { fn add(&self, r: Value) -> Result<Value, String> { let s: String = match r { Value::Object(o) => match o.downcast::<String>() { Ok(s) => format!("{}{}", self, s), Err(_) => return Err(format!("Can only add two strings together",)), }, _ => return Err(format!("Can only add two strings together")), }; Ok(Value::Object(Box::new(s))) } }