1use std::sync::LazyLock;
7
8use crate::types::{CelType, FunctionDecl, OverloadDecl};
9
10pub static STANDARD_LIBRARY: LazyLock<Vec<FunctionDecl>> = LazyLock::new(build_standard_library);
12
13fn build_standard_library() -> Vec<FunctionDecl> {
14 let mut funcs = Vec::new();
15
16 funcs.push(
20 FunctionDecl::new("_+_")
21 .with_overload(OverloadDecl::function("add_int64_int64", vec![CelType::Int, CelType::Int], CelType::Int))
22 .with_overload(OverloadDecl::function("add_uint64_uint64", vec![CelType::UInt, CelType::UInt], CelType::UInt))
23 .with_overload(OverloadDecl::function("add_double_double", vec![CelType::Double, CelType::Double], CelType::Double))
24 .with_overload(OverloadDecl::function("add_string_string", vec![CelType::String, CelType::String], CelType::String))
25 .with_overload(OverloadDecl::function("add_bytes_bytes", vec![CelType::Bytes, CelType::Bytes], CelType::Bytes))
26 .with_overload(OverloadDecl::function(
27 "add_list_list",
28 vec![CelType::list(CelType::type_param("T")), CelType::list(CelType::type_param("T"))],
29 CelType::list(CelType::type_param("T")),
30 ).with_type_params(vec!["T".to_string()]))
31 .with_overload(OverloadDecl::function("add_timestamp_duration", vec![CelType::Timestamp, CelType::Duration], CelType::Timestamp))
32 .with_overload(OverloadDecl::function("add_duration_timestamp", vec![CelType::Duration, CelType::Timestamp], CelType::Timestamp))
33 .with_overload(OverloadDecl::function("add_duration_duration", vec![CelType::Duration, CelType::Duration], CelType::Duration)),
34 );
35
36 funcs.push(
38 FunctionDecl::new("_-_")
39 .with_overload(OverloadDecl::function("subtract_int64_int64", vec![CelType::Int, CelType::Int], CelType::Int))
40 .with_overload(OverloadDecl::function("subtract_uint64_uint64", vec![CelType::UInt, CelType::UInt], CelType::UInt))
41 .with_overload(OverloadDecl::function("subtract_double_double", vec![CelType::Double, CelType::Double], CelType::Double))
42 .with_overload(OverloadDecl::function("subtract_timestamp_timestamp", vec![CelType::Timestamp, CelType::Timestamp], CelType::Duration))
43 .with_overload(OverloadDecl::function("subtract_timestamp_duration", vec![CelType::Timestamp, CelType::Duration], CelType::Timestamp))
44 .with_overload(OverloadDecl::function("subtract_duration_duration", vec![CelType::Duration, CelType::Duration], CelType::Duration)),
45 );
46
47 funcs.push(
49 FunctionDecl::new("_*_")
50 .with_overload(OverloadDecl::function("multiply_int64_int64", vec![CelType::Int, CelType::Int], CelType::Int))
51 .with_overload(OverloadDecl::function("multiply_uint64_uint64", vec![CelType::UInt, CelType::UInt], CelType::UInt))
52 .with_overload(OverloadDecl::function("multiply_double_double", vec![CelType::Double, CelType::Double], CelType::Double)),
53 );
54
55 funcs.push(
57 FunctionDecl::new("_/_")
58 .with_overload(OverloadDecl::function("divide_int64_int64", vec![CelType::Int, CelType::Int], CelType::Int))
59 .with_overload(OverloadDecl::function("divide_uint64_uint64", vec![CelType::UInt, CelType::UInt], CelType::UInt))
60 .with_overload(OverloadDecl::function("divide_double_double", vec![CelType::Double, CelType::Double], CelType::Double)),
61 );
62
63 funcs.push(
65 FunctionDecl::new("_%_")
66 .with_overload(OverloadDecl::function("modulo_int64_int64", vec![CelType::Int, CelType::Int], CelType::Int))
67 .with_overload(OverloadDecl::function("modulo_uint64_uint64", vec![CelType::UInt, CelType::UInt], CelType::UInt)),
68 );
69
70 funcs.push(
72 FunctionDecl::new("-_")
73 .with_overload(OverloadDecl::function("negate_int64", vec![CelType::Int], CelType::Int))
74 .with_overload(OverloadDecl::function("negate_double", vec![CelType::Double], CelType::Double)),
75 );
76
77 funcs.push(
79 FunctionDecl::new("_==_")
80 .with_overload(OverloadDecl::function(
81 "equals",
82 vec![CelType::type_param("T"), CelType::type_param("T")],
83 CelType::Bool,
84 ).with_type_params(vec!["T".to_string()])),
85 );
86
87 funcs.push(
89 FunctionDecl::new("_!=_")
90 .with_overload(OverloadDecl::function(
91 "not_equals",
92 vec![CelType::type_param("T"), CelType::type_param("T")],
93 CelType::Bool,
94 ).with_type_params(vec!["T".to_string()])),
95 );
96
97 funcs.push(
99 FunctionDecl::new("_<_")
100 .with_overload(OverloadDecl::function("less_bool", vec![CelType::Bool, CelType::Bool], CelType::Bool))
101 .with_overload(OverloadDecl::function("less_int64", vec![CelType::Int, CelType::Int], CelType::Bool))
102 .with_overload(OverloadDecl::function("less_uint64", vec![CelType::UInt, CelType::UInt], CelType::Bool))
103 .with_overload(OverloadDecl::function("less_double", vec![CelType::Double, CelType::Double], CelType::Bool))
104 .with_overload(OverloadDecl::function("less_string", vec![CelType::String, CelType::String], CelType::Bool))
105 .with_overload(OverloadDecl::function("less_bytes", vec![CelType::Bytes, CelType::Bytes], CelType::Bool))
106 .with_overload(OverloadDecl::function("less_timestamp", vec![CelType::Timestamp, CelType::Timestamp], CelType::Bool))
107 .with_overload(OverloadDecl::function("less_duration", vec![CelType::Duration, CelType::Duration], CelType::Bool)),
108 );
109
110 funcs.push(
112 FunctionDecl::new("_<=_")
113 .with_overload(OverloadDecl::function("less_equals_bool", vec![CelType::Bool, CelType::Bool], CelType::Bool))
114 .with_overload(OverloadDecl::function("less_equals_int64", vec![CelType::Int, CelType::Int], CelType::Bool))
115 .with_overload(OverloadDecl::function("less_equals_uint64", vec![CelType::UInt, CelType::UInt], CelType::Bool))
116 .with_overload(OverloadDecl::function("less_equals_double", vec![CelType::Double, CelType::Double], CelType::Bool))
117 .with_overload(OverloadDecl::function("less_equals_string", vec![CelType::String, CelType::String], CelType::Bool))
118 .with_overload(OverloadDecl::function("less_equals_bytes", vec![CelType::Bytes, CelType::Bytes], CelType::Bool))
119 .with_overload(OverloadDecl::function("less_equals_timestamp", vec![CelType::Timestamp, CelType::Timestamp], CelType::Bool))
120 .with_overload(OverloadDecl::function("less_equals_duration", vec![CelType::Duration, CelType::Duration], CelType::Bool)),
121 );
122
123 funcs.push(
125 FunctionDecl::new("_>_")
126 .with_overload(OverloadDecl::function("greater_bool", vec![CelType::Bool, CelType::Bool], CelType::Bool))
127 .with_overload(OverloadDecl::function("greater_int64", vec![CelType::Int, CelType::Int], CelType::Bool))
128 .with_overload(OverloadDecl::function("greater_uint64", vec![CelType::UInt, CelType::UInt], CelType::Bool))
129 .with_overload(OverloadDecl::function("greater_double", vec![CelType::Double, CelType::Double], CelType::Bool))
130 .with_overload(OverloadDecl::function("greater_string", vec![CelType::String, CelType::String], CelType::Bool))
131 .with_overload(OverloadDecl::function("greater_bytes", vec![CelType::Bytes, CelType::Bytes], CelType::Bool))
132 .with_overload(OverloadDecl::function("greater_timestamp", vec![CelType::Timestamp, CelType::Timestamp], CelType::Bool))
133 .with_overload(OverloadDecl::function("greater_duration", vec![CelType::Duration, CelType::Duration], CelType::Bool)),
134 );
135
136 funcs.push(
138 FunctionDecl::new("_>=_")
139 .with_overload(OverloadDecl::function("greater_equals_bool", vec![CelType::Bool, CelType::Bool], CelType::Bool))
140 .with_overload(OverloadDecl::function("greater_equals_int64", vec![CelType::Int, CelType::Int], CelType::Bool))
141 .with_overload(OverloadDecl::function("greater_equals_uint64", vec![CelType::UInt, CelType::UInt], CelType::Bool))
142 .with_overload(OverloadDecl::function("greater_equals_double", vec![CelType::Double, CelType::Double], CelType::Bool))
143 .with_overload(OverloadDecl::function("greater_equals_string", vec![CelType::String, CelType::String], CelType::Bool))
144 .with_overload(OverloadDecl::function("greater_equals_bytes", vec![CelType::Bytes, CelType::Bytes], CelType::Bool))
145 .with_overload(OverloadDecl::function("greater_equals_timestamp", vec![CelType::Timestamp, CelType::Timestamp], CelType::Bool))
146 .with_overload(OverloadDecl::function("greater_equals_duration", vec![CelType::Duration, CelType::Duration], CelType::Bool)),
147 );
148
149 funcs.push(
151 FunctionDecl::new("_&&_")
152 .with_overload(OverloadDecl::function("logical_and", vec![CelType::Bool, CelType::Bool], CelType::Bool)),
153 );
154
155 funcs.push(
157 FunctionDecl::new("_||_")
158 .with_overload(OverloadDecl::function("logical_or", vec![CelType::Bool, CelType::Bool], CelType::Bool)),
159 );
160
161 funcs.push(
163 FunctionDecl::new("!_")
164 .with_overload(OverloadDecl::function("logical_not", vec![CelType::Bool], CelType::Bool)),
165 );
166
167 funcs.push(
169 FunctionDecl::new("_?_:_")
170 .with_overload(OverloadDecl::function(
171 "conditional",
172 vec![CelType::Bool, CelType::type_param("T"), CelType::type_param("T")],
173 CelType::type_param("T"),
174 ).with_type_params(vec!["T".to_string()])),
175 );
176
177 funcs.push(
179 FunctionDecl::new("@in")
180 .with_overload(OverloadDecl::function(
181 "in_list",
182 vec![CelType::type_param("T"), CelType::list(CelType::type_param("T"))],
183 CelType::Bool,
184 ).with_type_params(vec!["T".to_string()]))
185 .with_overload(OverloadDecl::function(
186 "in_map",
187 vec![CelType::type_param("K"), CelType::map(CelType::type_param("K"), CelType::type_param("V"))],
188 CelType::Bool,
189 ).with_type_params(vec!["K".to_string(), "V".to_string()])),
190 );
191
192 funcs.push(
194 FunctionDecl::new("_[_]")
195 .with_overload(OverloadDecl::function(
196 "index_list",
197 vec![CelType::list(CelType::type_param("T")), CelType::Int],
198 CelType::type_param("T"),
199 ).with_type_params(vec!["T".to_string()]))
200 .with_overload(OverloadDecl::function(
201 "index_map",
202 vec![CelType::map(CelType::type_param("K"), CelType::type_param("V")), CelType::type_param("K")],
203 CelType::type_param("V"),
204 ).with_type_params(vec!["K".to_string(), "V".to_string()])),
205 );
206
207 funcs.push(
210 FunctionDecl::new("bool")
211 .with_overload(OverloadDecl::function("bool_to_bool", vec![CelType::Bool], CelType::Bool))
212 .with_overload(OverloadDecl::function("string_to_bool", vec![CelType::String], CelType::Bool)),
213 );
214
215 funcs.push(
216 FunctionDecl::new("bytes")
217 .with_overload(OverloadDecl::function("bytes_to_bytes", vec![CelType::Bytes], CelType::Bytes))
218 .with_overload(OverloadDecl::function("string_to_bytes", vec![CelType::String], CelType::Bytes)),
219 );
220
221 funcs.push(
222 FunctionDecl::new("double")
223 .with_overload(OverloadDecl::function("double_to_double", vec![CelType::Double], CelType::Double))
224 .with_overload(OverloadDecl::function("int_to_double", vec![CelType::Int], CelType::Double))
225 .with_overload(OverloadDecl::function("uint_to_double", vec![CelType::UInt], CelType::Double))
226 .with_overload(OverloadDecl::function("string_to_double", vec![CelType::String], CelType::Double)),
227 );
228
229 funcs.push(
230 FunctionDecl::new("duration")
231 .with_overload(OverloadDecl::function("duration_to_duration", vec![CelType::Duration], CelType::Duration))
232 .with_overload(OverloadDecl::function("string_to_duration", vec![CelType::String], CelType::Duration)),
233 );
234
235 funcs.push(
236 FunctionDecl::new("dyn")
237 .with_overload(OverloadDecl::function(
238 "to_dyn",
239 vec![CelType::type_param("T")],
240 CelType::Dyn,
241 ).with_type_params(vec!["T".to_string()])),
242 );
243
244 funcs.push(
245 FunctionDecl::new("int")
246 .with_overload(OverloadDecl::function("int_to_int", vec![CelType::Int], CelType::Int))
247 .with_overload(OverloadDecl::function("uint_to_int", vec![CelType::UInt], CelType::Int))
248 .with_overload(OverloadDecl::function("double_to_int", vec![CelType::Double], CelType::Int))
249 .with_overload(OverloadDecl::function("string_to_int", vec![CelType::String], CelType::Int))
250 .with_overload(OverloadDecl::function("timestamp_to_int", vec![CelType::Timestamp], CelType::Int)),
251 );
252
253 funcs.push(
254 FunctionDecl::new("string")
255 .with_overload(OverloadDecl::function("string_to_string", vec![CelType::String], CelType::String))
256 .with_overload(OverloadDecl::function("bool_to_string", vec![CelType::Bool], CelType::String))
257 .with_overload(OverloadDecl::function("int_to_string", vec![CelType::Int], CelType::String))
258 .with_overload(OverloadDecl::function("uint_to_string", vec![CelType::UInt], CelType::String))
259 .with_overload(OverloadDecl::function("double_to_string", vec![CelType::Double], CelType::String))
260 .with_overload(OverloadDecl::function("bytes_to_string", vec![CelType::Bytes], CelType::String))
261 .with_overload(OverloadDecl::function("timestamp_to_string", vec![CelType::Timestamp], CelType::String))
262 .with_overload(OverloadDecl::function("duration_to_string", vec![CelType::Duration], CelType::String)),
263 );
264
265 funcs.push(
266 FunctionDecl::new("timestamp")
267 .with_overload(OverloadDecl::function("timestamp_to_timestamp", vec![CelType::Timestamp], CelType::Timestamp))
268 .with_overload(OverloadDecl::function("string_to_timestamp", vec![CelType::String], CelType::Timestamp))
269 .with_overload(OverloadDecl::function("int_to_timestamp", vec![CelType::Int], CelType::Timestamp)),
270 );
271
272 funcs.push(
273 FunctionDecl::new("type")
274 .with_overload(OverloadDecl::function(
275 "type",
276 vec![CelType::type_param("T")],
277 CelType::type_of(CelType::type_param("T")),
278 ).with_type_params(vec!["T".to_string()])),
279 );
280
281 funcs.push(
282 FunctionDecl::new("uint")
283 .with_overload(OverloadDecl::function("uint_to_uint", vec![CelType::UInt], CelType::UInt))
284 .with_overload(OverloadDecl::function("int_to_uint", vec![CelType::Int], CelType::UInt))
285 .with_overload(OverloadDecl::function("double_to_uint", vec![CelType::Double], CelType::UInt))
286 .with_overload(OverloadDecl::function("string_to_uint", vec![CelType::String], CelType::UInt)),
287 );
288
289 funcs.push(
292 FunctionDecl::new("size")
293 .with_overload(OverloadDecl::function("size_string", vec![CelType::String], CelType::Int))
294 .with_overload(OverloadDecl::function("size_bytes", vec![CelType::Bytes], CelType::Int))
295 .with_overload(OverloadDecl::function(
296 "size_list",
297 vec![CelType::list(CelType::type_param("T"))],
298 CelType::Int,
299 ).with_type_params(vec!["T".to_string()]))
300 .with_overload(OverloadDecl::function(
301 "size_map",
302 vec![CelType::map(CelType::type_param("K"), CelType::type_param("V"))],
303 CelType::Int,
304 ).with_type_params(vec!["K".to_string(), "V".to_string()]))
305 .with_overload(OverloadDecl::method("string_size", vec![CelType::String], CelType::Int))
307 .with_overload(OverloadDecl::method("bytes_size", vec![CelType::Bytes], CelType::Int))
308 .with_overload(OverloadDecl::method(
309 "list_size",
310 vec![CelType::list(CelType::type_param("T"))],
311 CelType::Int,
312 ).with_type_params(vec!["T".to_string()]))
313 .with_overload(OverloadDecl::method(
314 "map_size",
315 vec![CelType::map(CelType::type_param("K"), CelType::type_param("V"))],
316 CelType::Int,
317 ).with_type_params(vec!["K".to_string(), "V".to_string()])),
318 );
319
320 funcs.push(
323 FunctionDecl::new("contains")
324 .with_overload(OverloadDecl::method("string_contains_string", vec![CelType::String, CelType::String], CelType::Bool)),
325 );
326
327 funcs.push(
328 FunctionDecl::new("endsWith")
329 .with_overload(OverloadDecl::method("string_ends_with_string", vec![CelType::String, CelType::String], CelType::Bool)),
330 );
331
332 funcs.push(
333 FunctionDecl::new("startsWith")
334 .with_overload(OverloadDecl::method("string_starts_with_string", vec![CelType::String, CelType::String], CelType::Bool)),
335 );
336
337 funcs.push(
338 FunctionDecl::new("matches")
339 .with_overload(OverloadDecl::function("matches_string_re", vec![CelType::String, CelType::String], CelType::Bool))
340 .with_overload(OverloadDecl::method("string_matches_re", vec![CelType::String, CelType::String], CelType::Bool)),
341 );
342
343 let timestamp_accessors = [
346 "getDate", "getDayOfMonth", "getDayOfWeek", "getDayOfYear",
347 "getFullYear", "getMonth",
348 ];
349
350 for name in timestamp_accessors {
351 let base_id = name.to_lowercase().replace("get", "").to_lowercase();
352 funcs.push(
353 FunctionDecl::new(name)
354 .with_overload(OverloadDecl::method(
355 format!("timestamp_to_{}", base_id),
356 vec![CelType::Timestamp],
357 CelType::Int,
358 ))
359 .with_overload(OverloadDecl::method(
360 format!("timestamp_to_{}_with_tz", base_id),
361 vec![CelType::Timestamp, CelType::String],
362 CelType::Int,
363 )),
364 );
365 }
366
367 let time_accessors = ["getHours", "getMinutes", "getSeconds", "getMilliseconds"];
369
370 for name in time_accessors {
371 let base_id = name.to_lowercase().replace("get", "").to_lowercase();
372 funcs.push(
373 FunctionDecl::new(name)
374 .with_overload(OverloadDecl::method(
375 format!("timestamp_to_{}", base_id),
376 vec![CelType::Timestamp],
377 CelType::Int,
378 ))
379 .with_overload(OverloadDecl::method(
380 format!("timestamp_to_{}_with_tz", base_id),
381 vec![CelType::Timestamp, CelType::String],
382 CelType::Int,
383 ))
384 .with_overload(OverloadDecl::method(
385 format!("duration_to_{}", base_id),
386 vec![CelType::Duration],
387 CelType::Int,
388 )),
389 );
390 }
391
392 funcs
393}
394
395#[allow(dead_code)]
397pub fn get_standard_function(name: &str) -> Option<&'static FunctionDecl> {
398 STANDARD_LIBRARY.iter().find(|f| f.name == name)
399}
400
401#[cfg(test)]
402mod tests {
403 use super::*;
404
405 #[test]
406 fn test_standard_library_loads() {
407 assert!(!STANDARD_LIBRARY.is_empty());
408 }
409
410 #[test]
411 fn test_add_operator() {
412 let add = get_standard_function("_+_").unwrap();
413 assert!(add.overloads.len() >= 4);
414 assert!(add.overloads.iter().any(|o| o.id == "add_int64_int64"));
415 assert!(add.overloads.iter().any(|o| o.id == "add_string_string"));
416 }
417
418 #[test]
419 fn test_comparison_operators() {
420 assert!(get_standard_function("_==_").is_some());
421 assert!(get_standard_function("_!=_").is_some());
422 assert!(get_standard_function("_<_").is_some());
423 assert!(get_standard_function("_<=_").is_some());
424 assert!(get_standard_function("_>_").is_some());
425 assert!(get_standard_function("_>=_").is_some());
426 }
427
428 #[test]
429 fn test_logical_operators() {
430 assert!(get_standard_function("_&&_").is_some());
431 assert!(get_standard_function("_||_").is_some());
432 assert!(get_standard_function("!_").is_some());
433 }
434
435 #[test]
436 fn test_size_has_both_standalone_and_method() {
437 let size = get_standard_function("size").unwrap();
438 assert!(size.has_standalone_overloads());
439 assert!(size.has_member_overloads());
440 }
441
442 #[test]
443 fn test_contains_is_method_only() {
444 let contains = get_standard_function("contains").unwrap();
445 assert!(!contains.has_standalone_overloads());
446 assert!(contains.has_member_overloads());
447 }
448
449 #[test]
450 fn test_type_conversions() {
451 assert!(get_standard_function("bool").is_some());
452 assert!(get_standard_function("int").is_some());
453 assert!(get_standard_function("uint").is_some());
454 assert!(get_standard_function("double").is_some());
455 assert!(get_standard_function("string").is_some());
456 assert!(get_standard_function("bytes").is_some());
457 assert!(get_standard_function("timestamp").is_some());
458 assert!(get_standard_function("duration").is_some());
459 assert!(get_standard_function("dyn").is_some());
460 assert!(get_standard_function("type").is_some());
461 }
462
463 #[test]
464 fn test_timestamp_accessors() {
465 assert!(get_standard_function("getDate").is_some());
466 assert!(get_standard_function("getHours").is_some());
467 assert!(get_standard_function("getMinutes").is_some());
468 }
469}