diff --git a/src/any.rs b/src/any.rs index a02604f1..49d27483 100644 --- a/src/any.rs +++ b/src/any.rs @@ -135,13 +135,13 @@ pub struct Dynamic(pub(crate) Union); pub enum Union { Unit(()), Bool(bool), - Str(String), + Str(Box), Char(char), Int(INT), #[cfg(not(feature = "no_float"))] Float(FLOAT), - Array(Array), - Map(Box), // Box it to reduce size + Array(Box), + Map(Box), Variant(Box), } @@ -324,15 +324,22 @@ impl Dynamic { cast_box::<_, Dynamic>(var) .map(|x| x.0) .or_else(|var| { - cast_box::<_, String>(var).map(Union::Str).or_else(|var| { - cast_box::<_, Array>(var).map(Union::Array).or_else(|var| { - cast_box::<_, Map>(var) - .map(|v| Union::Map(Box::new(v))) - .or_else(|var| -> Result { - Ok(Union::Variant(var as Box)) + cast_box::<_, String>(var) + .map(Box::new) + .map(Union::Str) + .or_else(|var| { + cast_box::<_, Array>(var) + .map(Box::new) + .map(Union::Array) + .or_else(|var| { + cast_box::<_, Map>(var) + .map(Box::new) + .map(Union::Map) + .or_else(|var| -> Result { + Ok(Union::Variant(var as Box)) + }) }) }) - }) }) .unwrap(), ) @@ -360,12 +367,16 @@ impl Dynamic { match &self.0 { Union::Unit(value) => (value as &dyn Variant).downcast_ref::().cloned(), Union::Bool(value) => (value as &dyn Variant).downcast_ref::().cloned(), - Union::Str(value) => (value as &dyn Variant).downcast_ref::().cloned(), + Union::Str(value) => (value.as_ref() as &dyn Variant) + .downcast_ref::() + .cloned(), Union::Char(value) => (value as &dyn Variant).downcast_ref::().cloned(), Union::Int(value) => (value as &dyn Variant).downcast_ref::().cloned(), #[cfg(not(feature = "no_float"))] Union::Float(value) => (value as &dyn Variant).downcast_ref::().cloned(), - Union::Array(value) => (value as &dyn Variant).downcast_ref::().cloned(), + Union::Array(value) => (value.as_ref() as &dyn Variant) + .downcast_ref::() + .cloned(), Union::Map(value) => (value.as_ref() as &dyn Variant) .downcast_ref::() .cloned(), @@ -404,12 +415,12 @@ impl Dynamic { match &self.0 { Union::Unit(value) => (value as &dyn Variant).downcast_ref::(), Union::Bool(value) => (value as &dyn Variant).downcast_ref::(), - Union::Str(value) => (value as &dyn Variant).downcast_ref::(), + Union::Str(value) => (value.as_ref() as &dyn Variant).downcast_ref::(), Union::Char(value) => (value as &dyn Variant).downcast_ref::(), Union::Int(value) => (value as &dyn Variant).downcast_ref::(), #[cfg(not(feature = "no_float"))] Union::Float(value) => (value as &dyn Variant).downcast_ref::(), - Union::Array(value) => (value as &dyn Variant).downcast_ref::(), + Union::Array(value) => (value.as_ref() as &dyn Variant).downcast_ref::(), Union::Map(value) => (value.as_ref() as &dyn Variant).downcast_ref::(), Union::Variant(value) => value.as_ref().downcast_ref::(), } @@ -426,12 +437,12 @@ impl Dynamic { match &mut self.0 { Union::Unit(value) => (value as &mut dyn Variant).downcast_mut::(), Union::Bool(value) => (value as &mut dyn Variant).downcast_mut::(), - Union::Str(value) => (value as &mut dyn Variant).downcast_mut::(), + Union::Str(value) => (value.as_mut() as &mut dyn Variant).downcast_mut::(), Union::Char(value) => (value as &mut dyn Variant).downcast_mut::(), Union::Int(value) => (value as &mut dyn Variant).downcast_mut::(), #[cfg(not(feature = "no_float"))] Union::Float(value) => (value as &mut dyn Variant).downcast_mut::(), - Union::Array(value) => (value as &mut dyn Variant).downcast_mut::(), + Union::Array(value) => (value.as_mut() as &mut dyn Variant).downcast_mut::(), Union::Map(value) => (value.as_mut() as &mut dyn Variant).downcast_mut::(), Union::Variant(value) => value.as_mut().downcast_mut::(), } @@ -477,7 +488,7 @@ impl Dynamic { /// Returns the name of the actual type if the cast fails. pub(crate) fn take_string(self) -> Result { match self.0 { - Union::Str(s) => Ok(s), + Union::Str(s) => Ok(*s), _ => Err(self.type_name()), } } @@ -499,7 +510,7 @@ impl Dynamic { Self(Union::Char(value)) } pub(crate) fn from_string(value: String) -> Self { - Self(Union::Str(value)) + Self(Union::Str(Box::new(value))) } } diff --git a/src/engine.rs b/src/engine.rs index 6c8f1b3e..6d7a165e 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1167,7 +1167,9 @@ impl Engine { Dynamic(Union::Map(rhs_value)) => { // Only allows String or char match lhs_value { - Dynamic(Union::Str(s)) => Ok(Dynamic::from_bool(rhs_value.contains_key(&s))), + Dynamic(Union::Str(s)) => { + Ok(Dynamic::from_bool(rhs_value.contains_key(s.as_ref()))) + } Dynamic(Union::Char(c)) => { Ok(Dynamic::from_bool(rhs_value.contains_key(&c.to_string()))) } @@ -1177,7 +1179,9 @@ impl Engine { Dynamic(Union::Str(rhs_value)) => { // Only allows String or char match lhs_value { - Dynamic(Union::Str(s)) => Ok(Dynamic::from_bool(rhs_value.contains(&s))), + Dynamic(Union::Str(s)) => { + Ok(Dynamic::from_bool(rhs_value.contains(s.as_ref()))) + } Dynamic(Union::Char(c)) => Ok(Dynamic::from_bool(rhs_value.contains(c))), _ => Err(Box::new(EvalAltResult::ErrorInExpr(lhs.position()))), } @@ -1314,7 +1318,7 @@ impl Engine { .map(|val| arr.push(val)) })?; - Ok(Dynamic(Union::Array(arr))) + Ok(Dynamic(Union::Array(Box::new(arr)))) } #[cfg(not(feature = "no_object"))] diff --git a/src/parser.rs b/src/parser.rs index 978de38d..802f8679 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -330,12 +330,14 @@ impl Expr { Self::False(_) => Dynamic::from_bool(false), Self::Unit(_) => Dynamic::from_unit(), - Self::Array(items, _) if items.iter().all(Self::is_constant) => Dynamic(Union::Array( - items - .iter() - .map(Self::get_constant_value) - .collect::>(), - )), + Self::Array(items, _) if items.iter().all(Self::is_constant) => { + Dynamic(Union::Array(Box::new( + items + .iter() + .map(Self::get_constant_value) + .collect::>(), + ))) + } Self::Map(items, _) if items.iter().all(|(_, v, _)| v.is_constant()) => { Dynamic(Union::Map(Box::new( @@ -1818,7 +1820,7 @@ pub fn map_dynamic_to_expr(value: Dynamic, pos: Position) -> Option { Union::Unit(_) => Some(Expr::Unit(pos)), Union::Int(value) => Some(Expr::IntegerConstant(value, pos)), Union::Char(value) => Some(Expr::CharConstant(value, pos)), - Union::Str(value) => Some(Expr::StringConstant(value.into(), pos)), + Union::Str(value) => Some(Expr::StringConstant((*value).into(), pos)), Union::Bool(true) => Some(Expr::True(pos)), Union::Bool(false) => Some(Expr::False(pos)), #[cfg(not(feature = "no_index"))]