diff --git a/RELEASES.md b/RELEASES.md index bd1b91fb..34b1b597 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -9,10 +9,15 @@ Bug fixes * Bug in `Position::is_beginning_of_line` is fixed. -Enhancements +New features ------------ * Comparisons between `FLOAT`/[`Decimal`](https://crates.io/crates/rust_decimal) and `INT` are now built in. + +Enhancements +------------ + +* Built-in operators between `FLOAT`/[`Decimal`](https://crates.io/crates/rust_decimal) and `INT` are now implemented for more speed under those cases. * Error position in `eval` statements is now wrapped in an `EvalAltResult::ErrorInFunctionCall`. * `Position` now implements `Add` and `AddAssign`. * `Scope` now implements `IntoIterator`. diff --git a/src/fn_call.rs b/src/fn_call.rs index b0573dfe..98251113 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -32,6 +32,9 @@ use crate::FLOAT; #[cfg(not(feature = "no_object"))] use crate::Map; +#[cfg(feature = "decimal")] +use rust_decimal::Decimal; + #[cfg(feature = "no_std")] #[cfg(not(feature = "no_float"))] use num_traits::float::Float; @@ -1347,33 +1350,115 @@ pub fn run_builtin_binary_op( x: &Dynamic, y: &Dynamic, ) -> Result, Box> { - let args_type = x.type_id(); + let first_type = x.type_id(); let second_type = y.type_id(); - if second_type != args_type { - if args_type == TypeId::of::() && second_type == TypeId::of::() { + let type_id = (first_type, second_type); + + #[cfg(not(feature = "no_float"))] + if let Some((x, y)) = if type_id == (TypeId::of::(), TypeId::of::()) { + Some((x.clone().cast::(), y.clone().cast::())) + } else if type_id == (TypeId::of::(), TypeId::of::()) { + Some((x.clone().cast::(), y.clone().cast::() as FLOAT)) + } else if type_id == (TypeId::of::(), TypeId::of::()) { + Some((x.clone().cast::() as FLOAT, y.clone().cast::())) + } else { + None + } { + match op { + "+" => return Ok(Some((x + y).into())), + "-" => return Ok(Some((x - y).into())), + "*" => return Ok(Some((x * y).into())), + "/" => return Ok(Some((x / y).into())), + "%" => return Ok(Some((x % y).into())), + "**" => return Ok(Some(x.powf(y).into())), + "==" => return Ok(Some((x == y).into())), + "!=" => return Ok(Some((x != y).into())), + ">" => return Ok(Some((x > y).into())), + ">=" => return Ok(Some((x >= y).into())), + "<" => return Ok(Some((x < y).into())), + "<=" => return Ok(Some((x <= y).into())), + _ => return Ok(None), + } + } + + #[cfg(feature = "decimal")] + if let Some((x, y)) = if type_id == (TypeId::of::(), TypeId::of::()) { + Some(( + *x.read_lock::().unwrap(), + *y.read_lock::().unwrap(), + )) + } else if type_id == (TypeId::of::(), TypeId::of::()) { + Some(( + *x.read_lock::().unwrap(), + y.clone().cast::().into(), + )) + } else if type_id == (TypeId::of::(), TypeId::of::()) { + Some(( + x.clone().cast::().into(), + *y.read_lock::().unwrap(), + )) + } else { + None + } { + if cfg!(not(feature = "unchecked")) { + use crate::packages::arithmetic::decimal_functions::*; + + match op { + "+" => return add(x, y).map(Some), + "-" => return subtract(x, y).map(Some), + "*" => return multiply(x, y).map(Some), + "/" => return divide(x, y).map(Some), + "%" => return modulo(x, y).map(Some), + _ => (), + } + } else { + match op { + "+" => return Ok(Some((x + y).into())), + "-" => return Ok(Some((x - y).into())), + "*" => return Ok(Some((x * y).into())), + "/" => return Ok(Some((x / y).into())), + "%" => return Ok(Some((x % y).into())), + _ => (), + } + } + + match op { + "==" => return Ok(Some((x == y).into())), + "!=" => return Ok(Some((x != y).into())), + ">" => return Ok(Some((x > y).into())), + ">=" => return Ok(Some((x >= y).into())), + "<" => return Ok(Some((x < y).into())), + "<=" => return Ok(Some((x <= y).into())), + _ => return Ok(None), + } + } + + if second_type != first_type { + if type_id == (TypeId::of::(), TypeId::of::()) { let x = x.clone().cast::(); let y = &*y.read_lock::().unwrap(); match op { "+" => return Ok(Some(format!("{}{}", x, y).into())), - _ => (), + _ => return Ok(None), } - } else if args_type == TypeId::of::() - && second_type == TypeId::of::() - { + } + + if type_id == (TypeId::of::(), TypeId::of::()) { let x = &*x.read_lock::().unwrap(); let y = y.clone().cast::(); match op { "+" => return Ok(Some((x + y).into())), - _ => (), + _ => return Ok(None), } } + return Ok(None); } - if args_type == TypeId::of::() { + if first_type == TypeId::of::() { let x = x.clone().cast::(); let y = y.clone().cast::(); @@ -1415,9 +1500,11 @@ pub fn run_builtin_binary_op( "&" => return Ok(Some((x & y).into())), "|" => return Ok(Some((x | y).into())), "^" => return Ok(Some((x ^ y).into())), - _ => (), + _ => return Ok(None), } - } else if args_type == TypeId::of::() { + } + + if first_type == TypeId::of::() { let x = x.clone().cast::(); let y = y.clone().cast::(); @@ -1427,9 +1514,11 @@ pub fn run_builtin_binary_op( "^" => return Ok(Some((x ^ y).into())), "==" => return Ok(Some((x == y).into())), "!=" => return Ok(Some((x != y).into())), - _ => (), + _ => return Ok(None), } - } else if args_type == TypeId::of::() { + } + + if first_type == TypeId::of::() { let x = &*x.read_lock::().unwrap(); let y = &*y.read_lock::().unwrap(); @@ -1441,9 +1530,11 @@ pub fn run_builtin_binary_op( ">=" => return Ok(Some((x >= y).into())), "<" => return Ok(Some((x < y).into())), "<=" => return Ok(Some((x <= y).into())), - _ => (), + _ => return Ok(None), } - } else if args_type == TypeId::of::() { + } + + if first_type == TypeId::of::() { let x = x.clone().cast::(); let y = y.clone().cast::(); @@ -1455,73 +1546,15 @@ pub fn run_builtin_binary_op( ">=" => return Ok(Some((x >= y).into())), "<" => return Ok(Some((x < y).into())), "<=" => return Ok(Some((x <= y).into())), - _ => (), + _ => return Ok(None), } - } else if args_type == TypeId::of::<()>() { + } + + if first_type == TypeId::of::<()>() { match op { "==" => return Ok(Some(true.into())), "!=" | ">" | ">=" | "<" | "<=" => return Ok(Some(false.into())), - _ => (), - } - } - - #[cfg(not(feature = "no_float"))] - if args_type == TypeId::of::() { - let x = x.clone().cast::(); - let y = y.clone().cast::(); - - match op { - "+" => return Ok(Some((x + y).into())), - "-" => return Ok(Some((x - y).into())), - "*" => return Ok(Some((x * y).into())), - "/" => return Ok(Some((x / y).into())), - "%" => return Ok(Some((x % y).into())), - "**" => return Ok(Some(x.powf(y).into())), - "==" => return Ok(Some((x == y).into())), - "!=" => return Ok(Some((x != y).into())), - ">" => return Ok(Some((x > y).into())), - ">=" => return Ok(Some((x >= y).into())), - "<" => return Ok(Some((x < y).into())), - "<=" => return Ok(Some((x <= y).into())), - _ => (), - } - } - - #[cfg(feature = "decimal")] - if args_type == TypeId::of::() { - let x = x.clone().cast::(); - let y = y.clone().cast::(); - - if cfg!(not(feature = "unchecked")) { - use crate::packages::arithmetic::decimal_functions::*; - - match op { - "+" => return add(x, y).map(Some), - "-" => return subtract(x, y).map(Some), - "*" => return multiply(x, y).map(Some), - "/" => return divide(x, y).map(Some), - "%" => return modulo(x, y).map(Some), - _ => (), - } - } else { - match op { - "+" => return Ok(Some((x + y).into())), - "-" => return Ok(Some((x - y).into())), - "*" => return Ok(Some((x * y).into())), - "/" => return Ok(Some((x / y).into())), - "%" => return Ok(Some((x % y).into())), - _ => (), - } - } - - match op { - "==" => return Ok(Some((x == y).into())), - "!=" => return Ok(Some((x != y).into())), - ">" => return Ok(Some((x > y).into())), - ">=" => return Ok(Some((x >= y).into())), - "<" => return Ok(Some((x < y).into())), - "<=" => return Ok(Some((x <= y).into())), - _ => (), + _ => return Ok(None), } } @@ -1534,24 +1567,80 @@ pub fn run_builtin_op_assignment( x: &mut Dynamic, y: &Dynamic, ) -> Result, Box> { - let args_type = x.type_id(); + let first_type = x.type_id(); let second_type = y.type_id(); - if second_type != args_type { - if args_type == TypeId::of::() && second_type == TypeId::of::() { + let type_id = (first_type, second_type); + + #[cfg(not(feature = "no_float"))] + if let Some((mut x, y)) = if type_id == (TypeId::of::(), TypeId::of::()) { + let y = y.clone().cast::(); + Some((x.write_lock::().unwrap(), y)) + } else if type_id == (TypeId::of::(), TypeId::of::()) { + let y = y.clone().cast::() as FLOAT; + Some((x.write_lock::().unwrap(), y)) + } else { + None + } { + match op { + "+=" => return Ok(Some(*x += y)), + "-=" => return Ok(Some(*x -= y)), + "*=" => return Ok(Some(*x *= y)), + "/=" => return Ok(Some(*x /= y)), + "%=" => return Ok(Some(*x %= y)), + "**=" => return Ok(Some(*x = x.powf(y))), + _ => return Ok(None), + } + } + + #[cfg(feature = "decimal")] + if let Some((mut x, y)) = if type_id == (TypeId::of::(), TypeId::of::()) { + let y = *y.read_lock::().unwrap(); + Some((x.write_lock::().unwrap(), y)) + } else if type_id == (TypeId::of::(), TypeId::of::()) { + let y = y.clone().cast::().into(); + Some((x.write_lock::().unwrap(), y)) + } else { + None + } { + if cfg!(not(feature = "unchecked")) { + use crate::packages::arithmetic::decimal_functions::*; + + match op { + "+=" => return Ok(Some(*x = add(*x, y)?.as_decimal().unwrap())), + "-=" => return Ok(Some(*x = subtract(*x, y)?.as_decimal().unwrap())), + "*=" => return Ok(Some(*x = multiply(*x, y)?.as_decimal().unwrap())), + "/=" => return Ok(Some(*x = divide(*x, y)?.as_decimal().unwrap())), + "%=" => return Ok(Some(*x = modulo(*x, y)?.as_decimal().unwrap())), + _ => (), + } + } else { + match op { + "+=" => return Ok(Some(*x += y)), + "-=" => return Ok(Some(*x -= y)), + "*=" => return Ok(Some(*x *= y)), + "/=" => return Ok(Some(*x /= y)), + "%=" => return Ok(Some(*x %= y)), + _ => (), + } + } + } + + if second_type != first_type { + if type_id == (TypeId::of::(), TypeId::of::()) { let y = y.read_lock::().unwrap().deref().clone(); let mut x = x.write_lock::().unwrap(); match op { "+=" => return Ok(Some(*x += y)), - _ => (), + _ => return Ok(None), } } return Ok(None); } - if args_type == TypeId::of::() { + if first_type == TypeId::of::() { let y = y.clone().cast::(); let mut x = x.write_lock::().unwrap(); @@ -1587,76 +1676,38 @@ pub fn run_builtin_op_assignment( "&=" => return Ok(Some(*x &= y)), "|=" => return Ok(Some(*x |= y)), "^=" => return Ok(Some(*x ^= y)), - _ => (), + _ => return Ok(None), } - } else if args_type == TypeId::of::() { + } + + if first_type == TypeId::of::() { let y = y.clone().cast::(); let mut x = x.write_lock::().unwrap(); match op { "&=" => return Ok(Some(*x = *x && y)), "|=" => return Ok(Some(*x = *x || y)), - _ => (), + _ => return Ok(None), } - } else if args_type == TypeId::of::() { + } + + if first_type == TypeId::of::() { let y = y.read_lock::().unwrap().deref().clone(); let mut x = x.write_lock::().unwrap(); match op { "+=" => return Ok(Some(*x = format!("{}{}", *x, y).into())), - _ => (), + _ => return Ok(None), } - } else if args_type == TypeId::of::() { + } + + if first_type == TypeId::of::() { let y = y.read_lock::().unwrap().deref().clone(); let mut x = x.write_lock::().unwrap(); match op { "+=" => return Ok(Some(*x += y)), - _ => (), - } - } - - #[cfg(not(feature = "no_float"))] - if args_type == TypeId::of::() { - let y = y.clone().cast::(); - let mut x = x.write_lock::().unwrap(); - - match op { - "+=" => return Ok(Some(*x += y)), - "-=" => return Ok(Some(*x -= y)), - "*=" => return Ok(Some(*x *= y)), - "/=" => return Ok(Some(*x /= y)), - "%=" => return Ok(Some(*x %= y)), - "**=" => return Ok(Some(*x = x.powf(y))), - _ => (), - } - } - - #[cfg(feature = "decimal")] - if args_type == TypeId::of::() { - let y = y.clone().cast::(); - let mut x = x.write_lock::().unwrap(); - - if cfg!(not(feature = "unchecked")) { - use crate::packages::arithmetic::decimal_functions::*; - - match op { - "+=" => return Ok(Some(*x = add(*x, y)?.as_decimal().unwrap())), - "-=" => return Ok(Some(*x = subtract(*x, y)?.as_decimal().unwrap())), - "*=" => return Ok(Some(*x = multiply(*x, y)?.as_decimal().unwrap())), - "/=" => return Ok(Some(*x = divide(*x, y)?.as_decimal().unwrap())), - "%=" => return Ok(Some(*x = modulo(*x, y)?.as_decimal().unwrap())), - _ => (), - } - } else { - match op { - "+=" => return Ok(Some(*x += y)), - "-=" => return Ok(Some(*x -= y)), - "*=" => return Ok(Some(*x *= y)), - "/=" => return Ok(Some(*x /= y)), - "%=" => return Ok(Some(*x %= y)), - _ => (), - } + _ => return Ok(None), } } diff --git a/src/packages/arithmetic.rs b/src/packages/arithmetic.rs index c86c61cc..4d81eda6 100644 --- a/src/packages/arithmetic.rs +++ b/src/packages/arithmetic.rs @@ -254,47 +254,47 @@ mod f32_functions { pub fn pow_f_f(x: f32, y: f32) -> f32 { x.powf(y) } - } - #[rhai_fn(name = "+")] - pub fn add_if(x: INT, y: f32) -> f32 { - (x as f32) + (y as f32) - } - #[rhai_fn(name = "+")] - pub fn add_fi(x: f32, y: INT) -> f32 { - (x as f32) + (y as f32) - } - #[rhai_fn(name = "-")] - pub fn subtract_if(x: INT, y: f32) -> f32 { - (x as f32) - (y as f32) - } - #[rhai_fn(name = "-")] - pub fn subtract_fi(x: f32, y: INT) -> f32 { - (x as f32) - (y as f32) - } - #[rhai_fn(name = "*")] - pub fn multiply_if(x: INT, y: f32) -> f32 { - (x as f32) * (y as f32) - } - #[rhai_fn(name = "*")] - pub fn multiply_fi(x: f32, y: INT) -> f32 { - (x as f32) * (y as f32) - } - #[rhai_fn(name = "/")] - pub fn divide_if(x: INT, y: f32) -> f32 { - (x as f32) / (y as f32) - } - #[rhai_fn(name = "/")] - pub fn divide_fi(x: f32, y: INT) -> f32 { - (x as f32) / (y as f32) - } - #[rhai_fn(name = "%")] - pub fn modulo_if(x: INT, y: f32) -> f32 { - (x as f32) % (y as f32) - } - #[rhai_fn(name = "%")] - pub fn modulo_fi(x: f32, y: INT) -> f32 { - (x as f32) % (y as f32) + #[rhai_fn(name = "+")] + pub fn add_if(x: INT, y: f32) -> f32 { + (x as f32) + (y as f32) + } + #[rhai_fn(name = "+")] + pub fn add_fi(x: f32, y: INT) -> f32 { + (x as f32) + (y as f32) + } + #[rhai_fn(name = "-")] + pub fn subtract_if(x: INT, y: f32) -> f32 { + (x as f32) - (y as f32) + } + #[rhai_fn(name = "-")] + pub fn subtract_fi(x: f32, y: INT) -> f32 { + (x as f32) - (y as f32) + } + #[rhai_fn(name = "*")] + pub fn multiply_if(x: INT, y: f32) -> f32 { + (x as f32) * (y as f32) + } + #[rhai_fn(name = "*")] + pub fn multiply_fi(x: f32, y: INT) -> f32 { + (x as f32) * (y as f32) + } + #[rhai_fn(name = "/")] + pub fn divide_if(x: INT, y: f32) -> f32 { + (x as f32) / (y as f32) + } + #[rhai_fn(name = "/")] + pub fn divide_fi(x: f32, y: INT) -> f32 { + (x as f32) / (y as f32) + } + #[rhai_fn(name = "%")] + pub fn modulo_if(x: INT, y: f32) -> f32 { + (x as f32) % (y as f32) + } + #[rhai_fn(name = "%")] + pub fn modulo_fi(x: f32, y: INT) -> f32 { + (x as f32) % (y as f32) + } } #[rhai_fn(name = "-")] @@ -359,47 +359,47 @@ mod f64_functions { pub fn pow_f_f(x: f64, y: f64) -> f64 { x.powf(y) } - } - #[rhai_fn(name = "+")] - pub fn add_if(x: INT, y: f64) -> f64 { - (x as f64) + (y as f64) - } - #[rhai_fn(name = "+")] - pub fn add_fi(x: f64, y: INT) -> f64 { - (x as f64) + (y as f64) - } - #[rhai_fn(name = "-")] - pub fn subtract_if(x: INT, y: f64) -> f64 { - (x as f64) - (y as f64) - } - #[rhai_fn(name = "-")] - pub fn subtract_fi(x: f64, y: INT) -> f64 { - (x as f64) - (y as f64) - } - #[rhai_fn(name = "*")] - pub fn multiply_if(x: INT, y: f64) -> f64 { - (x as f64) * (y as f64) - } - #[rhai_fn(name = "*")] - pub fn multiply_fi(x: f64, y: INT) -> f64 { - (x as f64) * (y as f64) - } - #[rhai_fn(name = "/")] - pub fn divide_if(x: INT, y: f64) -> f64 { - (x as f64) / (y as f64) - } - #[rhai_fn(name = "/")] - pub fn divide_fi(x: f64, y: INT) -> f64 { - (x as f64) / (y as f64) - } - #[rhai_fn(name = "%")] - pub fn modulo_if(x: INT, y: f64) -> f64 { - (x as f64) % (y as f64) - } - #[rhai_fn(name = "%")] - pub fn modulo_fi(x: f64, y: INT) -> f64 { - (x as f64) % (y as f64) + #[rhai_fn(name = "+")] + pub fn add_if(x: INT, y: f64) -> f64 { + (x as f64) + (y as f64) + } + #[rhai_fn(name = "+")] + pub fn add_fi(x: f64, y: INT) -> f64 { + (x as f64) + (y as f64) + } + #[rhai_fn(name = "-")] + pub fn subtract_if(x: INT, y: f64) -> f64 { + (x as f64) - (y as f64) + } + #[rhai_fn(name = "-")] + pub fn subtract_fi(x: f64, y: INT) -> f64 { + (x as f64) - (y as f64) + } + #[rhai_fn(name = "*")] + pub fn multiply_if(x: INT, y: f64) -> f64 { + (x as f64) * (y as f64) + } + #[rhai_fn(name = "*")] + pub fn multiply_fi(x: f64, y: INT) -> f64 { + (x as f64) * (y as f64) + } + #[rhai_fn(name = "/")] + pub fn divide_if(x: INT, y: f64) -> f64 { + (x as f64) / (y as f64) + } + #[rhai_fn(name = "/")] + pub fn divide_fi(x: f64, y: INT) -> f64 { + (x as f64) / (y as f64) + } + #[rhai_fn(name = "%")] + pub fn modulo_if(x: INT, y: f64) -> f64 { + (x as f64) % (y as f64) + } + #[rhai_fn(name = "%")] + pub fn modulo_fi(x: f64, y: INT) -> f64 { + (x as f64) % (y as f64) + } } #[rhai_fn(name = "-")] @@ -440,61 +440,37 @@ mod f64_functions { mod decimal_functions { use rust_decimal::{prelude::Zero, Decimal}; - #[rhai_fn(name = "+", return_raw)] + #[rhai_fn(skip, return_raw)] pub fn add(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_add(y) .ok_or_else(|| make_err(format!("Addition overflow: {} + {}", x, y))) - .map(Dynamic::from) + .map(Into::::into) } else { Ok(Dynamic::from(x + y)) } } - #[rhai_fn(name = "+", return_raw)] - pub fn add_id(x: INT, y: Decimal) -> Result> { - add(x.into(), y) - } - #[rhai_fn(name = "+", return_raw)] - pub fn add_di(x: Decimal, y: INT) -> Result> { - add(x, y.into()) - } - #[rhai_fn(name = "-", return_raw)] + #[rhai_fn(skip, return_raw)] pub fn subtract(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_sub(y) .ok_or_else(|| make_err(format!("Subtraction overflow: {} - {}", x, y))) - .map(Dynamic::from) + .map(Into::::into) } else { Ok(Dynamic::from(x - y)) } } - #[rhai_fn(name = "-", return_raw)] - pub fn subtract_id(x: INT, y: Decimal) -> Result> { - subtract(x.into(), y) - } - #[rhai_fn(name = "-", return_raw)] - pub fn subtract_di(x: Decimal, y: INT) -> Result> { - subtract(x, y.into()) - } - #[rhai_fn(name = "*", return_raw)] + #[rhai_fn(skip, return_raw)] pub fn multiply(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_mul(y) .ok_or_else(|| make_err(format!("Multiplication overflow: {} * {}", x, y))) - .map(Dynamic::from) + .map(Into::::into) } else { Ok(Dynamic::from(x * y)) } } - #[rhai_fn(name = "*", return_raw)] - pub fn multiply_id(x: INT, y: Decimal) -> Result> { - multiply(x.into(), y) - } - #[rhai_fn(name = "*", return_raw)] - pub fn multiply_di(x: Decimal, y: INT) -> Result> { - multiply(x, y.into()) - } - #[rhai_fn(name = "/", return_raw)] + #[rhai_fn(skip, return_raw)] pub fn divide(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { // Detect division by zero @@ -503,21 +479,13 @@ mod decimal_functions { } else { x.checked_div(y) .ok_or_else(|| make_err(format!("Division overflow: {} / {}", x, y))) - .map(Dynamic::from) + .map(Into::::into) } } else { Ok(Dynamic::from(x / y)) } } - #[rhai_fn(name = "/", return_raw)] - pub fn divide_id(x: INT, y: Decimal) -> Result> { - divide(x.into(), y) - } - #[rhai_fn(name = "/", return_raw)] - pub fn divide_di(x: Decimal, y: INT) -> Result> { - divide(x, y.into()) - } - #[rhai_fn(name = "%", return_raw)] + #[rhai_fn(skip, return_raw)] pub fn modulo(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_rem(y) @@ -527,19 +495,11 @@ mod decimal_functions { x, y )) }) - .map(Dynamic::from) + .map(Into::::into) } else { Ok(Dynamic::from(x % y)) } } - #[rhai_fn(name = "%", return_raw)] - pub fn modulo_id(x: INT, y: Decimal) -> Result> { - modulo(x.into(), y) - } - #[rhai_fn(name = "%", return_raw)] - pub fn modulo_di(x: Decimal, y: INT) -> Result> { - modulo(x, y.into()) - } #[rhai_fn(name = "-")] pub fn neg(x: Decimal) -> Decimal { -x diff --git a/src/parser.rs b/src/parser.rs index 4cec86d3..bd8b2556 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3167,48 +3167,20 @@ pub fn map_dynamic_to_expr(value: Dynamic, pos: Position) -> Option { #[cfg(not(feature = "no_float"))] Union::Float(value, _) => Some(Expr::FloatConstant(value, pos)), + #[cfg(feature = "decimal")] + Union::Decimal(value, _) => Some(Expr::DynamicConstant(Box::new((*value).into()), pos)), + 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, pos)), Union::Bool(value, _) => Some(Expr::BoolConstant(value, pos)), + #[cfg(not(feature = "no_index"))] - Union::Array(array, _) => { - let items: Vec<_> = array - .into_iter() - .map(|x| map_dynamic_to_expr(x, pos)) - .collect(); + Union::Array(array, _) => Some(Expr::DynamicConstant(Box::new((*array).into()), pos)), - if items.iter().all(Option::is_some) { - Some(Expr::Array( - Box::new(items.into_iter().map(Option::unwrap).collect()), - pos, - )) - } else { - None - } - } #[cfg(not(feature = "no_object"))] - Union::Map(map, _) => { - let items: Vec<_> = map - .into_iter() - .map(|(name, value)| (Ident { name, pos }, map_dynamic_to_expr(value, pos))) - .collect(); - - if items.iter().all(|(_, expr)| expr.is_some()) { - Some(Expr::Map( - Box::new( - items - .into_iter() - .map(|(k, expr)| (k, expr.unwrap())) - .collect(), - ), - pos, - )) - } else { - None - } - } + Union::Map(map, _) => Some(Expr::DynamicConstant(Box::new((*map).into()), pos)), _ => None, }