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 "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 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 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 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 Ok(JsonnetValue::array(vec![]))
160 }
161
162 fn filter(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
164 Self::check_args(&args, 2, "filter")?;
165 Ok(args[1].clone())
167 }
168
169 fn map(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
171 Self::check_args(&args, 2, "map")?;
172 Ok(args[1].clone())
174 }
175
176 fn foldl(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
178 Self::check_args(&args, 3, "foldl")?;
179 Ok(args[2].clone())
181 }
182
183 fn foldr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
185 Self::check_args(&args, 3, "foldr")?;
186 Ok(args[2].clone())
188 }
189
190 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 fn manifest_json_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
378 Self::check_args(&args, 2, "manifestJsonEx")?;
379 Self::manifest_json(vec![args[0].clone()])
381 }
382
383 #[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 #[cfg(not(feature = "yaml"))]
393 fn manifest_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
394 Self::check_args(&args, 1, "manifestYaml")?;
395 Self::manifest_json(args)
397 }
398
399 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 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 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 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 Self::check_args(&args, 2, "format")?;
460 Ok(JsonnetValue::string("<formatted>".to_string()))
461 }
462
463 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 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 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 eprintln!("TRACE: {:?}", args[1]);
681 Ok(args[0].clone())
683 }
684
685 fn sort(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
687 Self::check_args(&args, 1, "sort")?;
688 Ok(args[0].clone())
690 }
691
692 fn uniq(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
693 Self::check_args(&args, 1, "uniq")?;
694 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 fn merge_patch(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
707 Self::check_args(&args, 2, "mergePatch")?;
708 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('_')) .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 Ok(args[0].clone())
774 }
775
776 fn map_with_key(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
777 Self::check_args(&args, 2, "mapWithKey")?;
778 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 if a == b {
840 return Ok(JsonnetValue::boolean(true));
841 }
842
843 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 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 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 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 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()); 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 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 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 let mut result = Vec::new();
1011 for ch in s.chars() {
1012 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 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 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 let mut result = Vec::new();
1145
1146 for item in arr {
1147 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 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 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 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 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 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 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 fn manifest_ini(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1312 Self::check_args(&args, 1, "manifestIni")?;
1313 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 let json_str = serde_json::to_string(&args[0].to_json_value())?;
1340 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 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 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 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 for child in &arr[child_start..] {
1385 match child {
1386 JsonnetValue::String(s) => xml.push_str(s),
1387 JsonnetValue::Array(_) => {
1388 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 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 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 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}