1use crate::value_ops::{is_truthy, value_to_display_string};
6use nodedb_types::Value;
7
8pub fn eval_cast(val: &Value, to_type: &crate::expr::CastType) -> Value {
9 use crate::expr::CastType;
10 match to_type {
11 CastType::Int => match val {
12 Value::Integer(_) => val.clone(),
13 Value::Float(f) => Value::Integer(*f as i64),
14 Value::String(s) => s.parse::<i64>().map(Value::Integer).unwrap_or(Value::Null),
15 Value::Bool(b) => Value::Integer(*b as i64),
16 Value::Decimal(d) => {
17 use rust_decimal::prelude::ToPrimitive;
18 d.to_i64().map(Value::Integer).unwrap_or(Value::Null)
19 }
20 _ => Value::Null,
21 },
22 CastType::Float => match val {
23 Value::Float(_) => val.clone(),
24 Value::Integer(i) => Value::Float(*i as f64),
25 Value::String(s) => s
26 .parse::<f64>()
27 .map(Value::Float)
28 .ok()
29 .unwrap_or(Value::Null),
30 Value::Decimal(d) => {
31 use rust_decimal::prelude::ToPrimitive;
32 d.to_f64().map(Value::Float).unwrap_or(Value::Null)
33 }
34 _ => Value::Null,
35 },
36 CastType::String => Value::String(value_to_display_string(val)),
37 CastType::Bool => Value::Bool(is_truthy(val)),
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44 use crate::expr::CastType;
45
46 #[test]
47 fn cast_string_to_int() {
48 assert_eq!(
49 eval_cast(&Value::String("42".into()), &CastType::Int),
50 Value::Integer(42)
51 );
52 }
53
54 #[test]
55 fn cast_float_to_int() {
56 assert_eq!(
57 eval_cast(&Value::Float(3.7), &CastType::Int),
58 Value::Integer(3)
59 );
60 }
61
62 #[test]
63 fn cast_int_to_string() {
64 assert_eq!(
65 eval_cast(&Value::Integer(42), &CastType::String),
66 Value::String("42".into())
67 );
68 }
69
70 #[test]
71 fn cast_to_bool() {
72 assert_eq!(
73 eval_cast(&Value::Integer(1), &CastType::Bool),
74 Value::Bool(true)
75 );
76 assert_eq!(
77 eval_cast(&Value::Integer(0), &CastType::Bool),
78 Value::Bool(false)
79 );
80 assert_eq!(
81 eval_cast(&Value::String(String::new()), &CastType::Bool),
82 Value::Bool(false)
83 );
84 assert_eq!(
85 eval_cast(&Value::String("x".into()), &CastType::Bool),
86 Value::Bool(true)
87 );
88 }
89}