kotoba_jsonnet/
stdlib.rs

1//! Jsonnet standard library implementation
2
3use crate::error::{JsonnetError, Result};
4use crate::value::JsonnetValue;
5use sha1::Sha1;
6use sha2::{Sha256, Sha512, Digest};
7use sha3::Sha3_256;
8use std::collections::HashMap;
9
10/// Standard library function implementations
11pub struct StdLib;
12
13impl StdLib {
14    /// Call a standard library function
15    pub fn call_function(name: &str, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
16        match name {
17            "length" => Self::length(args),
18            "type" => Self::type_of(args),
19            "makeArray" => Self::make_array(args),
20            "filter" => Self::filter(args),
21            "map" => Self::map(args),
22            "foldl" => Self::foldl(args),
23            "foldr" => Self::foldr(args),
24            "range" => Self::range(args),
25            "join" => Self::join(args),
26            "split" => Self::split(args),
27            "contains" => Self::contains(args),
28            "startsWith" => Self::starts_with(args),
29            "endsWith" => Self::ends_with(args),
30            "toLower" => Self::to_lower(args),
31            "toUpper" => Self::to_upper(args),
32            "trim" => Self::trim(args),
33            "substr" => Self::substr(args),
34            "char" => Self::char_fn(args),
35            "codepoint" => Self::codepoint(args),
36            "toString" => Self::to_string(args),
37            "parseInt" => Self::parse_int(args),
38            "parseJson" => Self::parse_json(args),
39            "encodeUTF8" => Self::encode_utf8(args),
40            "decodeUTF8" => Self::decode_utf8(args),
41            "md5" => Self::md5(args),
42            "base64" => Self::base64(args),
43            "base64Decode" => Self::base64_decode(args),
44            "manifestJson" => Self::manifest_json(args),
45            "manifestJsonEx" => Self::manifest_json_ex(args),
46            "manifestYaml" => Self::manifest_yaml(args),
47            "escapeStringJson" => Self::escape_string_json(args),
48            "escapeStringYaml" => Self::escape_string_yaml(args),
49            "escapeStringPython" => Self::escape_string_python(args),
50            "escapeStringBash" => Self::escape_string_bash(args),
51            "escapeStringDollars" => Self::escape_string_dollars(args),
52            "stringChars" => Self::string_chars(args),
53            "stringBytes" => Self::string_bytes(args),
54            "format" => Self::format(args),
55            "isArray" => Self::is_array(args),
56            "isBoolean" => Self::is_boolean(args),
57            "isFunction" => Self::is_function(args),
58            "isNumber" => Self::is_number(args),
59            "isObject" => Self::is_object(args),
60            "isString" => Self::is_string(args),
61            "count" => Self::count(args),
62            "find" => Self::find(args),
63            "member" => Self::member(args),
64            "modulo" => Self::modulo(args),
65            "pow" => Self::pow(args),
66            "exp" => Self::exp(args),
67            "log" => Self::log(args),
68            "sqrt" => Self::sqrt(args),
69            "sin" => Self::sin(args),
70            "cos" => Self::cos(args),
71            "tan" => Self::tan(args),
72            "asin" => Self::asin(args),
73            "acos" => Self::acos(args),
74            "atan" => Self::atan(args),
75            "floor" => Self::floor(args),
76            "ceil" => Self::ceil(args),
77            "round" => Self::round(args),
78            "abs" => Self::abs(args),
79            "max" => Self::max(args),
80            "min" => Self::min(args),
81            "clamp" => Self::clamp(args),
82            "assertEqual" => Self::assert_equal(args),
83            "trace" => Self::trace(args),
84            "sort" => Self::sort(args),
85            "uniq" => Self::uniq(args),
86            "reverse" => Self::reverse(args),
87            "all" => Self::all(args),
88            "any" => Self::any(args),
89            "mergePatch" => Self::merge_patch(args),
90            "get" => Self::get(args),
91            "id" => Self::id(args),
92            "equals" => Self::equals(args),
93            "lines" => Self::lines(args),
94            "strReplace" => Self::str_replace(args),
95            "sha1" => Self::sha1(args),
96            "sha256" => Self::sha256(args),
97            "sha3" => Self::sha3(args),
98            "sha512" => Self::sha512(args),
99            "asciiLower" => Self::ascii_lower(args),
100            "asciiUpper" => Self::ascii_upper(args),
101            "set" => Self::set(args),
102            "flatMap" => Self::flat_map(args),
103            "mapWithIndex" => Self::map_with_index(args),
104            "lstripChars" => Self::lstrip_chars(args),
105            "rstripChars" => Self::rstrip_chars(args),
106            "stripChars" => Self::strip_chars(args),
107            "findSubstr" => Self::find_substr(args),
108            "repeat" => Self::repeat(args),
109            "setMember" => Self::set_member(args),
110            "setUnion" => Self::set_union(args),
111            "setInter" => Self::set_inter(args),
112            "setDiff" => Self::set_diff(args),
113            "objectFields" => Self::object_fields(args),
114            "objectFieldsAll" => Self::object_fields_all(args),
115            "objectHas" => Self::object_has(args),
116            "objectHasAll" => Self::object_has_all(args),
117            "objectValues" => Self::object_values(args),
118            "objectValuesAll" => Self::object_values_all(args),
119            "prune" => Self::prune(args),
120            "mapWithKey" => Self::map_with_key(args),
121            "manifestIni" => Self::manifest_ini(args),
122            "manifestPython" => Self::manifest_python(args),
123            "manifestCpp" => Self::manifest_cpp(args),
124            "manifestXmlJsonml" => Self::manifest_xml_jsonml(args),
125            "log2" => Self::log2(args),
126            "log10" => Self::log10(args),
127            "log1p" => Self::log1p(args),
128            "expm1" => Self::expm1(args),
129            _ => Err(JsonnetError::runtime_error(format!("Unknown std function: {}", name))),
130        }
131    }
132
133    /// std.length(x) - returns length of array, string, or object
134    pub fn length(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
135        Self::check_args(&args, 1, "length")?;
136        match &args[0] {
137            JsonnetValue::Array(arr) => Ok(JsonnetValue::number(arr.len() as f64)),
138            JsonnetValue::String(s) => Ok(JsonnetValue::number(s.len() as f64)),
139            JsonnetValue::Object(obj) => Ok(JsonnetValue::number(obj.len() as f64)),
140            _ => Err(JsonnetError::type_error("length() requires array, string, or object")),
141        }
142    }
143
144    /// std.type(x) - returns type of value as string
145    fn type_of(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
146        Self::check_args(&args, 1, "type")?;
147        let type_str = args[0].type_name();
148        Ok(JsonnetValue::string(type_str))
149    }
150
151    /// std.makeArray(n, func) - creates array by calling func n times
152    fn make_array(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
153        Self::check_args(&args, 2, "makeArray")?;
154        let _n = args[0].as_number()? as usize;
155        let _func = &args[1];
156
157        // TODO: Function call implementation needed
158        // For now, return empty array
159        Ok(JsonnetValue::array(vec![]))
160    }
161
162    /// std.filter(func, arr) - filters array using predicate function
163    fn filter(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
164        Self::check_args(&args, 2, "filter")?;
165        // TODO: Implement filtering
166        Ok(args[1].clone())
167    }
168
169    /// std.map(func, arr) - maps function over array
170    fn map(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
171        Self::check_args(&args, 2, "map")?;
172        // TODO: Implement mapping
173        Ok(args[1].clone())
174    }
175
176    /// std.foldl(func, arr, init) - left fold
177    fn foldl(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
178        Self::check_args(&args, 3, "foldl")?;
179        // TODO: Implement folding
180        Ok(args[2].clone())
181    }
182
183    /// std.foldr(func, arr, init) - right fold
184    fn foldr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
185        Self::check_args(&args, 3, "foldr")?;
186        // TODO: Implement folding
187        Ok(args[2].clone())
188    }
189
190    /// std.range(n) - creates array [0, 1, ..., n-1]
191    fn range(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
192        Self::check_args(&args, 1, "range")?;
193        let n = args[0].as_number()? as usize;
194        let arr: Vec<JsonnetValue> = (0..n).map(|i| JsonnetValue::number(i as f64)).collect();
195        Ok(JsonnetValue::array(arr))
196    }
197
198    /// std.join(sep, arr) - joins array elements with separator
199    fn join(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
200        Self::check_args(&args, 2, "join")?;
201        let sep = args[0].as_string()?;
202        let arr = args[1].as_array()?;
203
204        let mut result = String::new();
205        for (i, item) in arr.iter().enumerate() {
206            if i > 0 {
207                result.push_str(sep);
208            }
209            result.push_str(&item.to_string());
210        }
211
212        Ok(JsonnetValue::string(result))
213    }
214
215    /// std.split(str, sep) - splits string by separator
216    fn split(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
217        Self::check_args(&args, 2, "split")?;
218        let s = args[0].as_string()?;
219        let sep = args[1].as_string()?;
220
221        let parts: Vec<JsonnetValue> = s.split(sep).map(JsonnetValue::string).collect();
222        Ok(JsonnetValue::array(parts))
223    }
224
225    /// std.contains(arr, elem) - checks if array contains element
226    fn contains(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
227        Self::check_args(&args, 2, "contains")?;
228        let arr = args[0].as_array()?;
229        let contains = arr.iter().any(|item| item.equals(&args[1]));
230        Ok(JsonnetValue::boolean(contains))
231    }
232
233    /// std.startsWith(str, prefix) - checks if string starts with prefix
234    fn starts_with(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
235        Self::check_args(&args, 2, "startsWith")?;
236        let s = args[0].as_string()?;
237        let prefix = args[1].as_string()?;
238        Ok(JsonnetValue::boolean(s.starts_with(prefix)))
239    }
240
241    /// std.endsWith(str, suffix) - checks if string ends with suffix
242    fn ends_with(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
243        Self::check_args(&args, 2, "endsWith")?;
244        let s = args[0].as_string()?;
245        let suffix = args[1].as_string()?;
246        Ok(JsonnetValue::boolean(s.ends_with(suffix)))
247    }
248
249    /// std.substr(str, from, len) - extracts substring
250    fn substr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
251        Self::check_args(&args, 3, "substr")?;
252        let s = args[0].as_string()?;
253        let from = args[1].as_number()? as usize;
254        let len = args[2].as_number()? as usize;
255
256        let substr = if from >= s.len() {
257            ""
258        } else {
259            let end = (from + len).min(s.len());
260            &s[from..end]
261        };
262
263        Ok(JsonnetValue::string(substr))
264    }
265
266    /// std.char(n) - returns character for codepoint
267    fn char_fn(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
268        Self::check_args(&args, 1, "char")?;
269        let n = args[0].as_number()? as u32;
270        match char::from_u32(n) {
271            Some(c) => Ok(JsonnetValue::string(c.to_string())),
272            None => Err(JsonnetError::runtime_error("Invalid codepoint")),
273        }
274    }
275
276    /// std.codepoint(str) - returns codepoint of first character
277    fn codepoint(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
278        Self::check_args(&args, 1, "codepoint")?;
279        let s = args[0].as_string()?;
280        match s.chars().next() {
281            Some(c) => Ok(JsonnetValue::number(c as u32 as f64)),
282            None => Err(JsonnetError::runtime_error("Empty string")),
283        }
284    }
285
286    /// std.toString(x) - converts value to string
287    fn to_string(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
288        Self::check_args(&args, 1, "toString")?;
289        Ok(JsonnetValue::string(args[0].to_string()))
290    }
291
292    /// std.parseInt(str) - parses string as integer
293    fn parse_int(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
294        Self::check_args(&args, 1, "parseInt")?;
295        let s = args[0].as_string()?;
296        match s.parse::<f64>() {
297            Ok(n) => Ok(JsonnetValue::number(n)),
298            Err(_) => Err(JsonnetError::runtime_error("Invalid number format")),
299        }
300    }
301
302    /// std.parseJson(str) - parses JSON string
303    fn parse_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
304        Self::check_args(&args, 1, "parseJson")?;
305        let s = args[0].as_string()?;
306        match serde_json::from_str::<serde_json::Value>(s) {
307            Ok(value) => Ok(JsonnetValue::from_json_value(value)),
308            Err(_) => Err(JsonnetError::runtime_error("Invalid JSON")),
309        }
310    }
311
312    /// std.encodeUTF8(str) - encodes string as UTF-8 bytes
313    fn encode_utf8(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
314        Self::check_args(&args, 1, "encodeUTF8")?;
315        let s = args[0].as_string()?;
316        let bytes: Vec<JsonnetValue> = s.as_bytes().iter().map(|&b| JsonnetValue::number(b as f64)).collect();
317        Ok(JsonnetValue::array(bytes))
318    }
319
320    /// std.decodeUTF8(arr) - decodes UTF-8 bytes to string
321    fn decode_utf8(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
322        Self::check_args(&args, 1, "decodeUTF8")?;
323        let arr = args[0].as_array()?;
324        let mut bytes = Vec::new();
325        for item in arr {
326            let b = item.as_number()? as u8;
327            bytes.push(b);
328        }
329        match String::from_utf8(bytes) {
330            Ok(s) => Ok(JsonnetValue::string(s)),
331            Err(_) => Err(JsonnetError::runtime_error("Invalid UTF-8 sequence")),
332        }
333    }
334
335    /// std.md5(str) - computes MD5 hash
336    fn md5(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
337        Self::check_args(&args, 1, "md5")?;
338        let s = args[0].as_string()?;
339        use md5::{Md5, Digest};
340        let mut hasher = Md5::new();
341        hasher.update(s.as_bytes());
342        let result = hasher.finalize();
343        Ok(JsonnetValue::string(format!("{:x}", result)))
344    }
345
346    /// std.base64(str) - base64 encodes string
347    fn base64(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
348        Self::check_args(&args, 1, "base64")?;
349        let s = args[0].as_string()?;
350        use base64::{Engine as _, engine::general_purpose};
351        let encoded = general_purpose::STANDARD.encode(s.as_bytes());
352        Ok(JsonnetValue::string(encoded))
353    }
354
355    /// std.base64Decode(str) - base64 decodes string
356    fn base64_decode(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
357        Self::check_args(&args, 1, "base64Decode")?;
358        let s = args[0].as_string()?;
359        use base64::{Engine as _, engine::general_purpose};
360        match general_purpose::STANDARD.decode(s.as_bytes()) {
361            Ok(bytes) => match String::from_utf8(bytes) {
362                Ok(decoded) => Ok(JsonnetValue::string(decoded)),
363                Err(_) => Err(JsonnetError::runtime_error("Invalid UTF-8 in decoded data")),
364            },
365            Err(_) => Err(JsonnetError::runtime_error("Invalid base64")),
366        }
367    }
368
369    /// std.manifestJson(x) - pretty prints value as JSON
370    fn manifest_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
371        Self::check_args(&args, 1, "manifestJson")?;
372        let json = serde_json::to_string_pretty(&args[0].to_json_value())?;
373        Ok(JsonnetValue::string(json))
374    }
375
376    /// std.manifestJsonEx(x, indent) - pretty prints value as JSON with custom indent
377    fn manifest_json_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
378        Self::check_args(&args, 2, "manifestJsonEx")?;
379        // TODO: Implement custom indentation
380        Self::manifest_json(vec![args[0].clone()])
381    }
382
383    /// std.manifestYaml(x) - pretty prints value as YAML
384    #[cfg(feature = "yaml")]
385    fn manifest_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
386        Self::check_args(&args, 1, "manifestYaml")?;
387        let yaml = serde_yaml::to_string(&args[0].to_json_value())?;
388        Ok(JsonnetValue::string(yaml))
389    }
390
391    /// std.manifestYaml(x) - pretty prints value as YAML (fallback when yaml feature disabled)
392    #[cfg(not(feature = "yaml"))]
393    fn manifest_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
394        Self::check_args(&args, 1, "manifestYaml")?;
395        // Fallback to JSON when YAML feature is disabled
396        Self::manifest_json(args)
397    }
398
399    // String escaping functions
400    fn escape_string_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
401        Self::check_args(&args, 1, "escapeStringJson")?;
402        let s = args[0].as_string()?;
403        let escaped = serde_json::to_string(s)?;
404        Ok(JsonnetValue::string(escaped))
405    }
406
407    #[cfg(feature = "yaml")]
408    fn escape_string_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
409        Self::check_args(&args, 1, "escapeStringYaml")?;
410        // TODO: Implement proper YAML escaping
411        Self::escape_string_json(args)
412    }
413
414    #[cfg(not(feature = "yaml"))]
415    fn escape_string_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
416        Self::check_args(&args, 1, "escapeStringYaml")?;
417        // Fallback to JSON escaping when YAML feature is disabled
418        Self::escape_string_json(args)
419    }
420
421    fn escape_string_python(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
422        Self::check_args(&args, 1, "escapeStringPython")?;
423        let s = args[0].as_string()?;
424        let escaped = s.escape_default().to_string();
425        Ok(JsonnetValue::string(format!("'{}'", escaped)))
426    }
427
428    fn escape_string_bash(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
429        Self::check_args(&args, 1, "escapeStringBash")?;
430        let s = args[0].as_string()?;
431        let escaped = s.replace("'", "'\"'\"'").replace("\\", "\\\\");
432        Ok(JsonnetValue::string(format!("'{}'", escaped)))
433    }
434
435    fn escape_string_dollars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
436        Self::check_args(&args, 1, "escapeStringDollars")?;
437        let s = args[0].as_string()?;
438        let escaped = s.replace("$$", "$").replace("$", "$$");
439        Ok(JsonnetValue::string(escaped))
440    }
441
442    // Additional string functions
443    fn string_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
444        Self::check_args(&args, 1, "stringChars")?;
445        let s = args[0].as_string()?;
446        let chars: Vec<JsonnetValue> = s.chars().map(|c| JsonnetValue::string(c.to_string())).collect();
447        Ok(JsonnetValue::array(chars))
448    }
449
450    fn string_bytes(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
451        Self::check_args(&args, 1, "stringBytes")?;
452        let s = args[0].as_string()?;
453        let bytes: Vec<JsonnetValue> = s.as_bytes().iter().map(|&b| JsonnetValue::number(b as f64)).collect();
454        Ok(JsonnetValue::array(bytes))
455    }
456
457    fn format(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
458        // TODO: Implement format function
459        Self::check_args(&args, 2, "format")?;
460        Ok(JsonnetValue::string("<formatted>".to_string()))
461    }
462
463    // Type checking functions
464    fn is_array(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
465        Self::check_args(&args, 1, "isArray")?;
466        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Array(_))))
467    }
468
469    fn is_boolean(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
470        Self::check_args(&args, 1, "isBoolean")?;
471        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Boolean(_))))
472    }
473
474    fn is_function(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
475        Self::check_args(&args, 1, "isFunction")?;
476        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Function(_))))
477    }
478
479    fn is_number(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
480        Self::check_args(&args, 1, "isNumber")?;
481        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Number(_))))
482    }
483
484    fn is_object(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
485        Self::check_args(&args, 1, "isObject")?;
486        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Object(_))))
487    }
488
489    fn is_string(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
490        Self::check_args(&args, 1, "isString")?;
491        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::String(_))))
492    }
493
494    // Array functions
495    fn count(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
496        Self::check_args(&args, 2, "count")?;
497        let arr = args[0].as_array()?;
498        let elem = &args[1];
499        let count = arr.iter().filter(|item| item.equals(elem)).count() as f64;
500        Ok(JsonnetValue::number(count))
501    }
502
503    fn find(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
504        Self::check_args(&args, 2, "find")?;
505        match (&args[0], &args[1]) {
506            (JsonnetValue::Array(arr), value) => {
507                let mut indices = Vec::new();
508                for (i, item) in arr.iter().enumerate() {
509                    if item == value {
510                        indices.push(JsonnetValue::Number(i as f64));
511                    }
512                }
513                Ok(JsonnetValue::array(indices))
514            }
515            _ => Err(JsonnetError::runtime_error("find expects array and search value")),
516        }
517    }
518
519    fn member(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
520        Self::contains(args)
521    }
522
523    // Math functions
524    fn modulo(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
525        Self::check_args(&args, 2, "modulo")?;
526        let a = args[0].as_number()?;
527        let b = args[1].as_number()?;
528        if b == 0.0 {
529            return Err(JsonnetError::DivisionByZero);
530        }
531        Ok(JsonnetValue::number(a % b))
532    }
533
534    fn pow(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
535        Self::check_args(&args, 2, "pow")?;
536        let a = args[0].as_number()?;
537        let b = args[1].as_number()?;
538        Ok(JsonnetValue::number(a.powf(b)))
539    }
540
541    fn exp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
542        Self::check_args(&args, 1, "exp")?;
543        let x = args[0].as_number()?;
544        Ok(JsonnetValue::number(x.exp()))
545    }
546
547    fn log(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
548        Self::check_args(&args, 1, "log")?;
549        let x = args[0].as_number()?;
550        if x <= 0.0 {
551            return Err(JsonnetError::runtime_error("log of non-positive number"));
552        }
553        Ok(JsonnetValue::number(x.ln()))
554    }
555
556    fn sqrt(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
557        Self::check_args(&args, 1, "sqrt")?;
558        let x = args[0].as_number()?;
559        if x < 0.0 {
560            return Err(JsonnetError::runtime_error("sqrt of negative number"));
561        }
562        Ok(JsonnetValue::number(x.sqrt()))
563    }
564
565    fn sin(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
566        Self::check_args(&args, 1, "sin")?;
567        let x = args[0].as_number()?;
568        Ok(JsonnetValue::number(x.sin()))
569    }
570
571    fn cos(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
572        Self::check_args(&args, 1, "cos")?;
573        let x = args[0].as_number()?;
574        Ok(JsonnetValue::number(x.cos()))
575    }
576
577    fn tan(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
578        Self::check_args(&args, 1, "tan")?;
579        let x = args[0].as_number()?;
580        Ok(JsonnetValue::number(x.tan()))
581    }
582
583    fn asin(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
584        Self::check_args(&args, 1, "asin")?;
585        let x = args[0].as_number()?;
586        Ok(JsonnetValue::number(x.asin()))
587    }
588
589    fn acos(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
590        Self::check_args(&args, 1, "acos")?;
591        let x = args[0].as_number()?;
592        Ok(JsonnetValue::number(x.acos()))
593    }
594
595    fn atan(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
596        Self::check_args(&args, 1, "atan")?;
597        let x = args[0].as_number()?;
598        Ok(JsonnetValue::number(x.atan()))
599    }
600
601    fn floor(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
602        Self::check_args(&args, 1, "floor")?;
603        let x = args[0].as_number()?;
604        Ok(JsonnetValue::number(x.floor()))
605    }
606
607    fn ceil(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
608        Self::check_args(&args, 1, "ceil")?;
609        let x = args[0].as_number()?;
610        Ok(JsonnetValue::number(x.ceil()))
611    }
612
613    fn round(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
614        Self::check_args(&args, 1, "round")?;
615        let x = args[0].as_number()?;
616        Ok(JsonnetValue::number(x.round()))
617    }
618
619    fn abs(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
620        Self::check_args(&args, 1, "abs")?;
621        let x = args[0].as_number()?;
622        Ok(JsonnetValue::number(x.abs()))
623    }
624
625    fn max(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
626        Self::check_args(&args, 1, "max")?;
627        let arr = args[0].as_array()?;
628        if arr.is_empty() {
629            return Err(JsonnetError::runtime_error("max() called on empty array"));
630        }
631        let mut max_val = f64::NEG_INFINITY;
632        for item in arr {
633            let val = item.as_number()?;
634            if val > max_val {
635                max_val = val;
636            }
637        }
638        Ok(JsonnetValue::number(max_val))
639    }
640
641    fn min(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
642        Self::check_args(&args, 1, "min")?;
643        let arr = args[0].as_array()?;
644        if arr.is_empty() {
645            return Err(JsonnetError::runtime_error("min() called on empty array"));
646        }
647        let mut min_val = f64::INFINITY;
648        for item in arr {
649            let val = item.as_number()?;
650            if val < min_val {
651                min_val = val;
652            }
653        }
654        Ok(JsonnetValue::number(min_val))
655    }
656
657    fn clamp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
658        Self::check_args(&args, 3, "clamp")?;
659        let x = args[0].as_number()?;
660        let min = args[1].as_number()?;
661        let max = args[2].as_number()?;
662        let clamped = x.max(min).min(max);
663        Ok(JsonnetValue::number(clamped))
664    }
665
666    fn assert_equal(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
667        Self::check_args(&args, 2, "assertEqual")?;
668        if !args[0].equals(&args[1]) {
669            return Err(JsonnetError::assertion_failed(format!(
670                "Assertion failed: {} != {}",
671                args[0], args[1]
672            )));
673        }
674        Ok(JsonnetValue::boolean(true))
675    }
676
677    fn trace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
678        Self::check_args(&args, 2, "trace")?;
679        // Print the second argument to stderr for tracing
680        eprintln!("TRACE: {:?}", args[1]);
681        // Return the first argument
682        Ok(args[0].clone())
683    }
684
685    // Array manipulation functions
686    fn sort(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
687        Self::check_args(&args, 1, "sort")?;
688        // TODO: Implement sorting
689        Ok(args[0].clone())
690    }
691
692    fn uniq(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
693        Self::check_args(&args, 1, "uniq")?;
694        // TODO: Implement uniqueness filtering
695        Ok(args[0].clone())
696    }
697
698    fn reverse(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
699        Self::check_args(&args, 1, "reverse")?;
700        let arr = args[0].as_array()?;
701        let reversed: Vec<JsonnetValue> = arr.iter().rev().cloned().collect();
702        Ok(JsonnetValue::array(reversed))
703    }
704
705    // Object functions
706    fn merge_patch(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
707        Self::check_args(&args, 2, "mergePatch")?;
708        // TODO: Implement merge patch
709        Ok(args[0].clone())
710    }
711
712    fn get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
713        Self::check_args(&args, 3, "get")?;
714        let obj = args[0].as_object()?;
715        let key = args[1].as_string()?;
716        let default = &args[2];
717        Ok(obj.get(key).unwrap_or(default).clone())
718    }
719
720    fn object_fields(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
721        Self::check_args(&args, 1, "objectFields")?;
722        let obj = args[0].as_object()?;
723        let fields: Vec<JsonnetValue> = obj.keys()
724            .filter(|&k| !k.starts_with('_')) // Filter out hidden fields
725            .map(|k| JsonnetValue::string(k.clone()))
726            .collect();
727        Ok(JsonnetValue::array(fields))
728    }
729
730    fn object_fields_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
731        Self::check_args(&args, 1, "objectFieldsAll")?;
732        let obj = args[0].as_object()?;
733        let fields: Vec<JsonnetValue> = obj.keys()
734            .map(|k| JsonnetValue::string(k.clone()))
735            .collect();
736        Ok(JsonnetValue::array(fields))
737    }
738
739    fn object_has(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
740        Self::check_args(&args, 2, "objectHas")?;
741        let obj = args[0].as_object()?;
742        let key = args[1].as_string()?;
743        Ok(JsonnetValue::boolean(obj.contains_key(key) && !key.starts_with('_')))
744    }
745
746    fn object_has_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
747        Self::check_args(&args, 2, "objectHasAll")?;
748        let obj = args[0].as_object()?;
749        let key = args[1].as_string()?;
750        Ok(JsonnetValue::boolean(obj.contains_key(key)))
751    }
752
753    fn object_values(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
754        Self::check_args(&args, 1, "objectValues")?;
755        let obj = args[0].as_object()?;
756        let values: Vec<JsonnetValue> = obj.iter()
757            .filter(|(k, _)| !k.starts_with('_'))
758            .map(|(_, v)| v.clone())
759            .collect();
760        Ok(JsonnetValue::array(values))
761    }
762
763    fn object_values_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
764        Self::check_args(&args, 1, "objectValuesAll")?;
765        let obj = args[0].as_object()?;
766        let values: Vec<JsonnetValue> = obj.values().cloned().collect();
767        Ok(JsonnetValue::array(values))
768    }
769
770    fn prune(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
771        Self::check_args(&args, 1, "prune")?;
772        // TODO: Implement pruning (remove null values)
773        Ok(args[0].clone())
774    }
775
776    fn map_with_key(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
777        Self::check_args(&args, 2, "mapWithKey")?;
778        // TODO: Implement mapWithKey
779        Ok(args[1].clone())
780    }
781
782    fn to_lower(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
783        Self::check_args(&args, 1, "toLower")?;
784        match &args[0] {
785            JsonnetValue::String(s) => Ok(JsonnetValue::string(s.to_lowercase())),
786            _ => Err(JsonnetError::runtime_error("toLower expects a string argument")),
787        }
788    }
789
790    fn to_upper(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
791        Self::check_args(&args, 1, "toUpper")?;
792        match &args[0] {
793            JsonnetValue::String(s) => Ok(JsonnetValue::string(s.to_uppercase())),
794            _ => Err(JsonnetError::runtime_error("toUpper expects a string argument")),
795        }
796    }
797
798    fn trim(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
799        Self::check_args(&args, 1, "trim")?;
800        match &args[0] {
801            JsonnetValue::String(s) => Ok(JsonnetValue::string(s.trim().to_string())),
802            _ => Err(JsonnetError::runtime_error("trim expects a string argument")),
803        }
804    }
805
806    fn all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
807        Self::check_args(&args, 1, "all")?;
808        match &args[0] {
809            JsonnetValue::Array(arr) => {
810                let result = arr.iter().all(|item| item.is_truthy());
811                Ok(JsonnetValue::boolean(result))
812            }
813            _ => Err(JsonnetError::runtime_error("all expects an array argument")),
814        }
815    }
816
817    fn any(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
818        Self::check_args(&args, 1, "any")?;
819        match &args[0] {
820            JsonnetValue::Array(arr) => {
821                let result = arr.iter().any(|item| item.is_truthy());
822                Ok(JsonnetValue::boolean(result))
823            }
824            _ => Err(JsonnetError::runtime_error("any expects an array argument")),
825        }
826    }
827
828    fn id(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
829        Self::check_args(&args, 1, "id")?;
830        Ok(args[0].clone())
831    }
832
833    fn equals(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
834        Self::check_args(&args, 2, "equals")?;
835        let a = &args[0];
836        let b = &args[1];
837
838        // First check primitive equality
839        if a == b {
840            return Ok(JsonnetValue::boolean(true));
841        }
842
843        // Check types
844        let ta = a.type_name();
845        let tb = b.type_name();
846        if ta != tb {
847            return Ok(JsonnetValue::boolean(false));
848        }
849
850        match (a, b) {
851            (JsonnetValue::Array(arr_a), JsonnetValue::Array(arr_b)) => {
852                if arr_a.len() != arr_b.len() {
853                    return Ok(JsonnetValue::boolean(false));
854                }
855                for (i, item_a) in arr_a.iter().enumerate() {
856                    let eq_args = vec![item_a.clone(), arr_b[i].clone()];
857                    if let Ok(JsonnetValue::Boolean(false)) = Self::equals(eq_args) {
858                        return Ok(JsonnetValue::boolean(false));
859                    }
860                }
861                Ok(JsonnetValue::boolean(true))
862            }
863            (JsonnetValue::Object(obj_a), JsonnetValue::Object(obj_b)) => {
864                // Get field names
865                let fields_a: Vec<String> = obj_a.keys().cloned().collect();
866                let fields_b: Vec<String> = obj_b.keys().cloned().collect();
867
868                if fields_a.len() != fields_b.len() {
869                    return Ok(JsonnetValue::boolean(false));
870                }
871
872                // Sort for comparison
873                let mut sorted_a = fields_a.clone();
874                sorted_a.sort();
875                let mut sorted_b = fields_b.clone();
876                sorted_b.sort();
877
878                if sorted_a != sorted_b {
879                    return Ok(JsonnetValue::boolean(false));
880                }
881
882                // Compare all field values
883                for field in sorted_a {
884                    let val_a = &obj_a[&field];
885                    let val_b = &obj_b[&field];
886                    let eq_args = vec![val_a.clone(), val_b.clone()];
887                    if let Ok(JsonnetValue::Boolean(false)) = Self::equals(eq_args) {
888                        return Ok(JsonnetValue::boolean(false));
889                    }
890                }
891                Ok(JsonnetValue::boolean(true))
892            }
893            _ => Ok(JsonnetValue::boolean(false)),
894        }
895    }
896
897    fn lines(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
898        Self::check_args(&args, 1, "lines")?;
899        match &args[0] {
900            JsonnetValue::Array(arr) => {
901                let mut lines = Vec::new();
902                for item in arr {
903                    // Convert to string representation like Jsonnet does
904                    match item {
905                        JsonnetValue::String(s) => lines.push(s.clone()),
906                        JsonnetValue::Number(n) => lines.push(n.to_string()),
907                        JsonnetValue::Boolean(b) => lines.push(b.to_string()),
908                        _ => lines.push(format!("{}", item)),
909                    }
910                }
911                lines.push("".to_string()); // Add trailing newline
912                Ok(JsonnetValue::string(lines.join("\n")))
913            }
914            _ => Err(JsonnetError::runtime_error("lines expects an array argument")),
915        }
916    }
917
918    fn str_replace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
919        Self::check_args(&args, 3, "strReplace")?;
920
921        let str_val = &args[0];
922        let from_val = &args[1];
923        let to_val = &args[2];
924
925        let str = str_val.as_string()?.to_string();
926        let from = from_val.as_string()?.to_string();
927        let to = to_val.as_string()?.to_string();
928
929        if from.is_empty() {
930            return Err(JsonnetError::runtime_error("'from' string must not be zero length"));
931        }
932
933        // Simple implementation using Rust's string replace
934        // For now, we'll use a simple approach. Full implementation would need
935        // the complex recursive logic from Google Jsonnet
936        let result = str.replace(&from, &to);
937        Ok(JsonnetValue::string(result))
938    }
939
940    fn sha1(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
941        Self::check_args(&args, 1, "sha1")?;
942        let input = args[0].as_string()?.as_bytes();
943        let mut hasher = Sha1::new();
944        hasher.update(input);
945        let result = hasher.finalize();
946        Ok(JsonnetValue::string(hex::encode(result)))
947    }
948
949    fn sha256(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
950        Self::check_args(&args, 1, "sha256")?;
951        let input = args[0].as_string()?.as_bytes();
952        let mut hasher = Sha256::new();
953        hasher.update(input);
954        let result = hasher.finalize();
955        Ok(JsonnetValue::string(hex::encode(result)))
956    }
957
958    fn sha3(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
959        Self::check_args(&args, 1, "sha3")?;
960        let input = args[0].as_string()?.as_bytes();
961        let mut hasher = Sha3_256::new();
962        hasher.update(input);
963        let result = hasher.finalize();
964        Ok(JsonnetValue::string(hex::encode(result)))
965    }
966
967    fn sha512(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
968        Self::check_args(&args, 1, "sha512")?;
969        let input = args[0].as_string()?.as_bytes();
970        let mut hasher = Sha512::new();
971        hasher.update(input);
972        let result = hasher.finalize();
973        Ok(JsonnetValue::string(hex::encode(result)))
974    }
975
976    fn ascii_lower(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
977        Self::check_args(&args, 1, "asciiLower")?;
978        let input = args[0].as_string()?;
979        Ok(JsonnetValue::string(input.to_ascii_lowercase()))
980    }
981
982    fn ascii_upper(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
983        Self::check_args(&args, 1, "asciiUpper")?;
984        let input = args[0].as_string()?;
985        Ok(JsonnetValue::string(input.to_ascii_uppercase()))
986    }
987
988    fn flat_map(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
989        Self::check_args(&args, 2, "flatMap")?;
990        let func = &args[0];
991        let arr = &args[1];
992
993        match arr {
994            JsonnetValue::Array(array) => {
995                let mut result = Vec::new();
996                for item in array {
997                    // Apply function to each item
998                    // For now, we'll implement a simple version that expects the function to return an array
999                    // Full implementation would need to evaluate the function
1000                    if let JsonnetValue::Array(sub_array) = item {
1001                        result.extend(sub_array.clone());
1002                    } else {
1003                        result.push(item.clone());
1004                    }
1005                }
1006                Ok(JsonnetValue::array(result))
1007            }
1008            JsonnetValue::String(s) => {
1009                // For strings, treat each character as an element
1010                let mut result = Vec::new();
1011                for ch in s.chars() {
1012                    // Apply function to each character - simplified implementation
1013                    result.push(JsonnetValue::string(ch.to_string()));
1014                }
1015                Ok(JsonnetValue::array(result))
1016            }
1017            _ => Err(JsonnetError::runtime_error("flatMap expects array or string as second argument")),
1018        }
1019    }
1020
1021    fn map_with_index(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1022        Self::check_args(&args, 2, "mapWithIndex")?;
1023        let func = &args[0];
1024        let arr = &args[1];
1025
1026        match arr {
1027            JsonnetValue::Array(array) => {
1028                let mut result = Vec::new();
1029                for (i, item) in array.iter().enumerate() {
1030                    // Apply function with index - simplified implementation
1031                    // In full implementation, this would call the function with (index, value)
1032                    result.push(JsonnetValue::array(vec![JsonnetValue::number(i as f64), item.clone()]));
1033                }
1034                Ok(JsonnetValue::array(result))
1035            }
1036            JsonnetValue::String(s) => {
1037                let mut result = Vec::new();
1038                for (i, ch) in s.chars().enumerate() {
1039                    result.push(JsonnetValue::array(vec![
1040                        JsonnetValue::number(i as f64),
1041                        JsonnetValue::string(ch.to_string())
1042                    ]));
1043                }
1044                Ok(JsonnetValue::array(result))
1045            }
1046            _ => Err(JsonnetError::runtime_error("mapWithIndex expects array or string as second argument")),
1047        }
1048    }
1049
1050    fn lstrip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1051        Self::check_args(&args, 2, "lstripChars")?;
1052        let str_val = args[0].as_string()?;
1053        let chars_val = args[1].as_string()?;
1054
1055        let chars_set: std::collections::HashSet<char> = chars_val.chars().collect();
1056        let result: String = str_val.chars()
1057            .skip_while(|c| chars_set.contains(c))
1058            .collect();
1059
1060        Ok(JsonnetValue::string(result))
1061    }
1062
1063    fn rstrip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1064        Self::check_args(&args, 2, "rstripChars")?;
1065        let str_val = args[0].as_string()?;
1066        let chars_val = args[1].as_string()?;
1067
1068        let chars_set: std::collections::HashSet<char> = chars_val.chars().collect();
1069        let result: String = str_val.chars()
1070            .rev()
1071            .skip_while(|c| chars_set.contains(c))
1072            .collect::<Vec<char>>()
1073            .into_iter()
1074            .rev()
1075            .collect();
1076
1077        Ok(JsonnetValue::string(result))
1078    }
1079
1080    fn strip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1081        Self::check_args(&args, 2, "stripChars")?;
1082        let str_val = &args[0];
1083        let chars_val = &args[1];
1084
1085        // First apply lstripChars, then rstripChars
1086        let lstripped_args = vec![str_val.clone(), chars_val.clone()];
1087        let lstripped = Self::lstrip_chars(lstripped_args)?;
1088        let rstripped_args = vec![lstripped, chars_val.clone()];
1089        Self::rstrip_chars(rstripped_args)
1090    }
1091
1092    fn find_substr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1093        Self::check_args(&args, 2, "findSubstr")?;
1094        let pat = args[0].as_string()?;
1095        let str = args[1].as_string()?;
1096
1097        if pat.is_empty() {
1098            return Err(JsonnetError::runtime_error("findSubstr pattern cannot be empty"));
1099        }
1100
1101        let mut result = Vec::new();
1102        let mut start = 0;
1103
1104        while let Some(pos) = str[start..].find(&pat) {
1105            result.push(JsonnetValue::number((start + pos) as f64));
1106            start += pos + pat.len();
1107        }
1108
1109        Ok(JsonnetValue::array(result))
1110    }
1111
1112    fn repeat(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1113        Self::check_args(&args, 2, "repeat")?;
1114        let what = &args[0];
1115        let count_val = &args[1];
1116
1117        let count = if let JsonnetValue::Number(n) = count_val {
1118            *n as usize
1119        } else {
1120            return Err(JsonnetError::runtime_error("repeat count must be a number"));
1121        };
1122
1123        match what {
1124            JsonnetValue::String(s) => {
1125                let repeated = s.repeat(count);
1126                Ok(JsonnetValue::string(repeated))
1127            }
1128            JsonnetValue::Array(arr) => {
1129                let mut result = Vec::new();
1130                for _ in 0..count {
1131                    result.extend(arr.clone());
1132                }
1133                Ok(JsonnetValue::array(result))
1134            }
1135            _ => Err(JsonnetError::runtime_error("repeat first argument must be string or array")),
1136        }
1137    }
1138
1139    fn set(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1140        Self::check_args(&args, 1, "set")?;
1141        match &args[0] {
1142            JsonnetValue::Array(arr) => {
1143                // Remove duplicates while preserving order
1144                let mut result = Vec::new();
1145
1146                for item in arr {
1147                    // Check if item is already in result
1148                    let mut found = false;
1149                    for existing in &result {
1150                        if existing == item {
1151                            found = true;
1152                            break;
1153                        }
1154                    }
1155                    if !found {
1156                        result.push(item.clone());
1157                    }
1158                }
1159
1160                Ok(JsonnetValue::array(result))
1161            }
1162            _ => Err(JsonnetError::runtime_error("set expects an array argument")),
1163        }
1164    }
1165
1166    fn set_member(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1167        Self::check_args(&args, 2, "setMember")?;
1168        let value = &args[0];
1169        let arr = match &args[1] {
1170            JsonnetValue::Array(a) => a,
1171            _ => return Err(JsonnetError::runtime_error("setMember expects array as second argument")),
1172        };
1173
1174        for item in arr {
1175            if item == value {
1176                return Ok(JsonnetValue::boolean(true));
1177            }
1178        }
1179        Ok(JsonnetValue::boolean(false))
1180    }
1181
1182    fn set_union(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1183        Self::check_args(&args, 2, "setUnion")?;
1184        let arr_a = match &args[0] {
1185            JsonnetValue::Array(a) => a,
1186            _ => return Err(JsonnetError::runtime_error("setUnion expects arrays as arguments")),
1187        };
1188        let arr_b = match &args[1] {
1189            JsonnetValue::Array(a) => a,
1190            _ => return Err(JsonnetError::runtime_error("setUnion expects arrays as arguments")),
1191        };
1192
1193        let mut result = Vec::new();
1194
1195        // Add all elements from first array (preserving order)
1196        for item in arr_a {
1197            let mut found = false;
1198            for existing in &result {
1199                if existing == item {
1200                    found = true;
1201                    break;
1202                }
1203            }
1204            if !found {
1205                result.push(item.clone());
1206            }
1207        }
1208
1209        // Add elements from second array that aren't already in result
1210        for item in arr_b {
1211            let mut found = false;
1212            for existing in &result {
1213                if existing == item {
1214                    found = true;
1215                    break;
1216                }
1217            }
1218            if !found {
1219                result.push(item.clone());
1220            }
1221        }
1222
1223        Ok(JsonnetValue::array(result))
1224    }
1225
1226    fn set_inter(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1227        Self::check_args(&args, 2, "setInter")?;
1228        let arr_a = match &args[0] {
1229            JsonnetValue::Array(a) => a,
1230            _ => return Err(JsonnetError::runtime_error("setInter expects arrays as arguments")),
1231        };
1232        let arr_b = match &args[1] {
1233            JsonnetValue::Array(a) => a,
1234            _ => return Err(JsonnetError::runtime_error("setInter expects arrays as arguments")),
1235        };
1236
1237        let mut result = Vec::new();
1238
1239        for item_a in arr_a {
1240            // Check if item_a exists in arr_b
1241            let mut found_in_b = false;
1242            for item_b in arr_b {
1243                if item_a == item_b {
1244                    found_in_b = true;
1245                    break;
1246                }
1247            }
1248
1249            if found_in_b {
1250                // Check if item_a is already in result
1251                let mut already_in_result = false;
1252                for existing in &result {
1253                    if existing == item_a {
1254                        already_in_result = true;
1255                        break;
1256                    }
1257                }
1258                if !already_in_result {
1259                    result.push(item_a.clone());
1260                }
1261            }
1262        }
1263
1264        Ok(JsonnetValue::array(result))
1265    }
1266
1267    fn set_diff(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1268        Self::check_args(&args, 2, "setDiff")?;
1269        let arr_a = match &args[0] {
1270            JsonnetValue::Array(a) => a,
1271            _ => return Err(JsonnetError::runtime_error("setDiff expects arrays as arguments")),
1272        };
1273        let arr_b = match &args[1] {
1274            JsonnetValue::Array(a) => a,
1275            _ => return Err(JsonnetError::runtime_error("setDiff expects arrays as arguments")),
1276        };
1277
1278        let mut result = Vec::new();
1279
1280        for item_a in arr_a {
1281            // Check if item_a does NOT exist in arr_b
1282            let mut found_in_b = false;
1283            for item_b in arr_b {
1284                if item_a == item_b {
1285                    found_in_b = true;
1286                    break;
1287                }
1288            }
1289
1290            if !found_in_b {
1291                // Check if item_a is already in result
1292                let mut already_in_result = false;
1293                for existing in &result {
1294                    if existing == item_a {
1295                        already_in_result = true;
1296                        break;
1297                    }
1298                }
1299                if !already_in_result {
1300                    result.push(item_a.clone());
1301                }
1302            }
1303        }
1304
1305        Ok(JsonnetValue::array(result))
1306    }
1307
1308    // Phase 4: Advanced Features
1309
1310    // Manifest functions
1311    fn manifest_ini(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1312        Self::check_args(&args, 1, "manifestIni")?;
1313        // Simplified INI format - convert object to INI-like format
1314        match &args[0] {
1315            JsonnetValue::Object(obj) => {
1316                let mut result = String::new();
1317                for (key, value) in obj {
1318                    if !key.starts_with('_') {
1319                        result.push_str(&format!("[{}]\n", key));
1320                        if let JsonnetValue::Object(section) = value {
1321                            for (k, v) in section {
1322                                if !k.starts_with('_') {
1323                                    result.push_str(&format!("{}={}\n", k, v));
1324                                }
1325                            }
1326                        }
1327                        result.push('\n');
1328                    }
1329                }
1330                Ok(JsonnetValue::string(result.trim().to_string()))
1331            }
1332            _ => Err(JsonnetError::runtime_error("manifestIni expects an object")),
1333        }
1334    }
1335
1336    fn manifest_python(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1337        Self::check_args(&args, 1, "manifestPython")?;
1338        // Generate Python dict representation
1339        let json_str = serde_json::to_string(&args[0].to_json_value())?;
1340        // Simple conversion - replace JSON syntax with Python dict syntax
1341        let python_str = json_str
1342            .replace("null", "None")
1343            .replace("true", "True")
1344            .replace("false", "False");
1345        Ok(JsonnetValue::string(python_str))
1346    }
1347
1348    fn manifest_cpp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1349        Self::check_args(&args, 1, "manifestCpp")?;
1350        // Simplified C++ code generation
1351        let json_str = serde_json::to_string(&args[0].to_json_value())?;
1352        let cpp_str = format!("// Generated C++ code\nconst char* jsonData = R\"json(\n{}\n)json\";", json_str);
1353        Ok(JsonnetValue::string(cpp_str))
1354    }
1355
1356    fn manifest_xml_jsonml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1357        Self::check_args(&args, 1, "manifestXmlJsonml")?;
1358        // JsonML format: [tagName, {attributes}, ...children]
1359        match &args[0] {
1360            JsonnetValue::Array(arr) if !arr.is_empty() => {
1361                if let JsonnetValue::String(tag) = &arr[0] {
1362                    let mut xml = format!("<{}", tag);
1363
1364                    // Attributes (second element if it's an object)
1365                    let mut child_start = 1;
1366                    if arr.len() > 1 {
1367                        if let JsonnetValue::Object(attrs) = &arr[1] {
1368                            for (key, value) in attrs {
1369                                if !key.starts_with('_') {
1370                                    let value_str = match value {
1371                                        JsonnetValue::String(s) => s.clone(),
1372                                        _ => format!("{}", value),
1373                                    };
1374                                    xml.push_str(&format!(" {}=\"{}\"", key, value_str));
1375                                }
1376                            }
1377                            child_start = 2;
1378                        }
1379                    }
1380
1381                    xml.push('>');
1382
1383                    // Children
1384                    for child in &arr[child_start..] {
1385                        match child {
1386                            JsonnetValue::String(s) => xml.push_str(s),
1387                            JsonnetValue::Array(_) => {
1388                                // Recursively process child arrays
1389                                let child_xml = Self::manifest_xml_jsonml(vec![child.clone()])?;
1390                                if let JsonnetValue::String(child_str) = child_xml {
1391                                    xml.push_str(&child_str);
1392                                }
1393                            }
1394                            _ => xml.push_str(&format!("{}", child)),
1395                        }
1396                    }
1397
1398                    xml.push_str(&format!("</{}>", tag));
1399                    Ok(JsonnetValue::string(xml))
1400                } else {
1401                    Err(JsonnetError::runtime_error("JsonML array must start with string tag name"))
1402                }
1403            }
1404            _ => Err(JsonnetError::runtime_error("manifestXmlJsonml expects a JsonML array")),
1405        }
1406    }
1407
1408    // Advanced math functions
1409    fn log2(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1410        Self::check_args(&args, 1, "log2")?;
1411        let x = args[0].as_number()?;
1412        if x <= 0.0 {
1413            return Err(JsonnetError::runtime_error("log2 of non-positive number"));
1414        }
1415        Ok(JsonnetValue::number(x.log2()))
1416    }
1417
1418    fn log10(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1419        Self::check_args(&args, 1, "log10")?;
1420        let x = args[0].as_number()?;
1421        if x <= 0.0 {
1422            return Err(JsonnetError::runtime_error("log10 of non-positive number"));
1423        }
1424        Ok(JsonnetValue::number(x.log10()))
1425    }
1426
1427    fn log1p(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1428        Self::check_args(&args, 1, "log1p")?;
1429        let x = args[0].as_number()?;
1430        if x < -1.0 {
1431            return Err(JsonnetError::runtime_error("log1p of number less than -1"));
1432        }
1433        Ok(JsonnetValue::number((x + 1.0).ln()))
1434    }
1435
1436    fn expm1(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1437        Self::check_args(&args, 1, "expm1")?;
1438        let x = args[0].as_number()?;
1439        Ok(JsonnetValue::number(x.exp() - 1.0))
1440    }
1441
1442    /// Helper function to check argument count
1443    fn check_args(args: &[JsonnetValue], expected: usize, func_name: &str) -> Result<()> {
1444        if args.len() != expected {
1445            return Err(JsonnetError::invalid_function_call(format!(
1446                "{}() expects {} arguments, got {}",
1447                func_name, expected, args.len()
1448            )));
1449        }
1450        Ok(())
1451    }
1452}
1453
1454impl JsonnetValue {
1455    /// Convert from serde_json::Value to JsonnetValue
1456    pub fn from_json_value(value: serde_json::Value) -> Self {
1457        match value {
1458            serde_json::Value::Null => JsonnetValue::Null,
1459            serde_json::Value::Bool(b) => JsonnetValue::boolean(b),
1460            serde_json::Value::Number(n) => JsonnetValue::number(n.as_f64().unwrap_or(0.0)),
1461            serde_json::Value::String(s) => JsonnetValue::string(s),
1462            serde_json::Value::Array(arr) => {
1463                let jsonnet_arr: Vec<JsonnetValue> = arr.into_iter()
1464                    .map(JsonnetValue::from_json_value)
1465                    .collect();
1466                JsonnetValue::array(jsonnet_arr)
1467            }
1468            serde_json::Value::Object(obj) => {
1469                let mut jsonnet_obj = HashMap::new();
1470                for (k, v) in obj {
1471                    jsonnet_obj.insert(k, JsonnetValue::from_json_value(v));
1472                }
1473                JsonnetValue::object(jsonnet_obj)
1474            }
1475        }
1476    }
1477}