openjd_expr/functions/
conversion.rs1use crate::error::ExpressionError;
8use crate::function_library::EvalContext;
9use crate::value::{ExprValue, Float64};
10
11type R = Result<ExprValue, ExpressionError>;
12type Ctx<'a> = &'a mut dyn EvalContext;
13
14pub fn string_fn(_: Ctx, a: &[ExprValue]) -> R {
15 Ok(ExprValue::String(a[0].to_display_string()))
16}
17
18pub fn int_from_int(_: Ctx, a: &[ExprValue]) -> R {
19 match &a[0] {
20 ExprValue::Int(i) => Ok(ExprValue::Int(*i)),
21 _ => Err(ExpressionError::type_error("type error")),
22 }
23}
24
25pub fn int_from_float(_: Ctx, a: &[ExprValue]) -> R {
26 match &a[0] {
27 ExprValue::Float(f) => {
28 if f.value().fract() != 0.0 {
29 return Err(ExpressionError::new(format!(
30 "Cannot convert {f} to int: not a whole number"
31 )));
32 }
33 if f.value() >= i64::MAX as f64 || f.value() < i64::MIN as f64 {
34 return Err(ExpressionError::integer_overflow());
35 }
36 Ok(ExprValue::Int(f.value() as i64))
37 }
38 _ => Err(ExpressionError::type_error("type error")),
39 }
40}
41
42pub fn int_from_bool(_: Ctx, a: &[ExprValue]) -> R {
43 match &a[0] {
44 ExprValue::Bool(b) => Ok(ExprValue::Int(if *b { 1 } else { 0 })),
45 _ => Err(ExpressionError::type_error("type error")),
46 }
47}
48
49pub fn int_from_string(_: Ctx, a: &[ExprValue]) -> R {
50 match &a[0] {
51 ExprValue::String(s) => {
52 let v: i64 = s
53 .trim()
54 .parse()
55 .map_err(|_| ExpressionError::new(format!("Cannot convert '{s}' to int")))?;
56 Ok(ExprValue::Int(v))
57 }
58 _ => Err(ExpressionError::type_error("type error")),
59 }
60}
61
62pub fn float_from_float(_: Ctx, a: &[ExprValue]) -> R {
63 match &a[0] {
64 ExprValue::Float(f) => Ok(ExprValue::Float(Float64::new(f.value())?)),
65 _ => Err(ExpressionError::type_error("type error")),
66 }
67}
68
69pub fn float_from_int(_: Ctx, a: &[ExprValue]) -> R {
70 match &a[0] {
71 ExprValue::Int(i) => Ok(ExprValue::Float(Float64::new(*i as f64)?)),
72 _ => Err(ExpressionError::type_error("type error")),
73 }
74}
75
76pub fn float_from_string(_: Ctx, a: &[ExprValue]) -> R {
77 match &a[0] {
78 ExprValue::String(s) => {
79 let lower = s.trim().to_lowercase();
80 if lower == "inf" || lower == "infinity" || lower == "-inf" || lower == "-infinity" {
81 return Err(ExpressionError::float_error(
82 "Cannot convert to float: infinity",
83 ));
84 }
85 if lower == "nan" {
86 return Err(ExpressionError::float_error("Cannot convert to float: NaN"));
87 }
88 let v: f64 = s
89 .trim()
90 .parse()
91 .map_err(|_| ExpressionError::new(format!("Cannot convert '{s}' to float")))?;
92 Ok(ExprValue::Float(Float64::new(v)?))
93 }
94 _ => Err(ExpressionError::type_error("type error")),
95 }
96}
97
98pub fn bool_from_bool(_: Ctx, a: &[ExprValue]) -> R {
99 match &a[0] {
100 ExprValue::Bool(b) => Ok(ExprValue::Bool(*b)),
101 _ => Err(ExpressionError::type_error("type error")),
102 }
103}
104
105pub fn bool_from_int(_: Ctx, a: &[ExprValue]) -> R {
106 match &a[0] {
107 ExprValue::Int(i) => Ok(ExprValue::Bool(*i != 0)),
108 _ => Err(ExpressionError::type_error("type error")),
109 }
110}
111
112pub fn bool_from_float(_: Ctx, a: &[ExprValue]) -> R {
113 match &a[0] {
114 ExprValue::Float(f) => Ok(ExprValue::Bool(*f != 0.0)),
115 _ => Err(ExpressionError::type_error("type error")),
116 }
117}
118
119pub fn bool_from_null(_: Ctx, _a: &[ExprValue]) -> R {
120 Ok(ExprValue::Bool(false))
121}
122
123pub fn bool_from_string(_: Ctx, a: &[ExprValue]) -> R {
124 match &a[0] {
125 ExprValue::String(s) => match s.to_lowercase().as_str() {
126 "true" | "yes" | "on" | "1" => Ok(ExprValue::Bool(true)),
127 "false" | "no" | "off" | "0" => Ok(ExprValue::Bool(false)),
128 _ => Err(ExpressionError::new(format!(
129 "Cannot convert '{s}' to bool. Expected one of: 1, true, on, yes, 0, false, off, no"
130 ))),
131 },
132 _ => Err(ExpressionError::type_error("type error")),
133 }
134}
135
136pub fn bool_from_path(_: Ctx, _a: &[ExprValue]) -> R {
137 Err(ExpressionError::new("Cannot convert path to bool"))
138}
139
140pub fn bool_from_list(_: Ctx, _a: &[ExprValue]) -> R {
141 Err(ExpressionError::new("Cannot convert list to bool"))
142}