Skip to main content

fiddler_script/builtins/
mod.rs

1//! Built-in functions for FiddlerScript.
2//!
3//! This module provides the default built-in functions and a system for
4//! registering custom built-in functions.
5
6mod bytes;
7mod collections;
8mod compression;
9mod core;
10mod encoding;
11mod json;
12mod math;
13mod strings;
14mod time;
15
16use std::collections::HashMap;
17
18use crate::error::RuntimeError;
19use crate::Value;
20
21// Re-export json_to_value for use by other modules
22pub use json::json_to_value;
23
24/// Type alias for built-in function signatures.
25pub type BuiltinFn = fn(Vec<Value>) -> Result<Value, RuntimeError>;
26
27/// Get the default built-in functions.
28pub fn get_default_builtins() -> HashMap<String, BuiltinFn> {
29    let mut builtins: HashMap<String, BuiltinFn> = HashMap::new();
30
31    // Core functions
32    builtins.insert("print".to_string(), core::builtin_print);
33    builtins.insert("len".to_string(), core::builtin_len);
34    builtins.insert("str".to_string(), core::builtin_str);
35    builtins.insert("int".to_string(), core::builtin_int);
36    builtins.insert("float".to_string(), core::builtin_float);
37    builtins.insert("getenv".to_string(), core::builtin_getenv);
38    builtins.insert("drop".to_string(), core::builtin_drop);
39
40    // Math functions
41    builtins.insert("abs".to_string(), math::builtin_abs);
42    builtins.insert("ceil".to_string(), math::builtin_ceil);
43    builtins.insert("floor".to_string(), math::builtin_floor);
44    builtins.insert("round".to_string(), math::builtin_round);
45
46    // Time functions
47    builtins.insert("timestamp".to_string(), time::builtin_timestamp);
48    builtins.insert("epoch".to_string(), time::builtin_epoch);
49    builtins.insert(
50        "timestamp_millis".to_string(),
51        time::builtin_timestamp_millis,
52    );
53    builtins.insert(
54        "timestamp_micros".to_string(),
55        time::builtin_timestamp_micros,
56    );
57    builtins.insert(
58        "timestamp_iso8601".to_string(),
59        time::builtin_timestamp_iso8601,
60    );
61
62    // JSON
63    builtins.insert("parse_json".to_string(), json::builtin_parse_json);
64    builtins.insert("jmespath".to_string(), json::builtin_jmespath);
65
66    // Bytes conversion
67    builtins.insert(
68        "bytes_to_string".to_string(),
69        bytes::builtin_bytes_to_string,
70    );
71    builtins.insert("bytes".to_string(), bytes::builtin_bytes);
72
73    // Collections
74    builtins.insert("array".to_string(), collections::builtin_array);
75    builtins.insert("push".to_string(), collections::builtin_push);
76    builtins.insert("get".to_string(), collections::builtin_get);
77    builtins.insert("set".to_string(), collections::builtin_set);
78    builtins.insert("dict".to_string(), collections::builtin_dict);
79    builtins.insert("keys".to_string(), collections::builtin_keys);
80    builtins.insert("is_array".to_string(), collections::builtin_is_array);
81    builtins.insert("is_dict".to_string(), collections::builtin_is_dict);
82    builtins.insert("delete".to_string(), collections::builtin_delete);
83    builtins.insert("contains".to_string(), collections::builtin_contains);
84
85    // Compression
86    builtins.insert(
87        "gzip_compress".to_string(),
88        compression::builtin_gzip_compress,
89    );
90    builtins.insert(
91        "gzip_decompress".to_string(),
92        compression::builtin_gzip_decompress,
93    );
94    builtins.insert(
95        "zlib_compress".to_string(),
96        compression::builtin_zlib_compress,
97    );
98    builtins.insert(
99        "zlib_decompress".to_string(),
100        compression::builtin_zlib_decompress,
101    );
102    builtins.insert(
103        "deflate_compress".to_string(),
104        compression::builtin_deflate_compress,
105    );
106    builtins.insert(
107        "deflate_decompress".to_string(),
108        compression::builtin_deflate_decompress,
109    );
110
111    // Encoding
112    builtins.insert("base64_encode".to_string(), encoding::builtin_base64_encode);
113    builtins.insert("base64_decode".to_string(), encoding::builtin_base64_decode);
114
115    // String methods
116    builtins.insert("lines".to_string(), strings::builtin_lines);
117    builtins.insert("capitalize".to_string(), strings::builtin_capitalize);
118    builtins.insert("lowercase".to_string(), strings::builtin_lowercase);
119    builtins.insert("uppercase".to_string(), strings::builtin_uppercase);
120    builtins.insert("trim".to_string(), strings::builtin_trim);
121    builtins.insert("trim_prefix".to_string(), strings::builtin_trim_prefix);
122    builtins.insert("trim_suffix".to_string(), strings::builtin_trim_suffix);
123    builtins.insert("has_prefix".to_string(), strings::builtin_has_prefix);
124    builtins.insert("has_suffix".to_string(), strings::builtin_has_suffix);
125    builtins.insert("split".to_string(), strings::builtin_split);
126    builtins.insert("reverse".to_string(), strings::builtin_reverse);
127
128    builtins
129}
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134
135    #[test]
136    fn test_default_builtins() {
137        let builtins = get_default_builtins();
138
139        // Core
140        assert!(builtins.contains_key("print"));
141        assert!(builtins.contains_key("len"));
142        assert!(builtins.contains_key("str"));
143        assert!(builtins.contains_key("int"));
144        assert!(builtins.contains_key("getenv"));
145        assert!(builtins.contains_key("drop"));
146
147        // Math
148        assert!(builtins.contains_key("abs"));
149        assert!(builtins.contains_key("ceil"));
150        assert!(builtins.contains_key("floor"));
151        assert!(builtins.contains_key("round"));
152
153        // Time
154        assert!(builtins.contains_key("timestamp"));
155        assert!(builtins.contains_key("epoch"));
156        assert!(builtins.contains_key("timestamp_millis"));
157        assert!(builtins.contains_key("timestamp_micros"));
158        assert!(builtins.contains_key("timestamp_iso8601"));
159
160        // JSON
161        assert!(builtins.contains_key("parse_json"));
162        assert!(builtins.contains_key("jmespath"));
163
164        // Bytes
165        assert!(builtins.contains_key("bytes_to_string"));
166        assert!(builtins.contains_key("bytes"));
167
168        // Collections
169        assert!(builtins.contains_key("array"));
170        assert!(builtins.contains_key("push"));
171        assert!(builtins.contains_key("get"));
172        assert!(builtins.contains_key("set"));
173        assert!(builtins.contains_key("dict"));
174        assert!(builtins.contains_key("keys"));
175        assert!(builtins.contains_key("is_array"));
176        assert!(builtins.contains_key("is_dict"));
177        assert!(builtins.contains_key("delete"));
178        assert!(builtins.contains_key("contains"));
179
180        // Compression
181        assert!(builtins.contains_key("gzip_compress"));
182        assert!(builtins.contains_key("gzip_decompress"));
183        assert!(builtins.contains_key("zlib_compress"));
184        assert!(builtins.contains_key("zlib_decompress"));
185        assert!(builtins.contains_key("deflate_compress"));
186        assert!(builtins.contains_key("deflate_decompress"));
187
188        // Encoding
189        assert!(builtins.contains_key("base64_encode"));
190        assert!(builtins.contains_key("base64_decode"));
191
192        // String methods
193        assert!(builtins.contains_key("lines"));
194        assert!(builtins.contains_key("capitalize"));
195        assert!(builtins.contains_key("lowercase"));
196        assert!(builtins.contains_key("uppercase"));
197        assert!(builtins.contains_key("trim"));
198        assert!(builtins.contains_key("trim_prefix"));
199        assert!(builtins.contains_key("trim_suffix"));
200        assert!(builtins.contains_key("has_prefix"));
201        assert!(builtins.contains_key("has_suffix"));
202        assert!(builtins.contains_key("split"));
203        assert!(builtins.contains_key("reverse"));
204    }
205}