linkrs_query/executor/expression/functions/builtin/
conversion.rs1use crate::executor::expression::ExpressionError;
4use linkrs_core::value::NullType;
5use linkrs_core::Value;
6
7define_function_enum! {
8 pub enum ConversionFunction {
10 ToString => {
11 name: "to_string",
12 arity: 1,
13 variadic: false,
14 description: "Convert to String",
15 handler: execute_to_string
16 },
17 ToInt => {
18 name: "to_int",
19 arity: 1,
20 variadic: false,
21 description: "convert to an integer (math.)",
22 handler: execute_to_int
23 },
24 ToFloat => {
25 name: "to_float",
26 arity: 1,
27 variadic: false,
28 description: "convert to floating point",
29 handler: execute_to_float
30 },
31 ToBool => {
32 name: "to_bool",
33 arity: 1,
34 variadic: false,
35 description: "Convert to Boolean",
36 handler: execute_to_bool
37 },
38 }
39}
40
41fn execute_to_string(args: &[Value]) -> Result<Value, ExpressionError> {
42 match &args[0] {
43 Value::Null(_) => Ok(Value::Null(NullType::Null)),
44 _ => args[0]
45 .to_string()
46 .map(Value::string)
47 .map_err(ExpressionError::type_error),
48 }
49}
50
51fn execute_to_int(args: &[Value]) -> Result<Value, ExpressionError> {
52 match &args[0] {
53 Value::Null(_) => Ok(Value::Null(NullType::Null)),
54 _ => {
55 let result = args[0].to_int();
56 if let Value::Null(NullType::BadData) = result {
57 Err(ExpressionError::type_error(
58 "The to_int function does not support this type",
59 ))
60 } else {
61 Ok(result)
62 }
63 }
64 }
65}
66
67fn execute_to_float(args: &[Value]) -> Result<Value, ExpressionError> {
68 match &args[0] {
69 Value::Null(_) => Ok(Value::Null(NullType::Null)),
70 _ => {
71 let result = args[0].to_float();
72 if let Value::Null(NullType::BadData) = result {
73 Err(ExpressionError::type_error(
74 "The to_float function does not support the type",
75 ))
76 } else {
77 Ok(result)
78 }
79 }
80 }
81}
82
83fn execute_to_bool(args: &[Value]) -> Result<Value, ExpressionError> {
84 match &args[0] {
85 Value::Null(_) => Ok(Value::Null(NullType::Null)),
86 _ => {
87 let result = args[0].to_bool();
88 if let Value::Null(NullType::BadData) = result {
89 Err(ExpressionError::type_error(
90 "The to_bool function does not support this type",
91 ))
92 } else {
93 Ok(result)
94 }
95 }
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn test_to_string() {
105 let func = ConversionFunction::ToString;
106 let result = func
107 .execute(&[Value::Int(42)])
108 .expect("Implementation should not fail");
109 assert_eq!(result, Value::string("42"));
110 }
111
112 #[test]
113 fn test_to_int() {
114 let func = ConversionFunction::ToInt;
115 let result = func
116 .execute(&[Value::string("42")])
117 .expect("Implementation should not fail");
118 assert_eq!(result, Value::Int(42));
119 }
120
121 #[test]
122 fn test_to_float() {
123 let func = ConversionFunction::ToFloat;
124 let result = func
125 .execute(&[Value::Int(42)])
126 .expect("Implementation should not fail");
127 assert_eq!(result, Value::Float(42.0));
128 }
129
130 #[test]
131 fn test_to_bool() {
132 let func = ConversionFunction::ToBool;
133 let result = func
134 .execute(&[Value::Int(1)])
135 .expect("Implementation should not fail");
136 assert_eq!(result, Value::Bool(true));
137 }
138
139 #[test]
140 fn test_null_handling() {
141 let func = ConversionFunction::ToString;
142 let result = func
143 .execute(&[Value::Null(NullType::Null)])
144 .expect("Implementation should not fail");
145 assert_eq!(result, Value::Null(NullType::Null));
146 }
147}