diff --git a/src/any.rs b/src/any.rs index 6a5d9050..3b42acf8 100644 --- a/src/any.rs +++ b/src/any.rs @@ -550,8 +550,15 @@ impl Dynamic { /// Convert the `Dynamic` into `String` and return it. /// Returns the name of the actual type if the cast fails. pub fn take_string(self) -> Result { + self.take_immutable_string() + .map(ImmutableString::into_owned) + } + + /// Convert the `Dynamic` into `ImmutableString` and return it. + /// Returns the name of the actual type if the cast fails. + pub(crate) fn take_immutable_string(self) -> Result { match self.0 { - Union::Str(s) => Ok(s.into_owned()), + Union::Str(s) => Ok(s), _ => Err(self.type_name()), } } @@ -615,7 +622,7 @@ impl From> for Dynamic { Self(Union::Map(Box::new( value .into_iter() - .map(|(k, v)| (k, Dynamic::from(v))) + .map(|(k, v)| (k.into(), Dynamic::from(v))) .collect(), ))) } diff --git a/src/engine.rs b/src/engine.rs index f1260824..4a473b42 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -38,7 +38,7 @@ pub type Array = Vec; /// /// Not available under the `no_object` feature. #[cfg(not(feature = "no_object"))] -pub type Map = HashMap; +pub type Map = HashMap; #[cfg(not(feature = "unchecked"))] #[cfg(debug_assertions)] @@ -1389,7 +1389,7 @@ impl Engine { // val_map[idx] Ok(if create { let index = idx - .take_string() + .take_immutable_string() .map_err(|_| EvalAltResult::ErrorStringIndexExpr(idx_pos))?; map.entry(index).or_insert(Default::default()).into() @@ -1398,7 +1398,7 @@ impl Engine { .downcast_ref::() .ok_or_else(|| EvalAltResult::ErrorStringIndexExpr(idx_pos))?; - map.get_mut(index) + map.get_mut(index.as_str()) .map(Target::from) .unwrap_or_else(|| Target::from(())) }) @@ -1498,7 +1498,9 @@ impl Engine { Dynamic(Union::Map(rhs_value)) => match lhs_value { // Only allows String or char Dynamic(Union::Str(s)) => Ok(rhs_value.contains_key(s.as_str()).into()), - Dynamic(Union::Char(c)) => Ok(rhs_value.contains_key(&c.to_string()).into()), + Dynamic(Union::Char(c)) => { + Ok(rhs_value.contains_key(c.to_string().as_str()).into()) + } _ => Err(Box::new(EvalAltResult::ErrorInExpr(lhs.position()))), }, Dynamic(Union::Str(rhs_value)) => match lhs_value { diff --git a/src/optimize.rs b/src/optimize.rs index 7895fc68..6acdcc2b 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -408,7 +408,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr { // All other items can be thrown away. state.set_dirty(); let pos = m.1; - m.0.into_iter().find(|((name, _), _)| name == prop) + m.0.into_iter().find(|((name, _), _)| name.as_str() == prop) .map(|(_, expr)| expr.set_position(pos)) .unwrap_or_else(|| Expr::Unit(pos)) } @@ -434,7 +434,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr { // All other items can be thrown away. state.set_dirty(); let pos = m.1; - m.0.into_iter().find(|((name, _), _)| name == s.0.as_ref()) + m.0.into_iter().find(|((name, _), _)| *name == s.0) .map(|(_, expr)| expr.set_position(pos)) .unwrap_or_else(|| Expr::Unit(pos)) } @@ -472,7 +472,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr { // "xxx" in #{...} (Expr::StringConstant(a), Expr::Map(b)) => { state.set_dirty(); - if b.0.iter().find(|((name, _), _)| name == a.0.as_ref()).is_some() { + if b.0.iter().find(|((name, _), _)| *name == a.0).is_some() { Expr::True(a.1) } else { Expr::False(a.1) @@ -483,7 +483,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr { state.set_dirty(); let ch = a.0.to_string(); - if b.0.iter().find(|((name, _), _)| name == &ch).is_some() { + if b.0.iter().find(|((name, _), _)| name.as_str() == ch.as_str()).is_some() { Expr::True(a.1) } else { Expr::False(a.1) diff --git a/src/packages/map_basic.rs b/src/packages/map_basic.rs index 9be0fb42..1488e655 100644 --- a/src/packages/map_basic.rs +++ b/src/packages/map_basic.rs @@ -6,10 +6,10 @@ use crate::engine::Map; use crate::module::FuncReturn; use crate::parser::{ImmutableString, INT}; -use crate::stdlib::{string::ToString, vec::Vec}; +use crate::stdlib::vec::Vec; fn map_get_keys(map: &mut Map) -> FuncReturn> { - Ok(map.iter().map(|(k, _)| k.to_string().into()).collect()) + Ok(map.iter().map(|(k, _)| k.clone().into()).collect()) } fn map_get_values(map: &mut Map) -> FuncReturn> { Ok(map.iter().map(|(_, v)| v.clone()).collect()) diff --git a/src/parser.rs b/src/parser.rs index 5d0bd902..1f856791 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -464,7 +464,7 @@ pub enum Expr { /// [ expr, ... ] Array(Box<(StaticVec, Position)>), /// #{ name:expr, ... } - Map(Box<(StaticVec<((String, Position), Expr)>, Position)>), + Map(Box<(StaticVec<((ImmutableString, Position), Expr)>, Position)>), /// lhs in rhs In(Box<(Expr, Expr, Position)>), /// lhs && rhs @@ -1196,7 +1196,7 @@ fn parse_map_literal( } let expr = parse_expr(input, state, settings.level_up())?; - map.push(((name, pos), expr)); + map.push(((Into::::into(name), pos), expr)); } }