1use 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
10pub struct StdLib;
12
13impl StdLib {
14    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            "objectFieldsEx" => Self::object_fields_ex(args),
120            "objectValuesEx" => Self::object_values_ex(args),
121            "prune" => Self::prune(args),
122            "mapWithKey" => Self::map_with_key(args),
123            "manifestIni" => Self::manifest_ini(args),
124            "manifestPython" => Self::manifest_python(args),
125            "manifestCpp" => Self::manifest_cpp(args),
126            "manifestXmlJsonml" => Self::manifest_xml_jsonml(args),
127            "log2" => Self::log2(args),
128            "log10" => Self::log10(args),
129            "log1p" => Self::log1p(args),
130            "expm1" => Self::expm1(args),
131            "remove" => Self::remove(args),
132            "removeAt" => Self::remove_at(args),
133            "flattenArrays" => Self::flatten_arrays(args),
134            "objectKeysValues" => Self::object_keys_values(args),
135            "objectRemoveKey" => Self::object_remove_key(args),
136            "isInteger" => Self::is_integer(args),
137            "isDecimal" => Self::is_decimal(args),
138            "isEven" => Self::is_even(args),
139            "isOdd" => Self::is_odd(args),
140            _ => Err(JsonnetError::runtime_error(format!("Unknown std function: {}", name))),
141        }
142    }
143
144    pub fn length(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
146        Self::check_args(&args, 1, "length")?;
147        match &args[0] {
148            JsonnetValue::Array(arr) => Ok(JsonnetValue::number(arr.len() as f64)),
149            JsonnetValue::String(s) => Ok(JsonnetValue::number(s.len() as f64)),
150            JsonnetValue::Object(obj) => Ok(JsonnetValue::number(obj.len() as f64)),
151            _ => Err(JsonnetError::type_error("length() requires array, string, or object")),
152        }
153    }
154
155    fn type_of(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
157        Self::check_args(&args, 1, "type")?;
158        let type_str = args[0].type_name();
159        Ok(JsonnetValue::string(type_str))
160    }
161
162    fn make_array(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
164        Self::check_args(&args, 2, "makeArray")?;
165        let n = args[0].as_number()? as usize;
166        let _func = &args[1];
167
168        let mut result = Vec::new();
171        for i in 0..n {
172            result.push(JsonnetValue::number(i as f64));
174        }
175
176        Ok(JsonnetValue::array(result))
177    }
178
179    fn filter(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
181        Self::check_args(&args, 2, "filter")?;
182        let _func = &args[0];
183        let _arr = args[1].as_array()?;
184        Ok(args[1].clone())
187    }
188
189    fn map(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
191        Self::check_args(&args, 2, "map")?;
192        let _func = &args[0];
193        let _arr = args[1].as_array()?;
194        Ok(args[1].clone())
197    }
198
199    fn foldl(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
201        Self::check_args(&args, 3, "foldl")?;
202        let _func = &args[0];
203        let _arr = args[1].as_array()?;
204        Ok(args[2].clone())
207    }
208
209    fn foldr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
211        Self::check_args(&args, 3, "foldr")?;
212        let _func = &args[0];
213        let _arr = args[1].as_array()?;
214        Ok(args[2].clone())
217    }
218
219    fn range(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
221        Self::check_args(&args, 1, "range")?;
222        let n = args[0].as_number()? as usize;
223        let arr: Vec<JsonnetValue> = (0..n).map(|i| JsonnetValue::number(i as f64)).collect();
224        Ok(JsonnetValue::array(arr))
225    }
226
227    fn join(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
229        Self::check_args(&args, 2, "join")?;
230        let sep = args[0].as_string()?;
231        let arr = args[1].as_array()?;
232
233        let mut result = String::new();
234        for (i, item) in arr.iter().enumerate() {
235            if i > 0 {
236                result.push_str(sep);
237            }
238            result.push_str(&item.to_string());
239        }
240
241        Ok(JsonnetValue::string(result))
242    }
243
244    fn split(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
246        Self::check_args(&args, 2, "split")?;
247        let s = args[0].as_string()?;
248        let sep = args[1].as_string()?;
249
250        let parts: Vec<JsonnetValue> = s.split(sep).map(JsonnetValue::string).collect();
251        Ok(JsonnetValue::array(parts))
252    }
253
254    fn contains(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
256        Self::check_args(&args, 2, "contains")?;
257        let arr = args[0].as_array()?;
258        let contains = arr.iter().any(|item| item.equals(&args[1]));
259        Ok(JsonnetValue::boolean(contains))
260    }
261
262    fn starts_with(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
264        Self::check_args(&args, 2, "startsWith")?;
265        let s = args[0].as_string()?;
266        let prefix = args[1].as_string()?;
267        Ok(JsonnetValue::boolean(s.starts_with(prefix)))
268    }
269
270    fn ends_with(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
272        Self::check_args(&args, 2, "endsWith")?;
273        let s = args[0].as_string()?;
274        let suffix = args[1].as_string()?;
275        Ok(JsonnetValue::boolean(s.ends_with(suffix)))
276    }
277
278    fn substr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
280        Self::check_args(&args, 3, "substr")?;
281        let s = args[0].as_string()?;
282        let from = args[1].as_number()? as usize;
283        let len = args[2].as_number()? as usize;
284
285        let substr = if from >= s.len() {
286            ""
287        } else {
288            let end = (from + len).min(s.len());
289            &s[from..end]
290        };
291
292        Ok(JsonnetValue::string(substr))
293    }
294
295    fn char_fn(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
297        Self::check_args(&args, 1, "char")?;
298        let n = args[0].as_number()? as u32;
299        match char::from_u32(n) {
300            Some(c) => Ok(JsonnetValue::string(c.to_string())),
301            None => Err(JsonnetError::runtime_error("Invalid codepoint")),
302        }
303    }
304
305    fn codepoint(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
307        Self::check_args(&args, 1, "codepoint")?;
308        let s = args[0].as_string()?;
309        match s.chars().next() {
310            Some(c) => Ok(JsonnetValue::number(c as u32 as f64)),
311            None => Err(JsonnetError::runtime_error("Empty string")),
312        }
313    }
314
315    fn to_string(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
317        Self::check_args(&args, 1, "toString")?;
318        Ok(JsonnetValue::string(args[0].to_string()))
319    }
320
321    fn parse_int(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
323        Self::check_args(&args, 1, "parseInt")?;
324        let s = args[0].as_string()?;
325        match s.parse::<f64>() {
326            Ok(n) => Ok(JsonnetValue::number(n)),
327            Err(_) => Err(JsonnetError::runtime_error("Invalid number format")),
328        }
329    }
330
331    fn parse_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
333        Self::check_args(&args, 1, "parseJson")?;
334        let s = args[0].as_string()?;
335        match serde_json::from_str::<serde_json::Value>(s) {
336            Ok(value) => Ok(JsonnetValue::from_json_value(value)),
337            Err(_) => Err(JsonnetError::runtime_error("Invalid JSON")),
338        }
339    }
340
341    fn encode_utf8(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
343        Self::check_args(&args, 1, "encodeUTF8")?;
344        let s = args[0].as_string()?;
345        let bytes: Vec<JsonnetValue> = s.as_bytes().iter().map(|&b| JsonnetValue::number(b as f64)).collect();
346        Ok(JsonnetValue::array(bytes))
347    }
348
349    fn decode_utf8(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
351        Self::check_args(&args, 1, "decodeUTF8")?;
352        let arr = args[0].as_array()?;
353        let mut bytes = Vec::new();
354        for item in arr {
355            let b = item.as_number()? as u8;
356            bytes.push(b);
357        }
358        match String::from_utf8(bytes) {
359            Ok(s) => Ok(JsonnetValue::string(s)),
360            Err(_) => Err(JsonnetError::runtime_error("Invalid UTF-8 sequence")),
361        }
362    }
363
364    fn md5(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
366        Self::check_args(&args, 1, "md5")?;
367        let s = args[0].as_string()?;
368        use md5::{Md5, Digest};
369        let mut hasher = Md5::new();
370        hasher.update(s.as_bytes());
371        let result = hasher.finalize();
372        Ok(JsonnetValue::string(format!("{:x}", result)))
373    }
374
375    fn base64(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
377        Self::check_args(&args, 1, "base64")?;
378        let s = args[0].as_string()?;
379        use base64::{Engine as _, engine::general_purpose};
380        let encoded = general_purpose::STANDARD.encode(s.as_bytes());
381        Ok(JsonnetValue::string(encoded))
382    }
383
384    fn base64_decode(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
386        Self::check_args(&args, 1, "base64Decode")?;
387        let s = args[0].as_string()?;
388        use base64::{Engine as _, engine::general_purpose};
389        match general_purpose::STANDARD.decode(s.as_bytes()) {
390            Ok(bytes) => match String::from_utf8(bytes) {
391                Ok(decoded) => Ok(JsonnetValue::string(decoded)),
392                Err(_) => Err(JsonnetError::runtime_error("Invalid UTF-8 in decoded data")),
393            },
394            Err(_) => Err(JsonnetError::runtime_error("Invalid base64")),
395        }
396    }
397
398    fn manifest_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
400        Self::check_args(&args, 1, "manifestJson")?;
401        let json = serde_json::to_string_pretty(&args[0].to_json_value())?;
402        Ok(JsonnetValue::string(json))
403    }
404
405    fn manifest_json_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
407        Self::check_args(&args, 2, "manifestJsonEx")?;
408        let value = &args[0];
409        let indent = args[1].as_string()?;
410
411        match serde_json::to_string_pretty(&value.to_json_value()) {
414            Ok(json) => {
415                if indent.is_empty() {
416                    Ok(JsonnetValue::string(json))
417                } else {
418                    let indented = json.lines()
420                        .map(|line| {
421                            let leading_spaces = line.chars().take_while(|c| *c == ' ').count();
422                            if leading_spaces > 0 {
423                                let indent_level = leading_spaces / 2;
424                                format!("{}{}", indent.repeat(indent_level), &line[leading_spaces..])
425                            } else {
426                                line.to_string()
427                            }
428                        })
429                        .collect::<Vec<_>>()
430                        .join("\n");
431                    Ok(JsonnetValue::string(indented))
432                }
433            }
434            Err(_) => Err(JsonnetError::runtime_error("Failed to serialize to JSON")),
435        }
436    }
437
438    #[cfg(feature = "yaml")]
440    fn manifest_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
441        Self::check_args(&args, 1, "manifestYaml")?;
442        let yaml = serde_yaml::to_string(&args[0].to_json_value())?;
443        Ok(JsonnetValue::string(yaml))
444    }
445
446    #[cfg(not(feature = "yaml"))]
448    fn manifest_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
449        Self::check_args(&args, 1, "manifestYaml")?;
450        Self::manifest_json(args)
452    }
453
454    fn escape_string_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
456        Self::check_args(&args, 1, "escapeStringJson")?;
457        let s = args[0].as_string()?;
458        let escaped = serde_json::to_string(s)?;
459        Ok(JsonnetValue::string(escaped))
460    }
461
462    fn escape_string_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
463        Self::check_args(&args, 1, "escapeStringYaml")?;
464        let s = args[0].as_string()?;
465
466        let mut escaped = String::new();
469        for ch in s.chars() {
470            match ch {
471                '"' => escaped.push_str("\\\""),
472                '\\' => escaped.push_str("\\\\"),
473                '\n' => escaped.push_str("\\n"),
474                '\r' => escaped.push_str("\\r"),
475                '\t' => escaped.push_str("\\t"),
476                '\0' => escaped.push_str("\\0"),
477                _ => escaped.push(ch),
478            }
479        }
480
481        let needs_quotes = s.contains(' ') || s.contains('\t') || s.contains('\n') ||
483                          s.contains(':') || s.contains('#') || s.contains('-') ||
484                          s.starts_with('[') || s.starts_with('{') ||
485                          s.starts_with('"') || s.starts_with('\'');
486
487        if needs_quotes {
488            Ok(JsonnetValue::string(format!("\"{}\"", escaped)))
489        } else {
490            Ok(JsonnetValue::string(escaped))
491        }
492    }
493
494    fn escape_string_python(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
495        Self::check_args(&args, 1, "escapeStringPython")?;
496        let s = args[0].as_string()?;
497        let escaped = s.escape_default().to_string();
498        Ok(JsonnetValue::string(format!("'{}'", escaped)))
499    }
500
501    fn escape_string_bash(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
502        Self::check_args(&args, 1, "escapeStringBash")?;
503        let s = args[0].as_string()?;
504        let escaped = s.replace("'", "'\"'\"'").replace("\\", "\\\\");
505        Ok(JsonnetValue::string(format!("'{}'", escaped)))
506    }
507
508    fn escape_string_dollars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
509        Self::check_args(&args, 1, "escapeStringDollars")?;
510        let s = args[0].as_string()?;
511        let escaped = s.replace("$$", "$").replace("$", "$$");
512        Ok(JsonnetValue::string(escaped))
513    }
514
515    fn string_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
517        Self::check_args(&args, 1, "stringChars")?;
518        let s = args[0].as_string()?;
519        let chars: Vec<JsonnetValue> = s.chars().map(|c| JsonnetValue::string(c.to_string())).collect();
520        Ok(JsonnetValue::array(chars))
521    }
522
523    fn string_bytes(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
524        Self::check_args(&args, 1, "stringBytes")?;
525        let s = args[0].as_string()?;
526        let bytes: Vec<JsonnetValue> = s.as_bytes().iter().map(|&b| JsonnetValue::number(b as f64)).collect();
527        Ok(JsonnetValue::array(bytes))
528    }
529
530    fn format(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
531        Self::check_args(&args, 2, "format")?;
532        let format_str = args[0].as_string()?;
533        let values = args[1].as_array()?;
534
535        let mut result = format_str.to_string();
537        for (i, value) in values.iter().enumerate() {
538            let placeholder = format!("%{}", i + 1);
539            let value_str = match value {
540                JsonnetValue::String(s) => s.clone(),
541                JsonnetValue::Number(n) => n.to_string(),
542                JsonnetValue::Boolean(b) => b.to_string(),
543                _ => value.to_string(),
544            };
545            result = result.replace(&placeholder, &value_str);
546        }
547
548        Ok(JsonnetValue::string(result))
549    }
550
551    fn is_array(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
553        Self::check_args(&args, 1, "isArray")?;
554        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Array(_))))
555    }
556
557    fn is_boolean(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
558        Self::check_args(&args, 1, "isBoolean")?;
559        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Boolean(_))))
560    }
561
562    fn is_function(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
563        Self::check_args(&args, 1, "isFunction")?;
564        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Function(_))))
565    }
566
567    fn is_number(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
568        Self::check_args(&args, 1, "isNumber")?;
569        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Number(_))))
570    }
571
572    fn is_object(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
573        Self::check_args(&args, 1, "isObject")?;
574        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Object(_))))
575    }
576
577    fn is_string(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
578        Self::check_args(&args, 1, "isString")?;
579        Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::String(_))))
580    }
581
582    fn count(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
584        Self::check_args(&args, 2, "count")?;
585        let arr = args[0].as_array()?;
586        let elem = &args[1];
587        let count = arr.iter().filter(|item| item.equals(elem)).count() as f64;
588        Ok(JsonnetValue::number(count))
589    }
590
591    fn find(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
592        Self::check_args(&args, 2, "find")?;
593        match (&args[0], &args[1]) {
594            (JsonnetValue::Array(arr), value) => {
595                let mut indices = Vec::new();
596                for (i, item) in arr.iter().enumerate() {
597                    if item == value {
598                        indices.push(JsonnetValue::Number(i as f64));
599                    }
600                }
601                Ok(JsonnetValue::array(indices))
602            }
603            _ => Err(JsonnetError::runtime_error("find expects array and search value")),
604        }
605    }
606
607    fn member(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
608        Self::contains(args)
609    }
610
611    fn modulo(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
613        Self::check_args(&args, 2, "modulo")?;
614        let a = args[0].as_number()?;
615        let b = args[1].as_number()?;
616        if b == 0.0 {
617            return Err(JsonnetError::DivisionByZero);
618        }
619        Ok(JsonnetValue::number(a % b))
620    }
621
622    fn pow(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
623        Self::check_args(&args, 2, "pow")?;
624        let a = args[0].as_number()?;
625        let b = args[1].as_number()?;
626        Ok(JsonnetValue::number(a.powf(b)))
627    }
628
629    fn exp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
630        Self::check_args(&args, 1, "exp")?;
631        let x = args[0].as_number()?;
632        Ok(JsonnetValue::number(x.exp()))
633    }
634
635    fn log(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
636        Self::check_args(&args, 1, "log")?;
637        let x = args[0].as_number()?;
638        if x <= 0.0 {
639            return Err(JsonnetError::runtime_error("log of non-positive number"));
640        }
641        Ok(JsonnetValue::number(x.ln()))
642    }
643
644    fn sqrt(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
645        Self::check_args(&args, 1, "sqrt")?;
646        let x = args[0].as_number()?;
647        if x < 0.0 {
648            return Err(JsonnetError::runtime_error("sqrt of negative number"));
649        }
650        Ok(JsonnetValue::number(x.sqrt()))
651    }
652
653    fn sin(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
654        Self::check_args(&args, 1, "sin")?;
655        let x = args[0].as_number()?;
656        Ok(JsonnetValue::number(x.sin()))
657    }
658
659    fn cos(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
660        Self::check_args(&args, 1, "cos")?;
661        let x = args[0].as_number()?;
662        Ok(JsonnetValue::number(x.cos()))
663    }
664
665    fn tan(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
666        Self::check_args(&args, 1, "tan")?;
667        let x = args[0].as_number()?;
668        Ok(JsonnetValue::number(x.tan()))
669    }
670
671    fn asin(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
672        Self::check_args(&args, 1, "asin")?;
673        let x = args[0].as_number()?;
674        Ok(JsonnetValue::number(x.asin()))
675    }
676
677    fn acos(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
678        Self::check_args(&args, 1, "acos")?;
679        let x = args[0].as_number()?;
680        Ok(JsonnetValue::number(x.acos()))
681    }
682
683    fn atan(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
684        Self::check_args(&args, 1, "atan")?;
685        let x = args[0].as_number()?;
686        Ok(JsonnetValue::number(x.atan()))
687    }
688
689    fn floor(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
690        Self::check_args(&args, 1, "floor")?;
691        let x = args[0].as_number()?;
692        Ok(JsonnetValue::number(x.floor()))
693    }
694
695    fn ceil(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
696        Self::check_args(&args, 1, "ceil")?;
697        let x = args[0].as_number()?;
698        Ok(JsonnetValue::number(x.ceil()))
699    }
700
701    fn round(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
702        Self::check_args(&args, 1, "round")?;
703        let x = args[0].as_number()?;
704        Ok(JsonnetValue::number(x.round()))
705    }
706
707    fn abs(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
708        Self::check_args(&args, 1, "abs")?;
709        let x = args[0].as_number()?;
710        Ok(JsonnetValue::number(x.abs()))
711    }
712
713    fn max(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
714        Self::check_args(&args, 1, "max")?;
715        let arr = args[0].as_array()?;
716        if arr.is_empty() {
717            return Err(JsonnetError::runtime_error("max() called on empty array"));
718        }
719        let mut max_val = f64::NEG_INFINITY;
720        for item in arr {
721            let val = item.as_number()?;
722            if val > max_val {
723                max_val = val;
724            }
725        }
726        Ok(JsonnetValue::number(max_val))
727    }
728
729    fn min(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
730        Self::check_args(&args, 1, "min")?;
731        let arr = args[0].as_array()?;
732        if arr.is_empty() {
733            return Err(JsonnetError::runtime_error("min() called on empty array"));
734        }
735        let mut min_val = f64::INFINITY;
736        for item in arr {
737            let val = item.as_number()?;
738            if val < min_val {
739                min_val = val;
740            }
741        }
742        Ok(JsonnetValue::number(min_val))
743    }
744
745    fn clamp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
746        Self::check_args(&args, 3, "clamp")?;
747        let x = args[0].as_number()?;
748        let min = args[1].as_number()?;
749        let max = args[2].as_number()?;
750        let clamped = x.max(min).min(max);
751        Ok(JsonnetValue::number(clamped))
752    }
753
754    fn assert_equal(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
755        Self::check_args(&args, 2, "assertEqual")?;
756        if !args[0].equals(&args[1]) {
757            return Err(JsonnetError::assertion_failed(format!(
758                "Assertion failed: {} != {}\n  Left: {:?}\n  Right: {:?}",
759                args[0], args[1], args[0], args[1]
760            )));
761        }
762        Ok(JsonnetValue::boolean(true))
763    }
764
765    fn trace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
766        Self::check_args(&args, 2, "trace")?;
767        eprintln!("TRACE: {:?}", args[1]);
769        Ok(args[0].clone())
771    }
772
773    fn sort(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
775        Self::check_args(&args, 1, "sort")?;
776        let arr = args[0].as_array()?;
777
778        if arr.is_empty() {
779            return Ok(JsonnetValue::array(vec![]));
780        }
781
782        let mut sorted = arr.clone();
785        sorted.sort_by(|a, b| Self::compare_values(a, b));
786
787        Ok(JsonnetValue::array(sorted))
788    }
789
790    fn compare_values(a: &JsonnetValue, b: &JsonnetValue) -> std::cmp::Ordering {
791        match (a, b) {
792            (JsonnetValue::Null, JsonnetValue::Null) => std::cmp::Ordering::Equal,
793            (JsonnetValue::Null, _) => std::cmp::Ordering::Less,
794            (_, JsonnetValue::Null) => std::cmp::Ordering::Greater,
795            (JsonnetValue::Boolean(x), JsonnetValue::Boolean(y)) => x.cmp(y),
796            (JsonnetValue::Boolean(_), _) => std::cmp::Ordering::Less,
797            (_, JsonnetValue::Boolean(_)) => std::cmp::Ordering::Greater,
798            (JsonnetValue::Number(x), JsonnetValue::Number(y)) => {
799                x.partial_cmp(y).unwrap_or(std::cmp::Ordering::Equal)
800            }
801            (JsonnetValue::Number(_), _) => std::cmp::Ordering::Less,
802            (_, JsonnetValue::Number(_)) => std::cmp::Ordering::Greater,
803            (JsonnetValue::String(x), JsonnetValue::String(y)) => x.cmp(y),
804            (JsonnetValue::String(_), _) => std::cmp::Ordering::Less,
805            (_, JsonnetValue::String(_)) => std::cmp::Ordering::Greater,
806            (JsonnetValue::Array(x), JsonnetValue::Array(y)) => {
807                for (_i, (a_item, b_item)) in x.iter().zip(y.iter()).enumerate() {
808                    let cmp = Self::compare_values(a_item, b_item);
809                    if cmp != std::cmp::Ordering::Equal {
810                        return cmp;
811                    }
812                }
813                x.len().cmp(&y.len())
814            }
815            (JsonnetValue::Array(_), _) => std::cmp::Ordering::Less,
816            (_, JsonnetValue::Array(_)) => std::cmp::Ordering::Greater,
817            (JsonnetValue::Object(x), JsonnetValue::Object(y)) => {
818                let mut x_keys: Vec<_> = x.keys().collect();
820                let mut y_keys: Vec<_> = y.keys().collect();
821                x_keys.sort();
822                y_keys.sort();
823
824                for (x_key, y_key) in x_keys.iter().zip(y_keys.iter()) {
825                    let key_cmp = x_key.cmp(y_key);
826                    if key_cmp != std::cmp::Ordering::Equal {
827                        return key_cmp;
828                    }
829                    if let (Some(x_val), Some(y_val)) = (x.get(*x_key), y.get(*y_key)) {
830                        let val_cmp = Self::compare_values(x_val, y_val);
831                        if val_cmp != std::cmp::Ordering::Equal {
832                            return val_cmp;
833                        }
834                    }
835                }
836                x.len().cmp(&y.len())
837            }
838            _ => std::cmp::Ordering::Equal, }
840    }
841
842    fn uniq(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
843        Self::check_args(&args, 1, "uniq")?;
844        let arr = args[0].as_array()?;
845
846        let mut result: Vec<JsonnetValue> = Vec::new();
847        for item in arr {
848            let mut found = false;
850            for existing in &result {
851                if existing.equals(item) {
852                    found = true;
853                    break;
854                }
855            }
856            if !found {
857                result.push(item.clone());
858            }
859        }
860
861        Ok(JsonnetValue::array(result))
862    }
863
864    fn reverse(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
865        Self::check_args(&args, 1, "reverse")?;
866        let arr = args[0].as_array()?;
867        let reversed: Vec<JsonnetValue> = arr.iter().rev().cloned().collect();
868        Ok(JsonnetValue::array(reversed))
869    }
870
871    fn merge_patch(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
873        Self::check_args(&args, 2, "mergePatch")?;
874        let target = args[0].as_object()?;
875        let patch = args[1].as_object()?;
876
877        let mut result = target.clone();
878
879        for (key, patch_value) in patch {
880            match patch_value {
881                JsonnetValue::Null => {
882                    result.remove(key);
884                }
885                JsonnetValue::Object(patch_obj) => {
886                    if let Some(JsonnetValue::Object(target_obj)) = result.get(key) {
888                        let merged = Self::merge_patch(vec![
889                            JsonnetValue::object(target_obj.clone()),
890                            JsonnetValue::object(patch_obj.clone())
891                        ])?;
892                        if let JsonnetValue::Object(merged_obj) = merged {
893                            result.insert(key.clone(), JsonnetValue::object(merged_obj));
894                        }
895                    } else {
896                        result.insert(key.clone(), JsonnetValue::object(patch_obj.clone()));
898                    }
899                }
900                _ => {
901                    result.insert(key.clone(), patch_value.clone());
903                }
904            }
905        }
906
907        Ok(JsonnetValue::object(result))
908    }
909
910    fn get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
911        Self::check_args(&args, 3, "get")?;
912        let obj = args[0].as_object()?;
913        let key = args[1].as_string()?;
914        let default = &args[2];
915        Ok(obj.get(key).unwrap_or(default).clone())
916    }
917
918    fn object_fields(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
919        Self::check_args(&args, 1, "objectFields")?;
920        let obj = args[0].as_object()?;
921        let fields: Vec<JsonnetValue> = obj.keys()
922            .filter(|&k| !k.starts_with('_')) .map(|k| JsonnetValue::string(k.clone()))
924            .collect();
925        Ok(JsonnetValue::array(fields))
926    }
927
928    fn object_fields_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
929        Self::check_args(&args, 1, "objectFieldsAll")?;
930        let obj = args[0].as_object()?;
931        let fields: Vec<JsonnetValue> = obj.keys()
932            .map(|k| JsonnetValue::string(k.clone()))
933            .collect();
934        Ok(JsonnetValue::array(fields))
935    }
936
937    fn object_has(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
938        Self::check_args(&args, 2, "objectHas")?;
939        let obj = args[0].as_object()?;
940        let key = args[1].as_string()?;
941        Ok(JsonnetValue::boolean(obj.contains_key(key) && !key.starts_with('_')))
942    }
943
944    fn object_has_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
945        Self::check_args(&args, 2, "objectHasAll")?;
946        let obj = args[0].as_object()?;
947        let key = args[1].as_string()?;
948        Ok(JsonnetValue::boolean(obj.contains_key(key)))
949    }
950
951    fn object_values(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
952        Self::check_args(&args, 1, "objectValues")?;
953        let obj = args[0].as_object()?;
954        let values: Vec<JsonnetValue> = obj.iter()
955            .filter(|(k, _)| !k.starts_with('_'))
956            .map(|(_, v)| v.clone())
957            .collect();
958        Ok(JsonnetValue::array(values))
959    }
960
961    fn object_values_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
962        Self::check_args(&args, 1, "objectValuesAll")?;
963        let obj = args[0].as_object()?;
964        let values: Vec<JsonnetValue> = obj.values().cloned().collect();
965        Ok(JsonnetValue::array(values))
966    }
967
968    fn prune(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
969        Self::check_args(&args, 1, "prune")?;
970        Self::prune_value(&args[0])
971    }
972
973    fn prune_value(value: &JsonnetValue) -> Result<JsonnetValue> {
974        match value {
975            JsonnetValue::Null => Ok(JsonnetValue::Null),
976            JsonnetValue::Array(arr) => {
977                let pruned: Vec<JsonnetValue> = arr.iter()
978                    .map(|item| Self::prune_value(item))
979                    .collect::<Result<Vec<_>>>()?
980                    .into_iter()
981                    .filter(|item| !matches!(item, JsonnetValue::Null))
982                    .collect();
983                Ok(JsonnetValue::array(pruned))
984            }
985            JsonnetValue::Object(obj) => {
986                let mut pruned_obj = HashMap::new();
987                for (key, val) in obj {
988                    let pruned_val = Self::prune_value(val)?;
989                    if !matches!(pruned_val, JsonnetValue::Null) {
990                        pruned_obj.insert(key.clone(), pruned_val);
991                    }
992                }
993                Ok(JsonnetValue::object(pruned_obj))
994            }
995            _ => Ok(value.clone()),
996        }
997    }
998
999    fn map_with_key(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1000        Self::check_args(&args, 2, "mapWithKey")?;
1001        let _func = &args[0];
1002        let obj = args[1].as_object()?;
1003
1004        let mut result = HashMap::new();
1007        for (key, value) in obj {
1008            if !key.starts_with('_') {
1009                result.insert(key.clone(), JsonnetValue::array(vec![
1012                    JsonnetValue::string(key.clone()),
1013                    value.clone()
1014                ]));
1015            }
1016        }
1017
1018        Ok(JsonnetValue::object(result))
1019    }
1020
1021    fn object_fields_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1022        Self::check_args(&args, 2, "objectFieldsEx")?;
1023        let obj = args[0].as_object()?;
1024        let include_hidden = args[1].as_boolean()?;
1025
1026        let fields: Vec<JsonnetValue> = obj.keys()
1027            .filter(|&k| include_hidden || !k.starts_with('_'))
1028            .map(|k| JsonnetValue::string(k.clone()))
1029            .collect();
1030
1031        Ok(JsonnetValue::array(fields))
1032    }
1033
1034    fn object_values_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1035        Self::check_args(&args, 2, "objectValuesEx")?;
1036        let obj = args[0].as_object()?;
1037        let include_hidden = args[1].as_boolean()?;
1038
1039        let values: Vec<JsonnetValue> = obj.iter()
1040            .filter(|(k, _)| include_hidden || !k.starts_with('_'))
1041            .map(|(_, v)| v.clone())
1042            .collect();
1043
1044        Ok(JsonnetValue::array(values))
1045    }
1046
1047    fn to_lower(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1048        Self::check_args(&args, 1, "toLower")?;
1049        match &args[0] {
1050            JsonnetValue::String(s) => Ok(JsonnetValue::string(s.to_lowercase())),
1051            _ => Err(JsonnetError::runtime_error("toLower expects a string argument")),
1052        }
1053    }
1054
1055    fn to_upper(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1056        Self::check_args(&args, 1, "toUpper")?;
1057        match &args[0] {
1058            JsonnetValue::String(s) => Ok(JsonnetValue::string(s.to_uppercase())),
1059            _ => Err(JsonnetError::runtime_error("toUpper expects a string argument")),
1060        }
1061    }
1062
1063    fn trim(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1064        Self::check_args(&args, 1, "trim")?;
1065        match &args[0] {
1066            JsonnetValue::String(s) => Ok(JsonnetValue::string(s.trim().to_string())),
1067            _ => Err(JsonnetError::runtime_error("trim expects a string argument")),
1068        }
1069    }
1070
1071    fn all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1072        Self::check_args(&args, 1, "all")?;
1073        match &args[0] {
1074            JsonnetValue::Array(arr) => {
1075                let result = arr.iter().all(|item| item.is_truthy());
1076                Ok(JsonnetValue::boolean(result))
1077            }
1078            _ => Err(JsonnetError::runtime_error("all expects an array argument")),
1079        }
1080    }
1081
1082    fn any(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1083        Self::check_args(&args, 1, "any")?;
1084        match &args[0] {
1085            JsonnetValue::Array(arr) => {
1086                let result = arr.iter().any(|item| item.is_truthy());
1087                Ok(JsonnetValue::boolean(result))
1088            }
1089            _ => Err(JsonnetError::runtime_error("any expects an array argument")),
1090        }
1091    }
1092
1093    fn id(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1094        Self::check_args(&args, 1, "id")?;
1095        Ok(args[0].clone())
1096    }
1097
1098    fn equals(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1099        Self::check_args(&args, 2, "equals")?;
1100        let a = &args[0];
1101        let b = &args[1];
1102
1103        if a == b {
1105            return Ok(JsonnetValue::boolean(true));
1106        }
1107
1108        let ta = a.type_name();
1110        let tb = b.type_name();
1111        if ta != tb {
1112            return Ok(JsonnetValue::boolean(false));
1113        }
1114
1115        match (a, b) {
1116            (JsonnetValue::Array(arr_a), JsonnetValue::Array(arr_b)) => {
1117                if arr_a.len() != arr_b.len() {
1118                    return Ok(JsonnetValue::boolean(false));
1119                }
1120                for (i, item_a) in arr_a.iter().enumerate() {
1121                    let eq_args = vec![item_a.clone(), arr_b[i].clone()];
1122                    if let Ok(JsonnetValue::Boolean(false)) = Self::equals(eq_args) {
1123                        return Ok(JsonnetValue::boolean(false));
1124                    }
1125                }
1126                Ok(JsonnetValue::boolean(true))
1127            }
1128            (JsonnetValue::Object(obj_a), JsonnetValue::Object(obj_b)) => {
1129                let fields_a: Vec<String> = obj_a.keys().cloned().collect();
1131                let fields_b: Vec<String> = obj_b.keys().cloned().collect();
1132
1133                if fields_a.len() != fields_b.len() {
1134                    return Ok(JsonnetValue::boolean(false));
1135                }
1136
1137                let mut sorted_a = fields_a.clone();
1139                sorted_a.sort();
1140                let mut sorted_b = fields_b.clone();
1141                sorted_b.sort();
1142
1143                if sorted_a != sorted_b {
1144                    return Ok(JsonnetValue::boolean(false));
1145                }
1146
1147                for field in sorted_a {
1149                    let val_a = &obj_a[&field];
1150                    let val_b = &obj_b[&field];
1151                    let eq_args = vec![val_a.clone(), val_b.clone()];
1152                    if let Ok(JsonnetValue::Boolean(false)) = Self::equals(eq_args) {
1153                        return Ok(JsonnetValue::boolean(false));
1154                    }
1155                }
1156                Ok(JsonnetValue::boolean(true))
1157            }
1158            _ => Ok(JsonnetValue::boolean(false)),
1159        }
1160    }
1161
1162    fn lines(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1163        Self::check_args(&args, 1, "lines")?;
1164        match &args[0] {
1165            JsonnetValue::Array(arr) => {
1166                let mut lines = Vec::new();
1167                for item in arr {
1168                    match item {
1170                        JsonnetValue::String(s) => lines.push(s.clone()),
1171                        JsonnetValue::Number(n) => lines.push(n.to_string()),
1172                        JsonnetValue::Boolean(b) => lines.push(b.to_string()),
1173                        _ => lines.push(format!("{}", item)),
1174                    }
1175                }
1176                lines.push("".to_string()); Ok(JsonnetValue::string(lines.join("\n")))
1178            }
1179            _ => Err(JsonnetError::runtime_error("lines expects an array argument")),
1180        }
1181    }
1182
1183    fn str_replace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1184        Self::check_args(&args, 3, "strReplace")?;
1185
1186        let str_val = &args[0];
1187        let from_val = &args[1];
1188        let to_val = &args[2];
1189
1190        let str = str_val.as_string()?.to_string();
1191        let from = from_val.as_string()?.to_string();
1192        let to = to_val.as_string()?.to_string();
1193
1194        if from.is_empty() {
1195            return Err(JsonnetError::runtime_error("'from' string must not be zero length"));
1196        }
1197
1198        let result = str.replace(&from, &to);
1202        Ok(JsonnetValue::string(result))
1203    }
1204
1205    fn sha1(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1206        Self::check_args(&args, 1, "sha1")?;
1207        let input = args[0].as_string()?.as_bytes();
1208        let mut hasher = Sha1::new();
1209        hasher.update(input);
1210        let result = hasher.finalize();
1211        Ok(JsonnetValue::string(hex::encode(result)))
1212    }
1213
1214    fn sha256(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1215        Self::check_args(&args, 1, "sha256")?;
1216        let input = args[0].as_string()?.as_bytes();
1217        let mut hasher = Sha256::new();
1218        hasher.update(input);
1219        let result = hasher.finalize();
1220        Ok(JsonnetValue::string(hex::encode(result)))
1221    }
1222
1223    fn sha3(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1224        Self::check_args(&args, 1, "sha3")?;
1225        let input = args[0].as_string()?.as_bytes();
1226        let mut hasher = Sha3_256::new();
1227        hasher.update(input);
1228        let result = hasher.finalize();
1229        Ok(JsonnetValue::string(hex::encode(result)))
1230    }
1231
1232    fn sha512(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1233        Self::check_args(&args, 1, "sha512")?;
1234        let input = args[0].as_string()?.as_bytes();
1235        let mut hasher = Sha512::new();
1236        hasher.update(input);
1237        let result = hasher.finalize();
1238        Ok(JsonnetValue::string(hex::encode(result)))
1239    }
1240
1241    fn ascii_lower(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1242        Self::check_args(&args, 1, "asciiLower")?;
1243        let input = args[0].as_string()?;
1244        Ok(JsonnetValue::string(input.to_ascii_lowercase()))
1245    }
1246
1247    fn ascii_upper(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1248        Self::check_args(&args, 1, "asciiUpper")?;
1249        let input = args[0].as_string()?;
1250        Ok(JsonnetValue::string(input.to_ascii_uppercase()))
1251    }
1252
1253    fn flat_map(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1254        Self::check_args(&args, 2, "flatMap")?;
1255        let func = &args[0];
1256        let arr = &args[1];
1257
1258        match arr {
1259            JsonnetValue::Array(array) => {
1260                let mut result = Vec::new();
1261                for item in array {
1262                    if let JsonnetValue::Array(sub_array) = item {
1266                        result.extend(sub_array.clone());
1267                    } else {
1268                        result.push(item.clone());
1269                    }
1270                }
1271                Ok(JsonnetValue::array(result))
1272            }
1273            JsonnetValue::String(s) => {
1274                let mut result = Vec::new();
1276                for ch in s.chars() {
1277                    result.push(JsonnetValue::string(ch.to_string()));
1279                }
1280                Ok(JsonnetValue::array(result))
1281            }
1282            _ => Err(JsonnetError::runtime_error("flatMap expects array or string as second argument")),
1283        }
1284    }
1285
1286    fn map_with_index(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1287        Self::check_args(&args, 2, "mapWithIndex")?;
1288        let func = &args[0];
1289        let arr = &args[1];
1290
1291        match arr {
1292            JsonnetValue::Array(array) => {
1293                let mut result = Vec::new();
1294                for (i, item) in array.iter().enumerate() {
1295                    result.push(JsonnetValue::array(vec![JsonnetValue::number(i as f64), item.clone()]));
1298                }
1299                Ok(JsonnetValue::array(result))
1300            }
1301            JsonnetValue::String(s) => {
1302                let mut result = Vec::new();
1303                for (i, ch) in s.chars().enumerate() {
1304                    result.push(JsonnetValue::array(vec![
1305                        JsonnetValue::number(i as f64),
1306                        JsonnetValue::string(ch.to_string())
1307                    ]));
1308                }
1309                Ok(JsonnetValue::array(result))
1310            }
1311            _ => Err(JsonnetError::runtime_error("mapWithIndex expects array or string as second argument")),
1312        }
1313    }
1314
1315    fn lstrip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1316        Self::check_args(&args, 2, "lstripChars")?;
1317        let str_val = args[0].as_string()?;
1318        let chars_val = args[1].as_string()?;
1319
1320        let chars_set: std::collections::HashSet<char> = chars_val.chars().collect();
1321        let result: String = str_val.chars()
1322            .skip_while(|c| chars_set.contains(c))
1323            .collect();
1324
1325        Ok(JsonnetValue::string(result))
1326    }
1327
1328    fn rstrip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1329        Self::check_args(&args, 2, "rstripChars")?;
1330        let str_val = args[0].as_string()?;
1331        let chars_val = args[1].as_string()?;
1332
1333        let chars_set: std::collections::HashSet<char> = chars_val.chars().collect();
1334        let result: String = str_val.chars()
1335            .rev()
1336            .skip_while(|c| chars_set.contains(c))
1337            .collect::<Vec<char>>()
1338            .into_iter()
1339            .rev()
1340            .collect();
1341
1342        Ok(JsonnetValue::string(result))
1343    }
1344
1345    fn strip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1346        Self::check_args(&args, 2, "stripChars")?;
1347        let str_val = &args[0];
1348        let chars_val = &args[1];
1349
1350        let lstripped_args = vec![str_val.clone(), chars_val.clone()];
1352        let lstripped = Self::lstrip_chars(lstripped_args)?;
1353        let rstripped_args = vec![lstripped, chars_val.clone()];
1354        Self::rstrip_chars(rstripped_args)
1355    }
1356
1357    fn find_substr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1358        Self::check_args(&args, 2, "findSubstr")?;
1359        let pat = args[0].as_string()?;
1360        let str = args[1].as_string()?;
1361
1362        if pat.is_empty() {
1363            return Err(JsonnetError::runtime_error("findSubstr pattern cannot be empty"));
1364        }
1365
1366        let mut result = Vec::new();
1367        let mut start = 0;
1368
1369        while let Some(pos) = str[start..].find(&pat) {
1370            result.push(JsonnetValue::number((start + pos) as f64));
1371            start += pos + pat.len();
1372        }
1373
1374        Ok(JsonnetValue::array(result))
1375    }
1376
1377    fn repeat(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1378        Self::check_args(&args, 2, "repeat")?;
1379        let what = &args[0];
1380        let count_val = &args[1];
1381
1382        let count = if let JsonnetValue::Number(n) = count_val {
1383            *n as usize
1384        } else {
1385            return Err(JsonnetError::runtime_error("repeat count must be a number"));
1386        };
1387
1388        match what {
1389            JsonnetValue::String(s) => {
1390                let repeated = s.repeat(count);
1391                Ok(JsonnetValue::string(repeated))
1392            }
1393            JsonnetValue::Array(arr) => {
1394                let mut result = Vec::new();
1395                for _ in 0..count {
1396                    result.extend(arr.clone());
1397                }
1398                Ok(JsonnetValue::array(result))
1399            }
1400            _ => Err(JsonnetError::runtime_error("repeat first argument must be string or array")),
1401        }
1402    }
1403
1404    fn set(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1405        Self::check_args(&args, 1, "set")?;
1406        match &args[0] {
1407            JsonnetValue::Array(arr) => {
1408                let mut result = Vec::new();
1410
1411                for item in arr {
1412                    let mut found = false;
1414                    for existing in &result {
1415                        if existing == item {
1416                            found = true;
1417                            break;
1418                        }
1419                    }
1420                    if !found {
1421                        result.push(item.clone());
1422                    }
1423                }
1424
1425                Ok(JsonnetValue::array(result))
1426            }
1427            _ => Err(JsonnetError::runtime_error("set expects an array argument")),
1428        }
1429    }
1430
1431    fn set_member(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1432        Self::check_args(&args, 2, "setMember")?;
1433        let value = &args[0];
1434        let arr = match &args[1] {
1435            JsonnetValue::Array(a) => a,
1436            _ => return Err(JsonnetError::runtime_error("setMember expects array as second argument")),
1437        };
1438
1439        for item in arr {
1440            if item == value {
1441                return Ok(JsonnetValue::boolean(true));
1442            }
1443        }
1444        Ok(JsonnetValue::boolean(false))
1445    }
1446
1447    fn set_union(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1448        Self::check_args(&args, 2, "setUnion")?;
1449        let arr_a = match &args[0] {
1450            JsonnetValue::Array(a) => a,
1451            _ => return Err(JsonnetError::runtime_error("setUnion expects arrays as arguments")),
1452        };
1453        let arr_b = match &args[1] {
1454            JsonnetValue::Array(a) => a,
1455            _ => return Err(JsonnetError::runtime_error("setUnion expects arrays as arguments")),
1456        };
1457
1458        let mut result = Vec::new();
1459
1460        for item in arr_a {
1462            let mut found = false;
1463            for existing in &result {
1464                if existing == item {
1465                    found = true;
1466                    break;
1467                }
1468            }
1469            if !found {
1470                result.push(item.clone());
1471            }
1472        }
1473
1474        for item in arr_b {
1476            let mut found = false;
1477            for existing in &result {
1478                if existing == item {
1479                    found = true;
1480                    break;
1481                }
1482            }
1483            if !found {
1484                result.push(item.clone());
1485            }
1486        }
1487
1488        Ok(JsonnetValue::array(result))
1489    }
1490
1491    fn set_inter(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1492        Self::check_args(&args, 2, "setInter")?;
1493        let arr_a = match &args[0] {
1494            JsonnetValue::Array(a) => a,
1495            _ => return Err(JsonnetError::runtime_error("setInter expects arrays as arguments")),
1496        };
1497        let arr_b = match &args[1] {
1498            JsonnetValue::Array(a) => a,
1499            _ => return Err(JsonnetError::runtime_error("setInter expects arrays as arguments")),
1500        };
1501
1502        let mut result = Vec::new();
1503
1504        for item_a in arr_a {
1505            let mut found_in_b = false;
1507            for item_b in arr_b {
1508                if item_a == item_b {
1509                    found_in_b = true;
1510                    break;
1511                }
1512            }
1513
1514            if found_in_b {
1515                let mut already_in_result = false;
1517                for existing in &result {
1518                    if existing == item_a {
1519                        already_in_result = true;
1520                        break;
1521                    }
1522                }
1523                if !already_in_result {
1524                    result.push(item_a.clone());
1525                }
1526            }
1527        }
1528
1529        Ok(JsonnetValue::array(result))
1530    }
1531
1532    fn set_diff(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1533        Self::check_args(&args, 2, "setDiff")?;
1534        let arr_a = match &args[0] {
1535            JsonnetValue::Array(a) => a,
1536            _ => return Err(JsonnetError::runtime_error("setDiff expects arrays as arguments")),
1537        };
1538        let arr_b = match &args[1] {
1539            JsonnetValue::Array(a) => a,
1540            _ => return Err(JsonnetError::runtime_error("setDiff expects arrays as arguments")),
1541        };
1542
1543        let mut result = Vec::new();
1544
1545        for item_a in arr_a {
1546            let mut found_in_b = false;
1548            for item_b in arr_b {
1549                if item_a == item_b {
1550                    found_in_b = true;
1551                    break;
1552                }
1553            }
1554
1555            if !found_in_b {
1556                let mut already_in_result = false;
1558                for existing in &result {
1559                    if existing == item_a {
1560                        already_in_result = true;
1561                        break;
1562                    }
1563                }
1564                if !already_in_result {
1565                    result.push(item_a.clone());
1566                }
1567            }
1568        }
1569
1570        Ok(JsonnetValue::array(result))
1571    }
1572
1573    fn manifest_ini(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1577        Self::check_args(&args, 1, "manifestIni")?;
1578        match &args[0] {
1580            JsonnetValue::Object(obj) => {
1581                let mut result = String::new();
1582                for (key, value) in obj {
1583                    if !key.starts_with('_') {
1584                        result.push_str(&format!("[{}]\n", key));
1585                        if let JsonnetValue::Object(section) = value {
1586                            for (k, v) in section {
1587                                if !k.starts_with('_') {
1588                                    result.push_str(&format!("{}={}\n", k, v));
1589                                }
1590                            }
1591                        }
1592                        result.push('\n');
1593                    }
1594                }
1595                Ok(JsonnetValue::string(result.trim().to_string()))
1596            }
1597            _ => Err(JsonnetError::runtime_error("manifestIni expects an object")),
1598        }
1599    }
1600
1601    fn manifest_python(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1602        Self::check_args(&args, 1, "manifestPython")?;
1603        let json_str = serde_json::to_string(&args[0].to_json_value())?;
1605        let python_str = json_str
1607            .replace("null", "None")
1608            .replace("true", "True")
1609            .replace("false", "False");
1610        Ok(JsonnetValue::string(python_str))
1611    }
1612
1613    fn manifest_cpp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1614        Self::check_args(&args, 1, "manifestCpp")?;
1615        let json_str = serde_json::to_string(&args[0].to_json_value())?;
1617        let cpp_str = format!("// Generated C++ code\nconst char* jsonData = R\"json(\n{}\n)json\";", json_str);
1618        Ok(JsonnetValue::string(cpp_str))
1619    }
1620
1621    fn manifest_xml_jsonml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1622        Self::check_args(&args, 1, "manifestXmlJsonml")?;
1623        match &args[0] {
1625            JsonnetValue::Array(arr) if !arr.is_empty() => {
1626                if let JsonnetValue::String(tag) = &arr[0] {
1627                    let mut xml = format!("<{}", tag);
1628
1629                    let mut child_start = 1;
1631                    if arr.len() > 1 {
1632                        if let JsonnetValue::Object(attrs) = &arr[1] {
1633                            for (key, value) in attrs {
1634                                if !key.starts_with('_') {
1635                                    let value_str = match value {
1636                                        JsonnetValue::String(s) => s.clone(),
1637                                        _ => format!("{}", value),
1638                                    };
1639                                    xml.push_str(&format!(" {}=\"{}\"", key, value_str));
1640                                }
1641                            }
1642                            child_start = 2;
1643                        }
1644                    }
1645
1646                    xml.push('>');
1647
1648                    for child in &arr[child_start..] {
1650                        match child {
1651                            JsonnetValue::String(s) => xml.push_str(s),
1652                            JsonnetValue::Array(_) => {
1653                                let child_xml = Self::manifest_xml_jsonml(vec![child.clone()])?;
1655                                if let JsonnetValue::String(child_str) = child_xml {
1656                                    xml.push_str(&child_str);
1657                                }
1658                            }
1659                            _ => xml.push_str(&format!("{}", child)),
1660                        }
1661                    }
1662
1663                    xml.push_str(&format!("</{}>", tag));
1664                    Ok(JsonnetValue::string(xml))
1665                } else {
1666                    Err(JsonnetError::runtime_error("JsonML array must start with string tag name"))
1667                }
1668            }
1669            _ => Err(JsonnetError::runtime_error("manifestXmlJsonml expects a JsonML array")),
1670        }
1671    }
1672
1673    fn log2(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1675        Self::check_args(&args, 1, "log2")?;
1676        let x = args[0].as_number()?;
1677        if x <= 0.0 {
1678            return Err(JsonnetError::runtime_error("log2 of non-positive number"));
1679        }
1680        Ok(JsonnetValue::number(x.log2()))
1681    }
1682
1683    fn log10(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1684        Self::check_args(&args, 1, "log10")?;
1685        let x = args[0].as_number()?;
1686        if x <= 0.0 {
1687            return Err(JsonnetError::runtime_error("log10 of non-positive number"));
1688        }
1689        Ok(JsonnetValue::number(x.log10()))
1690    }
1691
1692    fn log1p(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1693        Self::check_args(&args, 1, "log1p")?;
1694        let x = args[0].as_number()?;
1695        if x < -1.0 {
1696            return Err(JsonnetError::runtime_error("log1p of number less than -1"));
1697        }
1698        Ok(JsonnetValue::number((x + 1.0).ln()))
1699    }
1700
1701    fn expm1(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1702        Self::check_args(&args, 1, "expm1")?;
1703        let x = args[0].as_number()?;
1704        Ok(JsonnetValue::number(x.exp() - 1.0))
1705    }
1706
1707    fn remove(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1711        Self::check_args(&args, 2, "remove")?;
1712        let arr = args[0].as_array()?;
1713        let value_to_remove = &args[1];
1714
1715        let filtered: Vec<JsonnetValue> = arr.iter()
1716            .filter(|item| !item.equals(value_to_remove))
1717            .cloned()
1718            .collect();
1719
1720        Ok(JsonnetValue::array(filtered))
1721    }
1722
1723    fn remove_at(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1724        Self::check_args(&args, 2, "removeAt")?;
1725        let arr = args[0].as_array()?;
1726        let index = args[1].as_number()? as usize;
1727
1728        if index >= arr.len() {
1729            return Err(JsonnetError::runtime_error("Index out of bounds"));
1730        }
1731
1732        let mut result = arr.clone();
1733        result.remove(index);
1734        Ok(JsonnetValue::array(result))
1735    }
1736
1737    fn flatten_arrays(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1738        Self::check_args(&args, 1, "flattenArrays")?;
1739        let arr = args[0].as_array()?;
1740
1741        let mut result = Vec::new();
1742        Self::flatten_array_recursive(arr, &mut result);
1743        Ok(JsonnetValue::array(result))
1744    }
1745
1746    fn flatten_array_recursive(arr: &[JsonnetValue], result: &mut Vec<JsonnetValue>) {
1747        for item in arr {
1748            match item {
1749                JsonnetValue::Array(sub_arr) => {
1750                    Self::flatten_array_recursive(sub_arr, result);
1751                }
1752                _ => result.push(item.clone()),
1753            }
1754        }
1755    }
1756
1757    fn object_keys_values(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1759        Self::check_args(&args, 1, "objectKeysValues")?;
1760        let obj = args[0].as_object()?;
1761
1762        let mut result = Vec::new();
1763        for (key, value) in obj {
1764            if !key.starts_with('_') {
1765                result.push(JsonnetValue::object(HashMap::from([
1766                    ("key".to_string(), JsonnetValue::string(key.clone())),
1767                    ("value".to_string(), value.clone()),
1768                ])));
1769            }
1770        }
1771
1772        Ok(JsonnetValue::array(result))
1773    }
1774
1775    fn object_remove_key(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1776        Self::check_args(&args, 2, "objectRemoveKey")?;
1777        let obj = args[0].as_object()?;
1778        let key_to_remove = args[1].as_string()?;
1779
1780        let mut result = obj.clone();
1781        result.remove(key_to_remove);
1782        Ok(JsonnetValue::object(result))
1783    }
1784
1785    fn is_integer(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1787        Self::check_args(&args, 1, "isInteger")?;
1788        match &args[0] {
1789            JsonnetValue::Number(n) => Ok(JsonnetValue::boolean(n.fract() == 0.0)),
1790            _ => Ok(JsonnetValue::boolean(false)),
1791        }
1792    }
1793
1794    fn is_decimal(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1795        Self::check_args(&args, 1, "isDecimal")?;
1796        match &args[0] {
1797            JsonnetValue::Number(n) => Ok(JsonnetValue::boolean(n.fract() != 0.0)),
1798            _ => Ok(JsonnetValue::boolean(false)),
1799        }
1800    }
1801
1802    fn is_even(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1803        Self::check_args(&args, 1, "isEven")?;
1804        match &args[0] {
1805            JsonnetValue::Number(n) if n.fract() == 0.0 => {
1806                Ok(JsonnetValue::boolean((*n as i64) % 2 == 0))
1807            }
1808            _ => Ok(JsonnetValue::boolean(false)),
1809        }
1810    }
1811
1812    fn is_odd(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1813        Self::check_args(&args, 1, "isOdd")?;
1814        match &args[0] {
1815            JsonnetValue::Number(n) if n.fract() == 0.0 => {
1816                Ok(JsonnetValue::boolean((*n as i64) % 2 != 0))
1817            }
1818            _ => Ok(JsonnetValue::boolean(false)),
1819        }
1820    }
1821
1822    fn check_args(args: &[JsonnetValue], expected: usize, func_name: &str) -> Result<()> {
1824        if args.len() != expected {
1825            return Err(JsonnetError::invalid_function_call(format!(
1826                "{}() expects {} arguments, got {}",
1827                func_name, expected, args.len()
1828            )));
1829        }
1830        Ok(())
1831    }
1832}
1833
1834impl JsonnetValue {
1835    pub fn from_json_value(value: serde_json::Value) -> Self {
1837        match value {
1838            serde_json::Value::Null => JsonnetValue::Null,
1839            serde_json::Value::Bool(b) => JsonnetValue::boolean(b),
1840            serde_json::Value::Number(n) => JsonnetValue::number(n.as_f64().unwrap_or(0.0)),
1841            serde_json::Value::String(s) => JsonnetValue::string(s),
1842            serde_json::Value::Array(arr) => {
1843                let jsonnet_arr: Vec<JsonnetValue> = arr.into_iter()
1844                    .map(JsonnetValue::from_json_value)
1845                    .collect();
1846                JsonnetValue::array(jsonnet_arr)
1847            }
1848            serde_json::Value::Object(obj) => {
1849                let mut jsonnet_obj = HashMap::new();
1850                for (k, v) in obj {
1851                    jsonnet_obj.insert(k, JsonnetValue::from_json_value(v));
1852                }
1853                JsonnetValue::object(jsonnet_obj)
1854            }
1855        }
1856    }
1857}