1use crate::error::{JsonnetError, Result};
4use crate::value::JsonnetValue;
5use serde_json::json;
6
7pub trait FunctionCallback {
9 fn call_function(&mut self, func: JsonnetValue, args: Vec<JsonnetValue>) -> Result<JsonnetValue>;
10 fn call_external_function(&mut self, func: &str, args: Vec<JsonnetValue>) -> Result<JsonnetValue>;
11}
12use sha1::Sha1;
13use sha2::{Sha256, Sha512, Digest};
14use sha3::Sha3_256;
15use std::collections::HashMap;
16
17pub struct StdLib;
19
20pub struct StdLibWithCallback<'a> {
22 callback: &'a mut dyn FunctionCallback,
23}
24
25impl<'a> StdLibWithCallback<'a> {
26 pub fn new(callback: &'a mut dyn FunctionCallback) -> Self {
27 StdLibWithCallback { callback }
28 }
29
30 pub fn call_function(&mut self, name: &str, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
32 match name {
33 "length" => StdLib::length(args),
34 "type" => StdLib::type_of(args),
35 "makeArray" => StdLib::make_array(args),
36 "filter" => self.filter(args),
37 "map" => self.map(args),
38 "foldl" => self.foldl(args),
39 "foldr" => self.foldr(args),
40 "range" => StdLib::range(args),
42 "join" => self.join_variadic(args),
43 "split" => StdLib::split(args),
44 "contains" => self.contains_variadic(args),
45 "startsWith" => StdLib::starts_with(args),
46 "endsWith" => StdLib::ends_with(args),
47 "toLower" => StdLib::to_lower(args),
48 "toUpper" => StdLib::to_upper(args),
49 "trim" => StdLib::trim(args),
50 "substr" => StdLib::substr(args),
51 "char" => StdLib::char_fn(args),
52 "codepoint" => StdLib::codepoint(args),
53 "toString" => StdLib::to_string(args),
54 "parseInt" => StdLib::parse_int(args),
55 "parseJson" => StdLib::parse_json(args),
56 "encodeUTF8" => StdLib::encode_utf8(args),
57 "decodeUTF8" => StdLib::decode_utf8(args),
58 "md5" => StdLib::md5(args),
59 "base64" => StdLib::base64(args),
60 "base64Decode" => StdLib::base64_decode(args),
61 "manifestJson" => StdLib::manifest_json(args),
62 "manifestJsonEx" => StdLib::manifest_json_ex(args),
63 "manifestYaml" => StdLib::manifest_yaml(args),
64 "escapeStringJson" => StdLib::escape_string_json(args),
65 "escapeStringYaml" => StdLib::escape_string_yaml(args),
66 "escapeStringPython" => StdLib::escape_string_python(args),
67 "escapeStringBash" => StdLib::escape_string_bash(args),
68 "escapeStringDollars" => StdLib::escape_string_dollars(args),
69 "stringChars" => StdLib::string_chars(args),
70 "stringBytes" => StdLib::string_bytes(args),
71 "format" => StdLib::format(args),
72 "isArray" => StdLib::is_array(args),
73 "isBoolean" => StdLib::is_boolean(args),
74 "isFunction" => StdLib::is_function(args),
75 "isNumber" => StdLib::is_number(args),
76 "isObject" => StdLib::is_object(args),
77 "isString" => StdLib::is_string(args),
78 "count" => StdLib::count(args),
79 "find" => StdLib::find(args),
80 "member" => StdLib::member(args),
81 "modulo" => StdLib::modulo(args),
82 "pow" => StdLib::pow(args),
83 "exp" => StdLib::exp(args),
84 "log" => StdLib::log(args),
85 "sqrt" => StdLib::sqrt(args),
86 "sin" => StdLib::sin(args),
87 "cos" => StdLib::cos(args),
88 "tan" => StdLib::tan(args),
89 "asin" => StdLib::asin(args),
90 "acos" => StdLib::acos(args),
91 "atan" => StdLib::atan(args),
92 "floor" => StdLib::floor(args),
93 "ceil" => StdLib::ceil(args),
94 "round" => StdLib::round(args),
95 "abs" => StdLib::abs(args),
96 "max" => StdLib::max(args),
97 "min" => StdLib::min(args),
98 "clamp" => StdLib::clamp(args),
99 "assertEqual" => StdLib::assert_equal(args),
100 "trace" => StdLib::trace(args),
101 "sort" => StdLib::sort(args),
102 "uniq" => StdLib::uniq(args),
103 "reverse" => StdLib::reverse(args),
104 "mergePatch" => StdLib::merge_patch(args),
105 "get" => StdLib::get(args),
106 "id" => StdLib::id(args),
107 "equals" => StdLib::equals(args),
108 "lines" => StdLib::lines(args),
109 "strReplace" => StdLib::str_replace(args),
110 "sha1" => StdLib::sha1(args),
111 "sha256" => StdLib::sha256(args),
112 "sha3" => StdLib::sha3(args),
113 "sha512" => StdLib::sha512(args),
114 "asciiLower" => StdLib::ascii_lower(args),
115 "asciiUpper" => StdLib::ascii_upper(args),
116 "set" => StdLib::set(args),
117 "flatMap" => StdLib::flat_map(args),
118 "mapWithIndex" => StdLib::map_with_index(args),
119 "lstripChars" => StdLib::lstrip_chars(args),
120 "rstripChars" => StdLib::rstrip_chars(args),
121 "stripChars" => StdLib::strip_chars(args),
122 "findSubstr" => StdLib::find_substr(args),
123 "repeat" => StdLib::repeat(args),
124 "setMember" => StdLib::set_member(args),
125 "setUnion" => StdLib::set_union(args),
126 "setInter" => StdLib::set_inter(args),
127 "setDiff" => StdLib::set_diff(args),
128 "objectFields" => StdLib::object_fields(args),
129 "objectFieldsAll" => StdLib::object_fields_all(args),
130 "objectHas" => StdLib::object_has(args),
131 "objectHasAll" => StdLib::object_has_all(args),
132 "objectValues" => StdLib::object_values(args),
133 "objectValuesAll" => StdLib::object_values_all(args),
134 "objectFieldsEx" => StdLib::object_fields_ex(args),
135 "objectValuesEx" => StdLib::object_values_ex(args),
136 "prune" => StdLib::prune(args),
137 "mapWithKey" => StdLib::map_with_key(args),
138 "manifestIni" => StdLib::manifest_ini(args),
139 "manifestPython" => StdLib::manifest_python(args),
140 "manifestCpp" => StdLib::manifest_cpp(args),
141 "manifestXmlJsonml" => StdLib::manifest_xml_jsonml(args),
142 "log2" => StdLib::log2(args),
143 "log10" => StdLib::log10(args),
144 "log1p" => StdLib::log1p(args),
145 "expm1" => StdLib::expm1(args),
146 "remove" => StdLib::remove(args),
147 "removeAt" => StdLib::remove_at(args),
148 "flattenArrays" => StdLib::flatten_arrays(args),
149 "objectKeysValues" => StdLib::object_keys_values(args),
150 "objectRemoveKey" => StdLib::object_remove_key(args),
151 "isInteger" => StdLib::is_integer(args),
152 "isDecimal" => StdLib::is_decimal(args),
153 "isEven" => StdLib::is_even(args),
154 "isOdd" => StdLib::is_odd(args),
155 "slice" => self.slice(args),
157 "zip" => self.zip(args),
158 "transpose" => self.transpose(args),
159 "flatten" => self.flatten(args),
160 "sum" => self.sum(args),
161 "product" => self.product(args),
162 "all" => self.all(args),
163 "any" => self.any(args),
164 "sortBy" => self.sort_by(args),
165 "groupBy" => self.group_by(args),
166 "partition" => self.partition(args),
167 "chunk" => self.chunk(args),
168 "unique" => self.unique(args),
169 "difference" => self.difference(args),
170 "intersection" => self.intersection(args),
171 "symmetricDifference" => self.symmetric_difference(args),
172 "isSubset" => self.is_subset(args),
173 "isSuperset" => self.is_superset(args),
174 "isDisjoint" => self.is_disjoint(args),
175 "cartesian" => self.cartesian(args),
176 "cross" => self.cross(args),
177 "dot" => self.dot(args),
178 "norm" => self.norm(args),
179 "normalize" => self.normalize(args),
180 "distance" => self.distance(args),
181 "angle" => self.angle(args),
182 "rotate" => self.rotate(args),
183 "scale" => self.scale(args),
184 "translate" => self.translate(args),
185 "reflect" => self.reflect(args),
186 "affine" => self.affine(args),
187 "splitLimit" => self.split_limit(args),
188 "replace" => self.replace(args),
189
190 "ai.httpGet" => StdLib::ai_http_get(args),
196 "ai.httpPost" => StdLib::ai_http_post(args),
197
198 "ai.callModel" => StdLib::ai_call_model(args),
200
201 "tool.execute" => StdLib::tool_execute(args),
203
204 "memory.get" => StdLib::memory_get(args),
206 "memory.set" => StdLib::memory_set(args),
207
208 "agent.create" => StdLib::agent_create(args),
210 "agent.execute" => self.callback.call_external_function(name, args),
211
212 "chain.create" => self.callback.call_external_function(name, args),
214 "chain.execute" => self.callback.call_external_function(name, args),
215 "db.query" => self.callback.call_external_function(name, args),
216 "db.rewrite" => self.callback.call_external_function(name, args),
217 "db.patch" => self.callback.call_external_function(name, args),
218
219 _ => Err(JsonnetError::runtime_error(format!(
220 "Unknown function: {}",
221 name
222 ))),
223 }
224 }
225
226 fn filter(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
228 StdLib::check_args(&args, 2, "filter")?;
229 let _func = &args[0];
230 let arr = args[1].as_array()?;
231
232 let mut result = Vec::new();
233 for item in arr {
234 let call_result = self.callback.call_function(_func.clone(), vec![item.clone()])?;
236 if call_result.is_truthy() {
237 result.push(item.clone());
238 }
239 }
240
241 Ok(JsonnetValue::array(result))
242 }
243
244 fn map(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
245 StdLib::check_args(&args, 2, "map")?;
246 let _func = &args[0];
247 let arr = args[1].as_array()?;
248
249 let mut result = Vec::new();
250 for item in arr {
251 let call_result = self.callback.call_function(_func.clone(), vec![item.clone()])?;
253 result.push(call_result);
254 }
255
256 Ok(JsonnetValue::array(result))
257 }
258
259 fn foldl(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
260 StdLib::check_args(&args, 3, "foldl")?;
261 let _func = &args[0];
262 let arr = args[1].as_array()?;
263 let mut accumulator = args[2].clone();
264
265 for item in arr {
266 accumulator = self.callback.call_function(_func.clone(), vec![accumulator, item.clone()])?;
268 }
269
270 Ok(accumulator)
271 }
272
273 fn foldr(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
274 StdLib::check_args(&args, 3, "foldr")?;
275 let _func = &args[0];
276 let arr = args[1].as_array()?;
277 let mut accumulator = args[2].clone();
278
279 for item in arr.iter().rev() {
280 accumulator = self.callback.call_function(_func.clone(), vec![item.clone(), accumulator])?;
282 }
283
284 Ok(accumulator)
285 }
286
287 fn slice(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
289 if args.len() < 2 {
290 return Err(JsonnetError::invalid_function_call("slice() expects at least 2 arguments".to_string()));
291 }
292 let start = args[1].as_number()? as usize;
293
294 match &args[0] {
295 JsonnetValue::Array(arr) => {
296 let end = if args.len() > 2 {
297 args[2].as_number()? as usize
298 } else {
299 arr.len()
300 };
301 let start = start.min(arr.len());
302 let end = end.min(arr.len());
303 if start > end {
304 Ok(JsonnetValue::array(vec![]))
305 } else {
306 Ok(JsonnetValue::array(arr[start..end].to_vec()))
307 }
308 }
309 JsonnetValue::String(s) => {
310 let end = if args.len() > 2 {
311 args[2].as_number()? as usize
312 } else {
313 s.chars().count()
314 };
315 let chars: Vec<char> = s.chars().collect();
316 let start = start.min(chars.len());
317 let end = end.min(chars.len());
318 if start > end {
319 Ok(JsonnetValue::string("".to_string()))
320 } else {
321 let sliced: String = chars[start..end].iter().collect();
322 Ok(JsonnetValue::string(sliced))
323 }
324 }
325 _ => Err(JsonnetError::invalid_function_call("slice() expects array or string as first argument".to_string())),
326 }
327 }
328
329 fn zip(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
330 if args.is_empty() {
331 return Err(JsonnetError::invalid_function_call("zip() expects at least one argument".to_string()));
332 }
333
334 let arrays: Result<Vec<Vec<JsonnetValue>>> = args.into_iter()
336 .map(|arg| arg.as_array().cloned())
337 .collect();
338
339 let arrays = arrays?;
340 if arrays.is_empty() {
341 return Ok(JsonnetValue::array(vec![]));
342 }
343
344 let min_len = arrays.iter().map(|arr| arr.len()).min().unwrap_or(0);
346
347 let mut result = Vec::new();
349 for i in 0..min_len {
350 let mut tuple = Vec::new();
351 for arr in &arrays {
352 tuple.push(arr[i].clone());
353 }
354 result.push(JsonnetValue::array(tuple));
355 }
356
357 Ok(JsonnetValue::array(result))
358 }
359
360 fn transpose(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
361 StdLib::check_args(&args, 1, "transpose")?;
362 let matrix = args[0].as_array()?;
363
364 if matrix.is_empty() {
365 return Ok(JsonnetValue::array(vec![]));
366 }
367
368 let mut max_len = 0;
370 for row in matrix {
371 match row {
372 JsonnetValue::Array(arr) => {
373 max_len = max_len.max(arr.len());
374 }
375 _ => return Err(JsonnetError::invalid_function_call("transpose() expects array of arrays".to_string())),
376 }
377 }
378
379 if max_len == 0 {
380 return Ok(JsonnetValue::array(vec![]));
381 }
382
383 let mut result = Vec::new();
385 for col in 0..max_len {
386 let mut new_row = Vec::new();
387 for row in matrix {
388 if let JsonnetValue::Array(arr) = row {
389 if col < arr.len() {
390 new_row.push(arr[col].clone());
391 } else {
392 new_row.push(JsonnetValue::Null);
393 }
394 }
395 }
396 result.push(JsonnetValue::array(new_row));
397 }
398
399 Ok(JsonnetValue::array(result))
400 }
401
402 fn flatten(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
403 StdLib::check_args(&args, 1, "flatten")?;
404 let depth = if args.len() > 1 {
405 args[1].as_number()? as usize
406 } else {
407 usize::MAX
408 };
409
410 fn flatten_recursive(arr: &Vec<JsonnetValue>, current_depth: usize, max_depth: usize) -> Vec<JsonnetValue> {
411 let mut result = Vec::new();
412 for item in arr {
413 match item {
414 JsonnetValue::Array(nested) if current_depth < max_depth => {
415 result.extend(flatten_recursive(nested, current_depth + 1, max_depth));
416 }
417 _ => result.push(item.clone()),
418 }
419 }
420 result
421 }
422
423 let arr = args[0].as_array()?;
424 let flattened = flatten_recursive(arr, 0, depth);
425 Ok(JsonnetValue::array(flattened))
426 }
427
428 fn sum(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
429 StdLib::check_args(&args, 1, "sum")?;
430 let arr = args[0].as_array()?;
431
432 let mut total = 0.0;
433 for item in arr {
434 total += item.as_number()?;
435 }
436
437 Ok(JsonnetValue::number(total))
438 }
439
440 fn product(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
441 StdLib::check_args(&args, 1, "product")?;
442 let arr = args[0].as_array()?;
443
444 let mut result = 1.0;
445 for item in arr {
446 result *= item.as_number()?;
447 }
448
449 Ok(JsonnetValue::number(result))
450 }
451
452 fn all(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
453 StdLib::check_args(&args, 1, "all")?;
454 let arr = args[0].as_array()?;
455
456 for item in arr {
457 if !item.is_truthy() {
458 return Ok(JsonnetValue::boolean(false));
459 }
460 }
461
462 Ok(JsonnetValue::boolean(true))
463 }
464
465 fn any(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
466 StdLib::check_args(&args, 1, "any")?;
467 let arr = args[0].as_array()?;
468
469 for item in arr {
470 if item.is_truthy() {
471 return Ok(JsonnetValue::boolean(true));
472 }
473 }
474
475 Ok(JsonnetValue::boolean(false))
476 }
477
478 fn chunk(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
479 StdLib::check_args(&args, 2, "chunk")?;
480 let arr = args[0].as_array()?;
481 let size = args[1].as_number()? as usize;
482
483 if size == 0 {
484 return Err(JsonnetError::invalid_function_call("chunk() size must be positive".to_string()));
485 }
486
487 let mut result = Vec::new();
488 for chunk in arr.chunks(size) {
489 result.push(JsonnetValue::array(chunk.to_vec()));
490 }
491
492 Ok(JsonnetValue::array(result))
493 }
494
495 fn unique(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
496 StdLib::check_args(&args, 1, "unique")?;
497 let arr = args[0].as_array()?;
498
499 let mut seen = std::collections::HashSet::new();
500 let mut result = Vec::new();
501
502 for item in arr {
503 if !seen.contains(&format!("{:?}", item)) {
505 seen.insert(format!("{:?}", item));
506 result.push(item.clone());
507 }
508 }
509
510 Ok(JsonnetValue::array(result))
511 }
512
513 fn difference(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
514 if args.is_empty() {
515 return Ok(JsonnetValue::array(vec![]));
516 }
517
518 let first = args[0].as_array()?;
519 let mut result = first.clone();
520
521 for arg in &args[1..] {
522 let other = arg.as_array()?;
523 let other_set: std::collections::HashSet<String> = other.iter()
524 .map(|v| format!("{:?}", v))
525 .collect();
526
527 result.retain(|item| !other_set.contains(&format!("{:?}", item)));
528 }
529
530 Ok(JsonnetValue::array(result))
531 }
532
533 fn intersection(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
534 if args.is_empty() {
535 return Ok(JsonnetValue::array(vec![]));
536 }
537
538 let first = args[0].as_array()?;
539 let mut result = first.clone();
540
541 for arg in &args[1..] {
542 let other = arg.as_array()?;
543 let other_set: std::collections::HashSet<String> = other.iter()
544 .map(|v| format!("{:?}", v))
545 .collect();
546
547 result.retain(|item| other_set.contains(&format!("{:?}", item)));
548 }
549
550 Ok(JsonnetValue::array(result))
551 }
552
553 fn symmetric_difference(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
554 StdLib::check_args(&args, 2, "symmetricDifference")?;
555 let a = args[0].as_array()?;
556 let b = args[1].as_array()?;
557
558 let a_set: std::collections::HashSet<String> = a.iter()
559 .map(|v| format!("{:?}", v))
560 .collect();
561 let b_set: std::collections::HashSet<String> = b.iter()
562 .map(|v| format!("{:?}", v))
563 .collect();
564
565 let symmetric_diff: std::collections::HashSet<_> = a_set.symmetric_difference(&b_set).cloned().collect();
566
567 let result: Vec<JsonnetValue> = a.iter()
568 .filter(|item| symmetric_diff.contains(&format!("{:?}", item)))
569 .chain(b.iter().filter(|item| symmetric_diff.contains(&format!("{:?}", item))))
570 .cloned()
571 .collect();
572
573 Ok(JsonnetValue::array(result))
574 }
575
576 fn is_subset(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
577 StdLib::check_args(&args, 2, "isSubset")?;
578 let a = args[0].as_array()?;
579 let b = args[1].as_array()?;
580
581 let b_set: std::collections::HashSet<String> = b.iter()
582 .map(|v| format!("{:?}", v))
583 .collect();
584
585 let is_subset = a.iter().all(|item| b_set.contains(&format!("{:?}", item)));
586
587 Ok(JsonnetValue::boolean(is_subset))
588 }
589
590 fn is_superset(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
591 StdLib::check_args(&args, 2, "isSuperset")?;
592 let a = args[0].as_array()?;
593 let b = args[1].as_array()?;
594
595 let a_set: std::collections::HashSet<String> = a.iter()
596 .map(|v| format!("{:?}", v))
597 .collect();
598
599 let is_superset = b.iter().all(|item| a_set.contains(&format!("{:?}", item)));
600
601 Ok(JsonnetValue::boolean(is_superset))
602 }
603
604 fn is_disjoint(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
605 StdLib::check_args(&args, 2, "isDisjoint")?;
606 let a = args[0].as_array()?;
607 let b = args[1].as_array()?;
608
609 let a_set: std::collections::HashSet<String> = a.iter()
610 .map(|v| format!("{:?}", v))
611 .collect();
612 let b_set: std::collections::HashSet<String> = b.iter()
613 .map(|v| format!("{:?}", v))
614 .collect();
615
616 let is_disjoint = a_set.intersection(&b_set).count() == 0;
617
618 Ok(JsonnetValue::boolean(is_disjoint))
619 }
620
621 fn cartesian(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
622 StdLib::check_args(&args, 1, "cartesian")?;
623 let arrays = args[0].as_array()?;
624
625 if arrays.is_empty() {
626 return Ok(JsonnetValue::array(vec![JsonnetValue::array(vec![])]));
627 }
628
629 let mut vec_arrays = Vec::new();
631 for arr in arrays {
632 vec_arrays.push(arr.as_array()?.clone());
633 }
634
635 fn cartesian_product(arrays: &[Vec<JsonnetValue>]) -> Vec<Vec<JsonnetValue>> {
636 if arrays.is_empty() {
637 return vec![vec![]];
638 }
639
640 let mut result = Vec::new();
641 let first = &arrays[0];
642 let rest = &arrays[1..];
643
644 for item in first {
645 for mut combo in cartesian_product(rest) {
646 combo.insert(0, item.clone());
647 result.push(combo);
648 }
649 }
650
651 result
652 }
653
654 let products = cartesian_product(&vec_arrays);
655 let result: Vec<JsonnetValue> = products.into_iter()
656 .map(|combo| JsonnetValue::array(combo))
657 .collect();
658
659 Ok(JsonnetValue::array(result))
660 }
661
662 fn cross(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
663 StdLib::check_args(&args, 2, "cross")?;
664 let a = args[0].as_array()?;
665 let b = args[1].as_array()?;
666
667 let mut result = Vec::new();
668 for item_a in a {
669 for item_b in b {
670 result.push(JsonnetValue::array(vec![item_a.clone(), item_b.clone()]));
671 }
672 }
673
674 Ok(JsonnetValue::array(result))
675 }
676
677 fn dot(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
678 StdLib::check_args(&args, 2, "dot")?;
679 let a = args[0].as_array()?;
680 let b = args[1].as_array()?;
681
682 if a.len() != b.len() {
683 return Err(JsonnetError::invalid_function_call("dot() arrays must have same length".to_string()));
684 }
685
686 let mut sum = 0.0;
687 for (x, y) in a.iter().zip(b.iter()) {
688 sum += x.as_number()? * y.as_number()?;
689 }
690
691 Ok(JsonnetValue::number(sum))
692 }
693
694 fn norm(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
695 StdLib::check_args(&args, 1, "norm")?;
696 let arr = args[0].as_array()?;
697
698 let mut sum_squares = 0.0;
699 for item in arr {
700 let val = item.as_number()?;
701 sum_squares += val * val;
702 }
703
704 Ok(JsonnetValue::number(sum_squares.sqrt()))
705 }
706
707 fn normalize(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
708 StdLib::check_args(&args, 1, "normalize")?;
709 let arr = args[0].as_array()?;
710
711 let mut sum_squares = 0.0;
713 for item in arr {
714 let val = item.as_number()?;
715 sum_squares += val * val;
716 }
717 let norm_val = sum_squares.sqrt();
718
719 if norm_val == 0.0 {
720 return Ok(args[0].clone());
721 }
722
723 let mut result = Vec::new();
724 for item in arr {
725 let val = item.as_number()?;
726 result.push(JsonnetValue::number(val / norm_val));
727 }
728
729 Ok(JsonnetValue::array(result))
730 }
731
732 fn distance(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
733 StdLib::check_args(&args, 2, "distance")?;
734 let a = args[0].as_array()?;
735 let b = args[1].as_array()?;
736
737 if a.len() != b.len() {
738 return Err(JsonnetError::invalid_function_call("distance() arrays must have same length".to_string()));
739 }
740
741 let mut sum_squares = 0.0;
742 for (x, y) in a.iter().zip(b.iter()) {
743 let diff = x.as_number()? - y.as_number()?;
744 sum_squares += diff * diff;
745 }
746
747 Ok(JsonnetValue::number(sum_squares.sqrt()))
748 }
749
750 fn angle(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
751 StdLib::check_args(&args, 2, "angle")?;
752 let a = args[0].as_array()?;
753 let b = args[1].as_array()?;
754
755 if a.len() != b.len() {
756 return Err(JsonnetError::invalid_function_call("angle() arrays must have same length".to_string()));
757 }
758
759 let mut dot_product = 0.0;
761 for (x, y) in a.iter().zip(b.iter()) {
762 dot_product += x.as_number()? * y.as_number()?;
763 }
764
765 let mut norm_a_sq = 0.0;
767 for item in a {
768 let val = item.as_number()?;
769 norm_a_sq += val * val;
770 }
771 let norm_a = norm_a_sq.sqrt();
772
773 let mut norm_b_sq = 0.0;
774 for item in b {
775 let val = item.as_number()?;
776 norm_b_sq += val * val;
777 }
778 let norm_b = norm_b_sq.sqrt();
779
780 if norm_a == 0.0 || norm_b == 0.0 {
781 return Ok(JsonnetValue::number(0.0));
782 }
783
784 let cos_theta = dot_product / (norm_a * norm_b);
785 let cos_theta = cos_theta.max(-1.0).min(1.0); Ok(JsonnetValue::number(cos_theta.acos()))
788 }
789
790 fn rotate(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
791 StdLib::check_args(&args, 2, "rotate")?;
792 let point = args[0].as_array()?;
793 let angle = args[1].as_number()?;
794
795 if point.len() != 2 {
796 return Err(JsonnetError::invalid_function_call("rotate() point must be 2D".to_string()));
797 }
798
799 let center = if args.len() > 2 {
800 args[2].as_array()?.to_vec()
801 } else {
802 vec![JsonnetValue::number(0.0), JsonnetValue::number(0.0)]
803 };
804
805 if center.len() != 2 {
806 return Err(JsonnetError::invalid_function_call("rotate() center must be 2D".to_string()));
807 }
808
809 let x = point[0].as_number()? - center[0].as_number()?;
810 let y = point[1].as_number()? - center[1].as_number()?;
811
812 let cos_a = angle.cos();
813 let sin_a = angle.sin();
814
815 let new_x = x * cos_a - y * sin_a + center[0].as_number()?;
816 let new_y = x * sin_a + y * cos_a + center[1].as_number()?;
817
818 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
819 }
820
821 fn scale(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
822 StdLib::check_args(&args, 2, "scale")?;
823 let point = args[0].as_array()?;
824 let factor = args[1].as_number()?;
825
826 if point.len() != 2 {
827 return Err(JsonnetError::invalid_function_call("scale() point must be 2D".to_string()));
828 }
829
830 let center = if args.len() > 2 {
831 args[2].as_array()?.to_vec()
832 } else {
833 vec![JsonnetValue::number(0.0), JsonnetValue::number(0.0)]
834 };
835
836 if center.len() != 2 {
837 return Err(JsonnetError::invalid_function_call("scale() center must be 2D".to_string()));
838 }
839
840 let x = point[0].as_number()? - center[0].as_number()?;
841 let y = point[1].as_number()? - center[1].as_number()?;
842
843 let new_x = x * factor + center[0].as_number()?;
844 let new_y = y * factor + center[1].as_number()?;
845
846 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
847 }
848
849 fn translate(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
850 StdLib::check_args(&args, 2, "translate")?;
851 let point = args[0].as_array()?;
852 let offset = args[1].as_array()?;
853
854 if point.len() != 2 || offset.len() != 2 {
855 return Err(JsonnetError::invalid_function_call("translate() requires 2D point and offset".to_string()));
856 }
857
858 let new_x = point[0].as_number()? + offset[0].as_number()?;
859 let new_y = point[1].as_number()? + offset[1].as_number()?;
860
861 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
862 }
863
864 fn reflect(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
865 StdLib::check_args(&args, 2, "reflect")?;
866 let point = args[0].as_array()?;
867 let axis = args[1].as_number()?; if point.len() != 2 {
870 return Err(JsonnetError::invalid_function_call("reflect() point must be 2D".to_string()));
871 }
872
873 let x = point[0].as_number()?;
874 let y = point[1].as_number()?;
875
876 let cos_2a = (2.0 * axis).cos();
877 let sin_2a = (2.0 * axis).sin();
878
879 let new_x = x * cos_2a + y * sin_2a;
880 let new_y = x * sin_2a - y * cos_2a;
881
882 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
883 }
884
885 fn affine(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
886 StdLib::check_args(&args, 2, "affine")?;
887 let point = args[0].as_array()?;
888 let matrix = args[1].as_array()?;
889
890 if point.len() != 2 {
891 return Err(JsonnetError::invalid_function_call("affine() point must be 2D".to_string()));
892 }
893
894 if matrix.len() != 6 {
895 return Err(JsonnetError::invalid_function_call("affine() matrix must be 6 elements [a,b,c,d,e,f]".to_string()));
896 }
897
898 let x = point[0].as_number()?;
899 let y = point[1].as_number()?;
900
901 let a = matrix[0].as_number()?;
902 let b = matrix[1].as_number()?;
903 let c = matrix[2].as_number()?;
904 let d = matrix[3].as_number()?;
905 let e = matrix[4].as_number()?;
906 let f = matrix[5].as_number()?;
907
908 let new_x = a * x + b * y + e;
909 let new_y = c * x + d * y + f;
910
911 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
912 }
913
914 fn split_limit(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
915 StdLib::check_args(&args, 3, "splitLimit")?;
916 let s = args[0].as_string()?;
917 let sep = args[1].as_string()?;
918 let limit = args[2].as_number()? as usize;
919
920 if sep.is_empty() {
921 let chars: Vec<String> = s.chars().take(limit).map(|c| c.to_string()).collect();
923 let result: Vec<JsonnetValue> = chars.into_iter().map(JsonnetValue::string).collect();
924 return Ok(JsonnetValue::array(result));
925 }
926
927 let mut parts: Vec<&str> = s.splitn(limit + 1, &sep).collect();
928 if parts.len() > limit {
929 let remaining = parts.split_off(limit);
931 parts.push(&s[(s.len() - remaining.join(&sep).len())..]);
932 }
933
934 let result: Vec<JsonnetValue> = parts.into_iter().map(|s| JsonnetValue::string(s.to_string())).collect();
935 Ok(JsonnetValue::array(result))
936 }
937
938 fn join_variadic(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
939 if args.is_empty() {
940 return Err(JsonnetError::invalid_function_call("join() expects at least one argument".to_string()));
941 }
942
943 let sep = args[0].as_string()?;
944 let arrays: Result<Vec<Vec<JsonnetValue>>> = args[1..].iter()
945 .map(|arg| arg.as_array().cloned())
946 .collect();
947
948 let arrays = arrays?;
949 let mut result = Vec::new();
950
951 for (i, arr) in arrays.iter().enumerate() {
952 if i > 0 && !sep.is_empty() {
953 result.push(JsonnetValue::string(sep.clone()));
954 }
955 result.extend(arr.iter().cloned());
956 }
957
958 Ok(JsonnetValue::array(result))
959 }
960
961 fn replace(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
962 StdLib::check_args(&args, 3, "replace")?;
963 let s = args[0].as_string()?;
964 let old = args[1].as_string()?;
965 let new = args[2].as_string()?;
966
967 let result = s.replace(&old, &new);
968 Ok(JsonnetValue::string(result))
969 }
970
971 fn contains_variadic(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
972 StdLib::check_args(&args, 2, "contains")?;
973
974 match &args[0] {
975 JsonnetValue::Array(arr) => {
976 let target = format!("{:?}", &args[1]);
978 for item in arr {
979 if format!("{:?}", item) == target {
980 return Ok(JsonnetValue::boolean(true));
981 }
982 }
983 Ok(JsonnetValue::boolean(false))
984 }
985 JsonnetValue::String(s) => {
986 let substr = args[1].as_string()?;
987 Ok(JsonnetValue::boolean(s.contains(&substr)))
988 }
989 JsonnetValue::Object(obj) => {
990 let key = args[1].as_string()?;
991 Ok(JsonnetValue::boolean(obj.contains_key(&*key)))
992 }
993 _ => Err(JsonnetError::invalid_function_call("contains() expects array, string, or object".to_string())),
994 }
995 }
996
997 fn sort_by(&mut self, _args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
999 Err(JsonnetError::runtime_error("sortBy() requires function calling mechanism - placeholder implementation".to_string()))
1000 }
1001
1002 fn group_by(&mut self, _args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1003 Err(JsonnetError::runtime_error("groupBy() requires function calling mechanism - placeholder implementation".to_string()))
1004 }
1005
1006 fn partition(&mut self, _args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1007 Err(JsonnetError::runtime_error("partition() requires function calling mechanism - placeholder implementation".to_string()))
1008 }
1009}
1010
1011impl StdLib {
1012 pub fn dispatch(
1014 &self,
1015 func_name: &str,
1016 args: &[JsonnetValue],
1017 ) -> Result<JsonnetValue> {
1018 match func_name {
1019 "ai.httpGet" => Ok(JsonnetValue::string("ai.httpGet stub")),
1021 "ai.httpPost" => Ok(JsonnetValue::string("ai.httpPost stub")),
1022 "ai.callModel" => Ok(JsonnetValue::string("ai.callModel stub")),
1023
1024 "tool.execute" => Ok(JsonnetValue::string("tool.execute stub")),
1026
1027 "memory.get" => Ok(JsonnetValue::string("memory.get stub")),
1029 "memory.set" => Ok(JsonnetValue::string("memory.set stub")),
1030
1031 "agent.create" => Ok(JsonnetValue::string("agent.create stub")),
1033 "agent.execute" => Ok(JsonnetValue::string("agent.execute stub")),
1034
1035 "chain.create" => Ok(JsonnetValue::string("chain.create stub")),
1037 "chain.execute" => Ok(JsonnetValue::string("chain.execute stub")),
1038
1039 "std.extVar" => self.std_ext_var(args.to_vec()),
1041 "std.manifestJson" => self.std_manifest_json(args.to_vec()),
1042 _ => Err(JsonnetError::runtime_error(format!("Unknown std function: {}", func_name))),
1045 }
1046 }
1047
1048 pub fn ai_http_get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1054 StdLib::check_args(&args, 1, "ai.httpGet")?;
1055 let url = args[0].as_string()?;
1056 let headers = if args.len() > 1 {
1057 args[1].as_object()?
1058 } else {
1059 &std::collections::HashMap::new()
1060 };
1061
1062 let result = json!({
1064 "url": url,
1065 "method": "GET",
1066 "headers": headers,
1067 "status": "pending",
1068 "response": "HTTP GET will be handled by AI runtime"
1069 });
1070 Ok(JsonnetValue::from_json_value(result))
1071 }
1072
1073 pub fn ai_http_post(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1075 StdLib::check_args(&args, 2, "ai.httpPost")?;
1076 let url = args[0].as_string()?;
1077 let body = &args[1];
1078 let headers = if args.len() > 2 {
1079 args[2].as_object()?
1080 } else {
1081 &std::collections::HashMap::new()
1082 };
1083
1084 let result = json!({
1086 "url": url,
1087 "method": "POST",
1088 "body": body,
1089 "headers": headers,
1090 "status": "pending",
1091 "response": "HTTP POST will be handled by AI runtime"
1092 });
1093 Ok(JsonnetValue::from_json_value(result))
1094 }
1095
1096 pub fn ai_call_model(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1098 StdLib::check_args(&args, 2, "ai.callModel")?;
1099 let model = args[0].as_string()?;
1100 let prompt = args[1].as_string()?;
1101 let options = if args.len() > 2 {
1102 args[2].as_object()?
1103 } else {
1104 &std::collections::HashMap::new()
1105 };
1106
1107 let result = json!({
1109 "model": model,
1110 "prompt": prompt,
1111 "options": options,
1112 "status": "pending",
1113 "response": "AI model call will be handled by AI runtime"
1114 });
1115 Ok(JsonnetValue::from_json_value(result))
1116 }
1117
1118 pub fn tool_execute(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1120 StdLib::check_args(&args, 2, "tool.execute")?;
1121 let name = args[0].as_string()?;
1122 let tool_args = &args[1];
1123
1124 let result = json!({
1126 "tool": name,
1127 "args": tool_args,
1128 "status": "pending",
1129 "output": "Tool execution will be handled by runtime"
1130 });
1131 Ok(JsonnetValue::from_json_value(result))
1132 }
1133
1134 pub fn memory_get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1136 StdLib::check_args(&args, 1, "memory.get")?;
1137 let key = args[0].as_string()?;
1138
1139 let result = json!({
1141 "key": key,
1142 "operation": "get",
1143 "status": "pending",
1144 "value": "Memory access will be handled by runtime"
1145 });
1146 Ok(JsonnetValue::from_json_value(result))
1147 }
1148
1149 pub fn memory_set(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1151 StdLib::check_args(&args, 2, "memory.set")?;
1152 let key = args[0].as_string()?;
1153 let value = &args[1];
1154
1155 let result = json!({
1157 "key": key,
1158 "value": value,
1159 "operation": "set",
1160 "status": "success"
1161 });
1162 Ok(JsonnetValue::from_json_value(result))
1163 }
1164
1165 pub fn agent_create(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1167 StdLib::check_args(&args, 1, "agent.create")?;
1168 let config = args[0].as_object()?;
1169
1170 let result = json!({
1172 "config": config,
1173 "operation": "create",
1174 "status": "pending",
1175 "agent_id": "mock-agent-id"
1176 });
1177 Ok(JsonnetValue::from_json_value(result))
1178 }
1179
1180 pub fn std_ext_var(&self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1182 StdLib::check_args(&args, 1, "std.extVar")?;
1183 let name = args[0].as_string()?;
1184
1185 let result = json!({
1187 "variable": name,
1188 "value": "External variable will be resolved by runtime",
1189 "status": "pending"
1190 });
1191 Ok(JsonnetValue::from_json_value(result))
1192 }
1193
1194 pub fn std_manifest_json(&self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1196 StdLib::check_args(&args, 1, "std.manifestJson")?;
1197 let value = &args[0];
1198 let indent = if args.len() > 1 {
1199 args[1].as_number()? as usize
1200 } else {
1201 0
1202 };
1203
1204 match serde_json::to_string_pretty(&value) {
1206 Ok(json_str) => {
1207 if indent > 0 {
1208 Ok(JsonnetValue::string(json_str))
1209 } else {
1210 Ok(JsonnetValue::string(serde_json::to_string(&value).unwrap_or_default()))
1211 }
1212 }
1213 Err(_) => Err(JsonnetError::runtime_error("Failed to serialize to JSON")),
1214 }
1215 }
1216
1217 pub fn length(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1219 Self::check_args(&args, 1, "length")?;
1220 match &args[0] {
1221 JsonnetValue::Array(arr) => Ok(JsonnetValue::number(arr.len() as f64)),
1222 JsonnetValue::String(s) => Ok(JsonnetValue::number(s.len() as f64)),
1223 JsonnetValue::Object(obj) => Ok(JsonnetValue::number(obj.len() as f64)),
1224 _ => Err(JsonnetError::type_error("length() requires array, string, or object")),
1225 }
1226 }
1227
1228 fn type_of(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1230 Self::check_args(&args, 1, "type")?;
1231 let type_str = args[0].type_name();
1232 Ok(JsonnetValue::string(type_str))
1233 }
1234
1235 fn make_array(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1237 Self::check_args(&args, 2, "makeArray")?;
1238 let n = args[0].as_number()? as usize;
1239 let _func = &args[1];
1240
1241 let mut result = Vec::new();
1244 for i in 0..n {
1245 result.push(JsonnetValue::number(i as f64));
1247 }
1248
1249 Ok(JsonnetValue::array(result))
1250 }
1251
1252 fn filter(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1254 Self::check_args(&args, 2, "filter")?;
1255 let _func = &args[0];
1256 let _arr = args[1].as_array()?;
1257 Ok(args[1].clone())
1260 }
1261
1262 fn map(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1264 Self::check_args(&args, 2, "map")?;
1265 let _func = &args[0];
1266 let _arr = args[1].as_array()?;
1267 Ok(args[1].clone())
1270 }
1271
1272 fn foldl(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1274 Self::check_args(&args, 3, "foldl")?;
1275 let _func = &args[0];
1276 let _arr = args[1].as_array()?;
1277 Ok(args[2].clone())
1280 }
1281
1282 fn foldr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1284 Self::check_args(&args, 3, "foldr")?;
1285 let _func = &args[0];
1286 let _arr = args[1].as_array()?;
1287 Ok(args[2].clone())
1290 }
1291
1292 fn range(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1294 Self::check_args(&args, 1, "range")?;
1295 let n = args[0].as_number()? as usize;
1296 let arr: Vec<JsonnetValue> = (0..n).map(|i| JsonnetValue::number(i as f64)).collect();
1297 Ok(JsonnetValue::array(arr))
1298 }
1299
1300 fn join(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1302 Self::check_args(&args, 2, "join")?;
1303 let sep = args[0].as_string()?;
1304 let arr = args[1].as_array()?;
1305
1306 let mut result = String::new();
1307 for (i, item) in arr.iter().enumerate() {
1308 if i > 0 {
1309 result.push_str(sep);
1310 }
1311 result.push_str(&item.to_string());
1312 }
1313
1314 Ok(JsonnetValue::string(result))
1315 }
1316
1317 fn split(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1319 Self::check_args(&args, 2, "split")?;
1320 let s = args[0].as_string()?;
1321 let sep = args[1].as_string()?;
1322
1323 let parts: Vec<JsonnetValue> = s.split(sep).map(JsonnetValue::string).collect();
1324 Ok(JsonnetValue::array(parts))
1325 }
1326
1327 fn contains(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1329 Self::check_args(&args, 2, "contains")?;
1330 let arr = args[0].as_array()?;
1331 let contains = arr.iter().any(|item| item.equals(&args[1]));
1332 Ok(JsonnetValue::boolean(contains))
1333 }
1334
1335 fn starts_with(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1337 Self::check_args(&args, 2, "startsWith")?;
1338 let s = args[0].as_string()?;
1339 let prefix = args[1].as_string()?;
1340 Ok(JsonnetValue::boolean(s.starts_with(prefix)))
1341 }
1342
1343 fn ends_with(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1345 Self::check_args(&args, 2, "endsWith")?;
1346 let s = args[0].as_string()?;
1347 let suffix = args[1].as_string()?;
1348 Ok(JsonnetValue::boolean(s.ends_with(suffix)))
1349 }
1350
1351 fn substr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1353 Self::check_args(&args, 3, "substr")?;
1354 let s = args[0].as_string()?;
1355 let from = args[1].as_number()? as usize;
1356 let len = args[2].as_number()? as usize;
1357
1358 let substr = if from >= s.len() {
1359 ""
1360 } else {
1361 let end = (from + len).min(s.len());
1362 &s[from..end]
1363 };
1364
1365 Ok(JsonnetValue::string(substr))
1366 }
1367
1368 fn char_fn(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1370 Self::check_args(&args, 1, "char")?;
1371 let n = args[0].as_number()? as u32;
1372 match char::from_u32(n) {
1373 Some(c) => Ok(JsonnetValue::string(c.to_string())),
1374 None => Err(JsonnetError::runtime_error("Invalid codepoint")),
1375 }
1376 }
1377
1378 fn codepoint(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1380 Self::check_args(&args, 1, "codepoint")?;
1381 let s = args[0].as_string()?;
1382 match s.chars().next() {
1383 Some(c) => Ok(JsonnetValue::number(c as u32 as f64)),
1384 None => Err(JsonnetError::runtime_error("Empty string")),
1385 }
1386 }
1387
1388 fn to_string(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1390 Self::check_args(&args, 1, "toString")?;
1391 Ok(JsonnetValue::string(args[0].to_string()))
1392 }
1393
1394 fn parse_int(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1396 Self::check_args(&args, 1, "parseInt")?;
1397 let s = args[0].as_string()?;
1398 match s.parse::<f64>() {
1399 Ok(n) => Ok(JsonnetValue::number(n)),
1400 Err(_) => Err(JsonnetError::runtime_error("Invalid number format")),
1401 }
1402 }
1403
1404 fn parse_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1406 Self::check_args(&args, 1, "parseJson")?;
1407 let s = args[0].as_string()?;
1408 match serde_json::from_str::<serde_json::Value>(s) {
1409 Ok(value) => Ok(JsonnetValue::from_json_value(value)),
1410 Err(_) => Err(JsonnetError::runtime_error("Invalid JSON")),
1411 }
1412 }
1413
1414 fn encode_utf8(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1416 Self::check_args(&args, 1, "encodeUTF8")?;
1417 let s = args[0].as_string()?;
1418 let bytes: Vec<JsonnetValue> = s.as_bytes().iter().map(|&b| JsonnetValue::number(b as f64)).collect();
1419 Ok(JsonnetValue::array(bytes))
1420 }
1421
1422 fn decode_utf8(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1424 Self::check_args(&args, 1, "decodeUTF8")?;
1425 let arr = args[0].as_array()?;
1426 let mut bytes = Vec::new();
1427 for item in arr {
1428 let b = item.as_number()? as u8;
1429 bytes.push(b);
1430 }
1431 match String::from_utf8(bytes) {
1432 Ok(s) => Ok(JsonnetValue::string(s)),
1433 Err(_) => Err(JsonnetError::runtime_error("Invalid UTF-8 sequence")),
1434 }
1435 }
1436
1437 fn md5(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1439 Self::check_args(&args, 1, "md5")?;
1440 let s = args[0].as_string()?;
1441 use md5::{Md5, Digest};
1442 let mut hasher = Md5::new();
1443 hasher.update(s.as_bytes());
1444 let result = hasher.finalize();
1445 Ok(JsonnetValue::string(format!("{:x}", result)))
1446 }
1447
1448 fn base64(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1450 Self::check_args(&args, 1, "base64")?;
1451 let s = args[0].as_string()?;
1452 use base64::{Engine as _, engine::general_purpose};
1453 let encoded = general_purpose::STANDARD.encode(s.as_bytes());
1454 Ok(JsonnetValue::string(encoded))
1455 }
1456
1457 fn base64_decode(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1459 Self::check_args(&args, 1, "base64Decode")?;
1460 let s = args[0].as_string()?;
1461 use base64::{Engine as _, engine::general_purpose};
1462 match general_purpose::STANDARD.decode(s.as_bytes()) {
1463 Ok(bytes) => match String::from_utf8(bytes) {
1464 Ok(decoded) => Ok(JsonnetValue::string(decoded)),
1465 Err(_) => Err(JsonnetError::runtime_error("Invalid UTF-8 in decoded data")),
1466 },
1467 Err(_) => Err(JsonnetError::runtime_error("Invalid base64")),
1468 }
1469 }
1470
1471 fn manifest_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1473 Self::check_args(&args, 1, "manifestJson")?;
1474 let json = serde_json::to_string_pretty(&args[0].to_json_value())?;
1475 Ok(JsonnetValue::string(json))
1476 }
1477
1478 fn manifest_json_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1480 Self::check_args(&args, 2, "manifestJsonEx")?;
1481 let value = &args[0];
1482 let indent = args[1].as_string()?;
1483
1484 match serde_json::to_string_pretty(&value.to_json_value()) {
1487 Ok(json) => {
1488 if indent.is_empty() {
1489 Ok(JsonnetValue::string(json))
1490 } else {
1491 let indented = json.lines()
1493 .map(|line| {
1494 let leading_spaces = line.chars().take_while(|c| *c == ' ').count();
1495 if leading_spaces > 0 {
1496 let indent_level = leading_spaces / 2;
1497 format!("{}{}", indent.repeat(indent_level), &line[leading_spaces..])
1498 } else {
1499 line.to_string()
1500 }
1501 })
1502 .collect::<Vec<_>>()
1503 .join("\n");
1504 Ok(JsonnetValue::string(indented))
1505 }
1506 }
1507 Err(_) => Err(JsonnetError::runtime_error("Failed to serialize to JSON")),
1508 }
1509 }
1510
1511 #[cfg(feature = "yaml")]
1513 fn manifest_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1514 Self::check_args(&args, 1, "manifestYaml")?;
1515 let yaml = serde_yaml::to_string(&args[0].to_json_value())?;
1516 Ok(JsonnetValue::string(yaml))
1517 }
1518
1519 #[cfg(not(feature = "yaml"))]
1521 fn manifest_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1522 Self::check_args(&args, 1, "manifestYaml")?;
1523 Self::manifest_json(args)
1525 }
1526
1527 fn escape_string_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1529 Self::check_args(&args, 1, "escapeStringJson")?;
1530 let s = args[0].as_string()?;
1531 let escaped = serde_json::to_string(s)?;
1532 Ok(JsonnetValue::string(escaped))
1533 }
1534
1535 fn escape_string_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1536 Self::check_args(&args, 1, "escapeStringYaml")?;
1537 let s = args[0].as_string()?;
1538
1539 let mut escaped = String::new();
1542 for ch in s.chars() {
1543 match ch {
1544 '"' => escaped.push_str("\\\""),
1545 '\\' => escaped.push_str("\\\\"),
1546 '\n' => escaped.push_str("\\n"),
1547 '\r' => escaped.push_str("\\r"),
1548 '\t' => escaped.push_str("\\t"),
1549 '\0' => escaped.push_str("\\0"),
1550 _ => escaped.push(ch),
1551 }
1552 }
1553
1554 let needs_quotes = s.contains(' ') || s.contains('\t') || s.contains('\n') ||
1556 s.contains(':') || s.contains('#') || s.contains('-') ||
1557 s.starts_with('[') || s.starts_with('{') ||
1558 s.starts_with('"') || s.starts_with('\'');
1559
1560 if needs_quotes {
1561 Ok(JsonnetValue::string(format!("\"{}\"", escaped)))
1562 } else {
1563 Ok(JsonnetValue::string(escaped))
1564 }
1565 }
1566
1567 fn escape_string_python(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1568 Self::check_args(&args, 1, "escapeStringPython")?;
1569 let s = args[0].as_string()?;
1570 let escaped = s.escape_default().to_string();
1571 Ok(JsonnetValue::string(format!("'{}'", escaped)))
1572 }
1573
1574 fn escape_string_bash(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1575 Self::check_args(&args, 1, "escapeStringBash")?;
1576 let s = args[0].as_string()?;
1577 let escaped = s.replace("'", "'\"'\"'").replace("\\", "\\\\");
1578 Ok(JsonnetValue::string(format!("'{}'", escaped)))
1579 }
1580
1581 fn escape_string_dollars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1582 Self::check_args(&args, 1, "escapeStringDollars")?;
1583 let s = args[0].as_string()?;
1584 let escaped = s.replace("$$", "$").replace("$", "$$");
1585 Ok(JsonnetValue::string(escaped))
1586 }
1587
1588 fn string_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1590 Self::check_args(&args, 1, "stringChars")?;
1591 let s = args[0].as_string()?;
1592 let chars: Vec<JsonnetValue> = s.chars().map(|c| JsonnetValue::string(c.to_string())).collect();
1593 Ok(JsonnetValue::array(chars))
1594 }
1595
1596 fn string_bytes(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1597 Self::check_args(&args, 1, "stringBytes")?;
1598 let s = args[0].as_string()?;
1599 let bytes: Vec<JsonnetValue> = s.as_bytes().iter().map(|&b| JsonnetValue::number(b as f64)).collect();
1600 Ok(JsonnetValue::array(bytes))
1601 }
1602
1603 fn format(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1604 Self::check_args(&args, 2, "format")?;
1605 let format_str = args[0].as_string()?;
1606 let values = args[1].as_array()?;
1607
1608 let mut result = format_str.to_string();
1610 for (i, value) in values.iter().enumerate() {
1611 let placeholder = format!("%{}", i + 1);
1612 let value_str = match value {
1613 JsonnetValue::String(s) => s.clone(),
1614 JsonnetValue::Number(n) => n.to_string(),
1615 JsonnetValue::Boolean(b) => b.to_string(),
1616 _ => value.to_string(),
1617 };
1618 result = result.replace(&placeholder, &value_str);
1619 }
1620
1621 Ok(JsonnetValue::string(result))
1622 }
1623
1624 fn is_array(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1626 Self::check_args(&args, 1, "isArray")?;
1627 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Array(_))))
1628 }
1629
1630 fn is_boolean(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1631 Self::check_args(&args, 1, "isBoolean")?;
1632 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Boolean(_))))
1633 }
1634
1635 fn is_function(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1636 Self::check_args(&args, 1, "isFunction")?;
1637 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Function(_))))
1638 }
1639
1640 fn is_number(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1641 Self::check_args(&args, 1, "isNumber")?;
1642 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Number(_))))
1643 }
1644
1645 fn is_object(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1646 Self::check_args(&args, 1, "isObject")?;
1647 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Object(_))))
1648 }
1649
1650 fn is_string(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1651 Self::check_args(&args, 1, "isString")?;
1652 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::String(_))))
1653 }
1654
1655 fn count(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1657 Self::check_args(&args, 2, "count")?;
1658 let arr = args[0].as_array()?;
1659 let elem = &args[1];
1660 let count = arr.iter().filter(|item| item.equals(elem)).count() as f64;
1661 Ok(JsonnetValue::number(count))
1662 }
1663
1664 fn find(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1665 Self::check_args(&args, 2, "find")?;
1666 match (&args[0], &args[1]) {
1667 (JsonnetValue::Array(arr), value) => {
1668 let mut indices = Vec::new();
1669 for (i, item) in arr.iter().enumerate() {
1670 if item == value {
1671 indices.push(JsonnetValue::Number(i as f64));
1672 }
1673 }
1674 Ok(JsonnetValue::array(indices))
1675 }
1676 _ => Err(JsonnetError::runtime_error("find expects array and search value")),
1677 }
1678 }
1679
1680 fn member(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1681 Self::contains(args)
1682 }
1683
1684 fn modulo(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1686 Self::check_args(&args, 2, "modulo")?;
1687 let a = args[0].as_number()?;
1688 let b = args[1].as_number()?;
1689 if b == 0.0 {
1690 return Err(JsonnetError::DivisionByZero);
1691 }
1692 Ok(JsonnetValue::number(a % b))
1693 }
1694
1695 fn pow(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1696 Self::check_args(&args, 2, "pow")?;
1697 let a = args[0].as_number()?;
1698 let b = args[1].as_number()?;
1699 Ok(JsonnetValue::number(a.powf(b)))
1700 }
1701
1702 fn exp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1703 Self::check_args(&args, 1, "exp")?;
1704 let x = args[0].as_number()?;
1705 Ok(JsonnetValue::number(x.exp()))
1706 }
1707
1708 fn log(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1709 Self::check_args(&args, 1, "log")?;
1710 let x = args[0].as_number()?;
1711 if x <= 0.0 {
1712 return Err(JsonnetError::runtime_error("log of non-positive number"));
1713 }
1714 Ok(JsonnetValue::number(x.ln()))
1715 }
1716
1717 fn sqrt(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1718 Self::check_args(&args, 1, "sqrt")?;
1719 let x = args[0].as_number()?;
1720 if x < 0.0 {
1721 return Err(JsonnetError::runtime_error("sqrt of negative number"));
1722 }
1723 Ok(JsonnetValue::number(x.sqrt()))
1724 }
1725
1726 fn sin(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1727 Self::check_args(&args, 1, "sin")?;
1728 let x = args[0].as_number()?;
1729 Ok(JsonnetValue::number(x.sin()))
1730 }
1731
1732 fn cos(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1733 Self::check_args(&args, 1, "cos")?;
1734 let x = args[0].as_number()?;
1735 Ok(JsonnetValue::number(x.cos()))
1736 }
1737
1738 fn tan(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1739 Self::check_args(&args, 1, "tan")?;
1740 let x = args[0].as_number()?;
1741 Ok(JsonnetValue::number(x.tan()))
1742 }
1743
1744 fn asin(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1745 Self::check_args(&args, 1, "asin")?;
1746 let x = args[0].as_number()?;
1747 Ok(JsonnetValue::number(x.asin()))
1748 }
1749
1750 fn acos(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1751 Self::check_args(&args, 1, "acos")?;
1752 let x = args[0].as_number()?;
1753 Ok(JsonnetValue::number(x.acos()))
1754 }
1755
1756 fn atan(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1757 Self::check_args(&args, 1, "atan")?;
1758 let x = args[0].as_number()?;
1759 Ok(JsonnetValue::number(x.atan()))
1760 }
1761
1762 fn floor(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1763 Self::check_args(&args, 1, "floor")?;
1764 let x = args[0].as_number()?;
1765 Ok(JsonnetValue::number(x.floor()))
1766 }
1767
1768 fn ceil(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1769 Self::check_args(&args, 1, "ceil")?;
1770 let x = args[0].as_number()?;
1771 Ok(JsonnetValue::number(x.ceil()))
1772 }
1773
1774 fn round(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1775 Self::check_args(&args, 1, "round")?;
1776 let x = args[0].as_number()?;
1777 Ok(JsonnetValue::number(x.round()))
1778 }
1779
1780 fn abs(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1781 Self::check_args(&args, 1, "abs")?;
1782 let x = args[0].as_number()?;
1783 Ok(JsonnetValue::number(x.abs()))
1784 }
1785
1786 fn max(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1787 Self::check_args(&args, 1, "max")?;
1788 let arr = args[0].as_array()?;
1789 if arr.is_empty() {
1790 return Err(JsonnetError::runtime_error("max() called on empty array"));
1791 }
1792 let mut max_val = f64::NEG_INFINITY;
1793 for item in arr {
1794 let val = item.as_number()?;
1795 if val > max_val {
1796 max_val = val;
1797 }
1798 }
1799 Ok(JsonnetValue::number(max_val))
1800 }
1801
1802 fn min(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1803 Self::check_args(&args, 1, "min")?;
1804 let arr = args[0].as_array()?;
1805 if arr.is_empty() {
1806 return Err(JsonnetError::runtime_error("min() called on empty array"));
1807 }
1808 let mut min_val = f64::INFINITY;
1809 for item in arr {
1810 let val = item.as_number()?;
1811 if val < min_val {
1812 min_val = val;
1813 }
1814 }
1815 Ok(JsonnetValue::number(min_val))
1816 }
1817
1818 fn clamp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1819 Self::check_args(&args, 3, "clamp")?;
1820 let x = args[0].as_number()?;
1821 let min = args[1].as_number()?;
1822 let max = args[2].as_number()?;
1823 let clamped = x.max(min).min(max);
1824 Ok(JsonnetValue::number(clamped))
1825 }
1826
1827 fn assert_equal(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1828 Self::check_args(&args, 2, "assertEqual")?;
1829 if !args[0].equals(&args[1]) {
1830 return Err(JsonnetError::assertion_failed(format!(
1831 "Assertion failed: {} != {}\n Left: {:?}\n Right: {:?}",
1832 args[0], args[1], args[0], args[1]
1833 )));
1834 }
1835 Ok(JsonnetValue::boolean(true))
1836 }
1837
1838 fn trace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1839 Self::check_args(&args, 2, "trace")?;
1840 eprintln!("TRACE: {:?}", args[1]);
1842 Ok(args[0].clone())
1844 }
1845
1846 fn sort(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1848 Self::check_args(&args, 1, "sort")?;
1849 let arr = args[0].as_array()?;
1850
1851 if arr.is_empty() {
1852 return Ok(JsonnetValue::array(vec![]));
1853 }
1854
1855 let mut sorted = arr.clone();
1858 sorted.sort_by(|a, b| Self::compare_values(a, b));
1859
1860 Ok(JsonnetValue::array(sorted))
1861 }
1862
1863 fn compare_values(a: &JsonnetValue, b: &JsonnetValue) -> std::cmp::Ordering {
1864 match (a, b) {
1865 (JsonnetValue::Null, JsonnetValue::Null) => std::cmp::Ordering::Equal,
1866 (JsonnetValue::Null, _) => std::cmp::Ordering::Less,
1867 (_, JsonnetValue::Null) => std::cmp::Ordering::Greater,
1868 (JsonnetValue::Boolean(x), JsonnetValue::Boolean(y)) => x.cmp(y),
1869 (JsonnetValue::Boolean(_), _) => std::cmp::Ordering::Less,
1870 (_, JsonnetValue::Boolean(_)) => std::cmp::Ordering::Greater,
1871 (JsonnetValue::Number(x), JsonnetValue::Number(y)) => {
1872 x.partial_cmp(y).unwrap_or(std::cmp::Ordering::Equal)
1873 }
1874 (JsonnetValue::Number(_), _) => std::cmp::Ordering::Less,
1875 (_, JsonnetValue::Number(_)) => std::cmp::Ordering::Greater,
1876 (JsonnetValue::String(x), JsonnetValue::String(y)) => x.cmp(y),
1877 (JsonnetValue::String(_), _) => std::cmp::Ordering::Less,
1878 (_, JsonnetValue::String(_)) => std::cmp::Ordering::Greater,
1879 (JsonnetValue::Array(x), JsonnetValue::Array(y)) => {
1880 for (_i, (a_item, b_item)) in x.iter().zip(y.iter()).enumerate() {
1881 let cmp = Self::compare_values(a_item, b_item);
1882 if cmp != std::cmp::Ordering::Equal {
1883 return cmp;
1884 }
1885 }
1886 x.len().cmp(&y.len())
1887 }
1888 (JsonnetValue::Array(_), _) => std::cmp::Ordering::Less,
1889 (_, JsonnetValue::Array(_)) => std::cmp::Ordering::Greater,
1890 (JsonnetValue::Object(x), JsonnetValue::Object(y)) => {
1891 let mut x_keys: Vec<_> = x.keys().collect();
1893 let mut y_keys: Vec<_> = y.keys().collect();
1894 x_keys.sort();
1895 y_keys.sort();
1896
1897 for (x_key, y_key) in x_keys.iter().zip(y_keys.iter()) {
1898 let key_cmp = x_key.cmp(y_key);
1899 if key_cmp != std::cmp::Ordering::Equal {
1900 return key_cmp;
1901 }
1902 if let (Some(x_val), Some(y_val)) = (x.get(*x_key), y.get(*y_key)) {
1903 let val_cmp = Self::compare_values(x_val, y_val);
1904 if val_cmp != std::cmp::Ordering::Equal {
1905 return val_cmp;
1906 }
1907 }
1908 }
1909 x.len().cmp(&y.len())
1910 }
1911 _ => std::cmp::Ordering::Equal, }
1913 }
1914
1915 fn uniq(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1916 Self::check_args(&args, 1, "uniq")?;
1917 let arr = args[0].as_array()?;
1918
1919 let mut result: Vec<JsonnetValue> = Vec::new();
1920 for item in arr {
1921 let mut found = false;
1923 for existing in &result {
1924 if existing.equals(item) {
1925 found = true;
1926 break;
1927 }
1928 }
1929 if !found {
1930 result.push(item.clone());
1931 }
1932 }
1933
1934 Ok(JsonnetValue::array(result))
1935 }
1936
1937 fn reverse(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1938 Self::check_args(&args, 1, "reverse")?;
1939 let arr = args[0].as_array()?;
1940 let reversed: Vec<JsonnetValue> = arr.iter().rev().cloned().collect();
1941 Ok(JsonnetValue::array(reversed))
1942 }
1943
1944 fn merge_patch(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1946 Self::check_args(&args, 2, "mergePatch")?;
1947 let target = args[0].as_object()?;
1948 let patch = args[1].as_object()?;
1949
1950 let mut result = target.clone();
1951
1952 for (key, patch_value) in patch {
1953 match patch_value {
1954 JsonnetValue::Null => {
1955 result.remove(key);
1957 }
1958 JsonnetValue::Object(patch_obj) => {
1959 if let Some(JsonnetValue::Object(target_obj)) = result.get(key) {
1961 let merged = Self::merge_patch(vec![
1962 JsonnetValue::object(target_obj.clone()),
1963 JsonnetValue::object(patch_obj.clone())
1964 ])?;
1965 if let JsonnetValue::Object(merged_obj) = merged {
1966 result.insert(key.clone(), JsonnetValue::object(merged_obj));
1967 }
1968 } else {
1969 result.insert(key.clone(), JsonnetValue::object(patch_obj.clone()));
1971 }
1972 }
1973 _ => {
1974 result.insert(key.clone(), patch_value.clone());
1976 }
1977 }
1978 }
1979
1980 Ok(JsonnetValue::object(result))
1981 }
1982
1983 fn get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1984 Self::check_args(&args, 3, "get")?;
1985 let obj = args[0].as_object()?;
1986 let key = args[1].as_string()?;
1987 let default = &args[2];
1988 Ok(obj.get(key).unwrap_or(default).clone())
1989 }
1990
1991 fn object_fields(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1992 Self::check_args(&args, 1, "objectFields")?;
1993 let obj = args[0].as_object()?;
1994 let fields: Vec<JsonnetValue> = obj.keys()
1995 .filter(|&k| !k.starts_with('_')) .map(|k| JsonnetValue::string(k.clone()))
1997 .collect();
1998 Ok(JsonnetValue::array(fields))
1999 }
2000
2001 fn object_fields_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2002 Self::check_args(&args, 1, "objectFieldsAll")?;
2003 let obj = args[0].as_object()?;
2004 let fields: Vec<JsonnetValue> = obj.keys()
2005 .map(|k| JsonnetValue::string(k.clone()))
2006 .collect();
2007 Ok(JsonnetValue::array(fields))
2008 }
2009
2010 fn object_has(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2011 Self::check_args(&args, 2, "objectHas")?;
2012 let obj = args[0].as_object()?;
2013 let key = args[1].as_string()?;
2014 Ok(JsonnetValue::boolean(obj.contains_key(key) && !key.starts_with('_')))
2015 }
2016
2017 fn object_has_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2018 Self::check_args(&args, 2, "objectHasAll")?;
2019 let obj = args[0].as_object()?;
2020 let key = args[1].as_string()?;
2021 Ok(JsonnetValue::boolean(obj.contains_key(key)))
2022 }
2023
2024 fn object_values(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2025 Self::check_args(&args, 1, "objectValues")?;
2026 let obj = args[0].as_object()?;
2027 let values: Vec<JsonnetValue> = obj.iter()
2028 .filter(|(k, _)| !k.starts_with('_'))
2029 .map(|(_, v)| v.clone())
2030 .collect();
2031 Ok(JsonnetValue::array(values))
2032 }
2033
2034 fn object_values_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2035 Self::check_args(&args, 1, "objectValuesAll")?;
2036 let obj = args[0].as_object()?;
2037 let values: Vec<JsonnetValue> = obj.values().cloned().collect();
2038 Ok(JsonnetValue::array(values))
2039 }
2040
2041 fn prune(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2042 Self::check_args(&args, 1, "prune")?;
2043 Self::prune_value(&args[0])
2044 }
2045
2046 fn prune_value(value: &JsonnetValue) -> Result<JsonnetValue> {
2047 match value {
2048 JsonnetValue::Null => Ok(JsonnetValue::Null),
2049 JsonnetValue::Array(arr) => {
2050 let pruned: Vec<JsonnetValue> = arr.iter()
2051 .map(|item| Self::prune_value(item))
2052 .collect::<Result<Vec<_>>>()?
2053 .into_iter()
2054 .filter(|item| !matches!(item, JsonnetValue::Null))
2055 .collect();
2056 Ok(JsonnetValue::array(pruned))
2057 }
2058 JsonnetValue::Object(obj) => {
2059 let mut pruned_obj = HashMap::new();
2060 for (key, val) in obj {
2061 let pruned_val = Self::prune_value(val)?;
2062 if !matches!(pruned_val, JsonnetValue::Null) {
2063 pruned_obj.insert(key.clone(), pruned_val);
2064 }
2065 }
2066 Ok(JsonnetValue::object(pruned_obj))
2067 }
2068 _ => Ok(value.clone()),
2069 }
2070 }
2071
2072 fn map_with_key(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2073 Self::check_args(&args, 2, "mapWithKey")?;
2074 let _func = &args[0];
2075 let obj = args[1].as_object()?;
2076
2077 let mut result = HashMap::new();
2080 for (key, value) in obj {
2081 if !key.starts_with('_') {
2082 result.insert(key.clone(), JsonnetValue::array(vec![
2085 JsonnetValue::string(key.clone()),
2086 value.clone()
2087 ]));
2088 }
2089 }
2090
2091 Ok(JsonnetValue::object(result))
2092 }
2093
2094 fn object_fields_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2095 Self::check_args(&args, 2, "objectFieldsEx")?;
2096 let obj = args[0].as_object()?;
2097 let include_hidden = args[1].as_boolean()?;
2098
2099 let fields: Vec<JsonnetValue> = obj.keys()
2100 .filter(|&k| include_hidden || !k.starts_with('_'))
2101 .map(|k| JsonnetValue::string(k.clone()))
2102 .collect();
2103
2104 Ok(JsonnetValue::array(fields))
2105 }
2106
2107 fn object_values_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2108 Self::check_args(&args, 2, "objectValuesEx")?;
2109 let obj = args[0].as_object()?;
2110 let include_hidden = args[1].as_boolean()?;
2111
2112 let values: Vec<JsonnetValue> = obj.iter()
2113 .filter(|(k, _)| include_hidden || !k.starts_with('_'))
2114 .map(|(_, v)| v.clone())
2115 .collect();
2116
2117 Ok(JsonnetValue::array(values))
2118 }
2119
2120 fn to_lower(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2121 Self::check_args(&args, 1, "toLower")?;
2122 match &args[0] {
2123 JsonnetValue::String(s) => Ok(JsonnetValue::string(s.to_lowercase())),
2124 _ => Err(JsonnetError::runtime_error("toLower expects a string argument")),
2125 }
2126 }
2127
2128 fn to_upper(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2129 Self::check_args(&args, 1, "toUpper")?;
2130 match &args[0] {
2131 JsonnetValue::String(s) => Ok(JsonnetValue::string(s.to_uppercase())),
2132 _ => Err(JsonnetError::runtime_error("toUpper expects a string argument")),
2133 }
2134 }
2135
2136 fn trim(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2137 Self::check_args(&args, 1, "trim")?;
2138 match &args[0] {
2139 JsonnetValue::String(s) => Ok(JsonnetValue::string(s.trim().to_string())),
2140 _ => Err(JsonnetError::runtime_error("trim expects a string argument")),
2141 }
2142 }
2143
2144 fn all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2145 Self::check_args(&args, 1, "all")?;
2146 match &args[0] {
2147 JsonnetValue::Array(arr) => {
2148 let result = arr.iter().all(|item| item.is_truthy());
2149 Ok(JsonnetValue::boolean(result))
2150 }
2151 _ => Err(JsonnetError::runtime_error("all expects an array argument")),
2152 }
2153 }
2154
2155 fn any(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2156 Self::check_args(&args, 1, "any")?;
2157 match &args[0] {
2158 JsonnetValue::Array(arr) => {
2159 let result = arr.iter().any(|item| item.is_truthy());
2160 Ok(JsonnetValue::boolean(result))
2161 }
2162 _ => Err(JsonnetError::runtime_error("any expects an array argument")),
2163 }
2164 }
2165
2166 fn id(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2167 Self::check_args(&args, 1, "id")?;
2168 Ok(args[0].clone())
2169 }
2170
2171 fn equals(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2172 Self::check_args(&args, 2, "equals")?;
2173 let a = &args[0];
2174 let b = &args[1];
2175
2176 if a == b {
2178 return Ok(JsonnetValue::boolean(true));
2179 }
2180
2181 let ta = a.type_name();
2183 let tb = b.type_name();
2184 if ta != tb {
2185 return Ok(JsonnetValue::boolean(false));
2186 }
2187
2188 match (a, b) {
2189 (JsonnetValue::Array(arr_a), JsonnetValue::Array(arr_b)) => {
2190 if arr_a.len() != arr_b.len() {
2191 return Ok(JsonnetValue::boolean(false));
2192 }
2193 for (i, item_a) in arr_a.iter().enumerate() {
2194 let eq_args = vec![item_a.clone(), arr_b[i].clone()];
2195 if let Ok(JsonnetValue::Boolean(false)) = Self::equals(eq_args) {
2196 return Ok(JsonnetValue::boolean(false));
2197 }
2198 }
2199 Ok(JsonnetValue::boolean(true))
2200 }
2201 (JsonnetValue::Object(obj_a), JsonnetValue::Object(obj_b)) => {
2202 let fields_a: Vec<String> = obj_a.keys().cloned().collect();
2204 let fields_b: Vec<String> = obj_b.keys().cloned().collect();
2205
2206 if fields_a.len() != fields_b.len() {
2207 return Ok(JsonnetValue::boolean(false));
2208 }
2209
2210 let mut sorted_a = fields_a.clone();
2212 sorted_a.sort();
2213 let mut sorted_b = fields_b.clone();
2214 sorted_b.sort();
2215
2216 if sorted_a != sorted_b {
2217 return Ok(JsonnetValue::boolean(false));
2218 }
2219
2220 for field in sorted_a {
2222 let val_a = &obj_a[&field];
2223 let val_b = &obj_b[&field];
2224 let eq_args = vec![val_a.clone(), val_b.clone()];
2225 if let Ok(JsonnetValue::Boolean(false)) = Self::equals(eq_args) {
2226 return Ok(JsonnetValue::boolean(false));
2227 }
2228 }
2229 Ok(JsonnetValue::boolean(true))
2230 }
2231 _ => Ok(JsonnetValue::boolean(false)),
2232 }
2233 }
2234
2235 fn lines(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2236 Self::check_args(&args, 1, "lines")?;
2237 match &args[0] {
2238 JsonnetValue::Array(arr) => {
2239 let mut lines = Vec::new();
2240 for item in arr {
2241 match item {
2243 JsonnetValue::String(s) => lines.push(s.clone()),
2244 JsonnetValue::Number(n) => lines.push(n.to_string()),
2245 JsonnetValue::Boolean(b) => lines.push(b.to_string()),
2246 _ => lines.push(format!("{}", item)),
2247 }
2248 }
2249 lines.push("".to_string()); Ok(JsonnetValue::string(lines.join("\n")))
2251 }
2252 _ => Err(JsonnetError::runtime_error("lines expects an array argument")),
2253 }
2254 }
2255
2256 fn str_replace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2257 Self::check_args(&args, 3, "strReplace")?;
2258
2259 let str_val = &args[0];
2260 let from_val = &args[1];
2261 let to_val = &args[2];
2262
2263 let str = str_val.as_string()?.to_string();
2264 let from = from_val.as_string()?.to_string();
2265 let to = to_val.as_string()?.to_string();
2266
2267 if from.is_empty() {
2268 return Err(JsonnetError::runtime_error("'from' string must not be zero length"));
2269 }
2270
2271 let result = str.replace(&from, &to);
2275 Ok(JsonnetValue::string(result))
2276 }
2277
2278 fn sha1(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2279 Self::check_args(&args, 1, "sha1")?;
2280 let input = args[0].as_string()?.as_bytes();
2281 let mut hasher = Sha1::new();
2282 hasher.update(input);
2283 let result = hasher.finalize();
2284 Ok(JsonnetValue::string(hex::encode(result)))
2285 }
2286
2287 fn sha256(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2288 Self::check_args(&args, 1, "sha256")?;
2289 let input = args[0].as_string()?.as_bytes();
2290 let mut hasher = Sha256::new();
2291 hasher.update(input);
2292 let result = hasher.finalize();
2293 Ok(JsonnetValue::string(hex::encode(result)))
2294 }
2295
2296 fn sha3(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2297 Self::check_args(&args, 1, "sha3")?;
2298 let input = args[0].as_string()?.as_bytes();
2299 let mut hasher = Sha3_256::new();
2300 hasher.update(input);
2301 let result = hasher.finalize();
2302 Ok(JsonnetValue::string(hex::encode(result)))
2303 }
2304
2305 fn sha512(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2306 Self::check_args(&args, 1, "sha512")?;
2307 let input = args[0].as_string()?.as_bytes();
2308 let mut hasher = Sha512::new();
2309 hasher.update(input);
2310 let result = hasher.finalize();
2311 Ok(JsonnetValue::string(hex::encode(result)))
2312 }
2313
2314 fn ascii_lower(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2315 Self::check_args(&args, 1, "asciiLower")?;
2316 let input = args[0].as_string()?;
2317 Ok(JsonnetValue::string(input.to_ascii_lowercase()))
2318 }
2319
2320 fn ascii_upper(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2321 Self::check_args(&args, 1, "asciiUpper")?;
2322 let input = args[0].as_string()?;
2323 Ok(JsonnetValue::string(input.to_ascii_uppercase()))
2324 }
2325
2326 fn flat_map(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2327 Self::check_args(&args, 2, "flatMap")?;
2328 let _func = &args[0];
2329 let arr = &args[1];
2330
2331 match arr {
2332 JsonnetValue::Array(array) => {
2333 let mut result = Vec::new();
2334 for item in array {
2335 if let JsonnetValue::Array(sub_array) = item {
2339 result.extend(sub_array.clone());
2340 } else {
2341 result.push(item.clone());
2342 }
2343 }
2344 Ok(JsonnetValue::array(result))
2345 }
2346 JsonnetValue::String(s) => {
2347 let mut result = Vec::new();
2349 for ch in s.chars() {
2350 result.push(JsonnetValue::string(ch.to_string()));
2352 }
2353 Ok(JsonnetValue::array(result))
2354 }
2355 _ => Err(JsonnetError::runtime_error("flatMap expects array or string as second argument")),
2356 }
2357 }
2358
2359 fn map_with_index(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2360 Self::check_args(&args, 2, "mapWithIndex")?;
2361 let _func = &args[0];
2362 let arr = &args[1];
2363
2364 match arr {
2365 JsonnetValue::Array(array) => {
2366 let mut result = Vec::new();
2367 for (i, item) in array.iter().enumerate() {
2368 result.push(JsonnetValue::array(vec![JsonnetValue::number(i as f64), item.clone()]));
2371 }
2372 Ok(JsonnetValue::array(result))
2373 }
2374 JsonnetValue::String(s) => {
2375 let mut result = Vec::new();
2376 for (i, ch) in s.chars().enumerate() {
2377 result.push(JsonnetValue::array(vec![
2378 JsonnetValue::number(i as f64),
2379 JsonnetValue::string(ch.to_string())
2380 ]));
2381 }
2382 Ok(JsonnetValue::array(result))
2383 }
2384 _ => Err(JsonnetError::runtime_error("mapWithIndex expects array or string as second argument")),
2385 }
2386 }
2387
2388 fn lstrip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2389 Self::check_args(&args, 2, "lstripChars")?;
2390 let str_val = args[0].as_string()?;
2391 let chars_val = args[1].as_string()?;
2392
2393 let chars_set: std::collections::HashSet<char> = chars_val.chars().collect();
2394 let result: String = str_val.chars()
2395 .skip_while(|c| chars_set.contains(c))
2396 .collect();
2397
2398 Ok(JsonnetValue::string(result))
2399 }
2400
2401 fn rstrip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2402 Self::check_args(&args, 2, "rstripChars")?;
2403 let str_val = args[0].as_string()?;
2404 let chars_val = args[1].as_string()?;
2405
2406 let chars_set: std::collections::HashSet<char> = chars_val.chars().collect();
2407 let result: String = str_val.chars()
2408 .rev()
2409 .skip_while(|c| chars_set.contains(c))
2410 .collect::<Vec<char>>()
2411 .into_iter()
2412 .rev()
2413 .collect();
2414
2415 Ok(JsonnetValue::string(result))
2416 }
2417
2418 fn strip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2419 Self::check_args(&args, 2, "stripChars")?;
2420 let str_val = &args[0];
2421 let chars_val = &args[1];
2422
2423 let lstripped_args = vec![str_val.clone(), chars_val.clone()];
2425 let lstripped = Self::lstrip_chars(lstripped_args)?;
2426 let rstripped_args = vec![lstripped, chars_val.clone()];
2427 Self::rstrip_chars(rstripped_args)
2428 }
2429
2430 fn find_substr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2431 Self::check_args(&args, 2, "findSubstr")?;
2432 let pat = args[0].as_string()?;
2433 let str = args[1].as_string()?;
2434
2435 if pat.is_empty() {
2436 return Err(JsonnetError::runtime_error("findSubstr pattern cannot be empty"));
2437 }
2438
2439 let mut result = Vec::new();
2440 let mut start = 0;
2441
2442 while let Some(pos) = str[start..].find(&pat) {
2443 result.push(JsonnetValue::number((start + pos) as f64));
2444 start += pos + pat.len();
2445 }
2446
2447 Ok(JsonnetValue::array(result))
2448 }
2449
2450 fn repeat(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2451 Self::check_args(&args, 2, "repeat")?;
2452 let what = &args[0];
2453 let count_val = &args[1];
2454
2455 let count = if let JsonnetValue::Number(n) = count_val {
2456 *n as usize
2457 } else {
2458 return Err(JsonnetError::runtime_error("repeat count must be a number"));
2459 };
2460
2461 match what {
2462 JsonnetValue::String(s) => {
2463 let repeated = s.repeat(count);
2464 Ok(JsonnetValue::string(repeated))
2465 }
2466 JsonnetValue::Array(arr) => {
2467 let mut result = Vec::new();
2468 for _ in 0..count {
2469 result.extend(arr.clone());
2470 }
2471 Ok(JsonnetValue::array(result))
2472 }
2473 _ => Err(JsonnetError::runtime_error("repeat first argument must be string or array")),
2474 }
2475 }
2476
2477 fn set(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2478 Self::check_args(&args, 1, "set")?;
2479 match &args[0] {
2480 JsonnetValue::Array(arr) => {
2481 let mut result = Vec::new();
2483
2484 for item in arr {
2485 let mut found = false;
2487 for existing in &result {
2488 if existing == item {
2489 found = true;
2490 break;
2491 }
2492 }
2493 if !found {
2494 result.push(item.clone());
2495 }
2496 }
2497
2498 Ok(JsonnetValue::array(result))
2499 }
2500 _ => Err(JsonnetError::runtime_error("set expects an array argument")),
2501 }
2502 }
2503
2504 fn set_member(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2505 Self::check_args(&args, 2, "setMember")?;
2506 let value = &args[0];
2507 let arr = match &args[1] {
2508 JsonnetValue::Array(a) => a,
2509 _ => return Err(JsonnetError::runtime_error("setMember expects array as second argument")),
2510 };
2511
2512 for item in arr {
2513 if item == value {
2514 return Ok(JsonnetValue::boolean(true));
2515 }
2516 }
2517 Ok(JsonnetValue::boolean(false))
2518 }
2519
2520 fn set_union(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2521 Self::check_args(&args, 2, "setUnion")?;
2522 let arr_a = match &args[0] {
2523 JsonnetValue::Array(a) => a,
2524 _ => return Err(JsonnetError::runtime_error("setUnion expects arrays as arguments")),
2525 };
2526 let arr_b = match &args[1] {
2527 JsonnetValue::Array(a) => a,
2528 _ => return Err(JsonnetError::runtime_error("setUnion expects arrays as arguments")),
2529 };
2530
2531 let mut result = Vec::new();
2532
2533 for item in arr_a {
2535 let mut found = false;
2536 for existing in &result {
2537 if existing == item {
2538 found = true;
2539 break;
2540 }
2541 }
2542 if !found {
2543 result.push(item.clone());
2544 }
2545 }
2546
2547 for item in arr_b {
2549 let mut found = false;
2550 for existing in &result {
2551 if existing == item {
2552 found = true;
2553 break;
2554 }
2555 }
2556 if !found {
2557 result.push(item.clone());
2558 }
2559 }
2560
2561 Ok(JsonnetValue::array(result))
2562 }
2563
2564 fn set_inter(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2565 Self::check_args(&args, 2, "setInter")?;
2566 let arr_a = match &args[0] {
2567 JsonnetValue::Array(a) => a,
2568 _ => return Err(JsonnetError::runtime_error("setInter expects arrays as arguments")),
2569 };
2570 let arr_b = match &args[1] {
2571 JsonnetValue::Array(a) => a,
2572 _ => return Err(JsonnetError::runtime_error("setInter expects arrays as arguments")),
2573 };
2574
2575 let mut result = Vec::new();
2576
2577 for item_a in arr_a {
2578 let mut found_in_b = false;
2580 for item_b in arr_b {
2581 if item_a == item_b {
2582 found_in_b = true;
2583 break;
2584 }
2585 }
2586
2587 if found_in_b {
2588 let mut already_in_result = false;
2590 for existing in &result {
2591 if existing == item_a {
2592 already_in_result = true;
2593 break;
2594 }
2595 }
2596 if !already_in_result {
2597 result.push(item_a.clone());
2598 }
2599 }
2600 }
2601
2602 Ok(JsonnetValue::array(result))
2603 }
2604
2605 fn set_diff(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2606 Self::check_args(&args, 2, "setDiff")?;
2607 let arr_a = match &args[0] {
2608 JsonnetValue::Array(a) => a,
2609 _ => return Err(JsonnetError::runtime_error("setDiff expects arrays as arguments")),
2610 };
2611 let arr_b = match &args[1] {
2612 JsonnetValue::Array(a) => a,
2613 _ => return Err(JsonnetError::runtime_error("setDiff expects arrays as arguments")),
2614 };
2615
2616 let mut result = Vec::new();
2617
2618 for item_a in arr_a {
2619 let mut found_in_b = false;
2621 for item_b in arr_b {
2622 if item_a == item_b {
2623 found_in_b = true;
2624 break;
2625 }
2626 }
2627
2628 if !found_in_b {
2629 let mut already_in_result = false;
2631 for existing in &result {
2632 if existing == item_a {
2633 already_in_result = true;
2634 break;
2635 }
2636 }
2637 if !already_in_result {
2638 result.push(item_a.clone());
2639 }
2640 }
2641 }
2642
2643 Ok(JsonnetValue::array(result))
2644 }
2645
2646 fn manifest_ini(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2650 Self::check_args(&args, 1, "manifestIni")?;
2651 match &args[0] {
2653 JsonnetValue::Object(obj) => {
2654 let mut result = String::new();
2655 for (key, value) in obj {
2656 if !key.starts_with('_') {
2657 result.push_str(&format!("[{}]\n", key));
2658 if let JsonnetValue::Object(section) = value {
2659 for (k, v) in section {
2660 if !k.starts_with('_') {
2661 result.push_str(&format!("{}={}\n", k, v));
2662 }
2663 }
2664 }
2665 result.push('\n');
2666 }
2667 }
2668 Ok(JsonnetValue::string(result.trim().to_string()))
2669 }
2670 _ => Err(JsonnetError::runtime_error("manifestIni expects an object")),
2671 }
2672 }
2673
2674 fn manifest_python(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2675 Self::check_args(&args, 1, "manifestPython")?;
2676 let json_str = serde_json::to_string(&args[0].to_json_value())?;
2678 let python_str = json_str
2680 .replace("null", "None")
2681 .replace("true", "True")
2682 .replace("false", "False");
2683 Ok(JsonnetValue::string(python_str))
2684 }
2685
2686 fn manifest_cpp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2687 Self::check_args(&args, 1, "manifestCpp")?;
2688 let json_str = serde_json::to_string(&args[0].to_json_value())?;
2690 let cpp_str = format!("// Generated C++ code\nconst char* jsonData = R\"json(\n{}\n)json\";", json_str);
2691 Ok(JsonnetValue::string(cpp_str))
2692 }
2693
2694 fn manifest_xml_jsonml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2695 Self::check_args(&args, 1, "manifestXmlJsonml")?;
2696 match &args[0] {
2698 JsonnetValue::Array(arr) if !arr.is_empty() => {
2699 if let JsonnetValue::String(tag) = &arr[0] {
2700 let mut xml = format!("<{}", tag);
2701
2702 let mut child_start = 1;
2704 if arr.len() > 1 {
2705 if let JsonnetValue::Object(attrs) = &arr[1] {
2706 for (key, value) in attrs {
2707 if !key.starts_with('_') {
2708 let value_str = match value {
2709 JsonnetValue::String(s) => s.clone(),
2710 _ => format!("{}", value),
2711 };
2712 xml.push_str(&format!(" {}=\"{}\"", key, value_str));
2713 }
2714 }
2715 child_start = 2;
2716 }
2717 }
2718
2719 xml.push('>');
2720
2721 for child in &arr[child_start..] {
2723 match child {
2724 JsonnetValue::String(s) => xml.push_str(s),
2725 JsonnetValue::Array(_) => {
2726 let child_xml = Self::manifest_xml_jsonml(vec![child.clone()])?;
2728 if let JsonnetValue::String(child_str) = child_xml {
2729 xml.push_str(&child_str);
2730 }
2731 }
2732 _ => xml.push_str(&format!("{}", child)),
2733 }
2734 }
2735
2736 xml.push_str(&format!("</{}>", tag));
2737 Ok(JsonnetValue::string(xml))
2738 } else {
2739 Err(JsonnetError::runtime_error("JsonML array must start with string tag name"))
2740 }
2741 }
2742 _ => Err(JsonnetError::runtime_error("manifestXmlJsonml expects a JsonML array")),
2743 }
2744 }
2745
2746 fn log2(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2748 Self::check_args(&args, 1, "log2")?;
2749 let x = args[0].as_number()?;
2750 if x <= 0.0 {
2751 return Err(JsonnetError::runtime_error("log2 of non-positive number"));
2752 }
2753 Ok(JsonnetValue::number(x.log2()))
2754 }
2755
2756 fn log10(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2757 Self::check_args(&args, 1, "log10")?;
2758 let x = args[0].as_number()?;
2759 if x <= 0.0 {
2760 return Err(JsonnetError::runtime_error("log10 of non-positive number"));
2761 }
2762 Ok(JsonnetValue::number(x.log10()))
2763 }
2764
2765 fn log1p(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2766 Self::check_args(&args, 1, "log1p")?;
2767 let x = args[0].as_number()?;
2768 if x < -1.0 {
2769 return Err(JsonnetError::runtime_error("log1p of number less than -1"));
2770 }
2771 Ok(JsonnetValue::number((x + 1.0).ln()))
2772 }
2773
2774 fn expm1(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2775 Self::check_args(&args, 1, "expm1")?;
2776 let x = args[0].as_number()?;
2777 Ok(JsonnetValue::number(x.exp() - 1.0))
2778 }
2779
2780 fn remove(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2784 Self::check_args(&args, 2, "remove")?;
2785 let arr = args[0].as_array()?;
2786 let value_to_remove = &args[1];
2787
2788 let filtered: Vec<JsonnetValue> = arr.iter()
2789 .filter(|item| !item.equals(value_to_remove))
2790 .cloned()
2791 .collect();
2792
2793 Ok(JsonnetValue::array(filtered))
2794 }
2795
2796 fn remove_at(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2797 Self::check_args(&args, 2, "removeAt")?;
2798 let arr = args[0].as_array()?;
2799 let index = args[1].as_number()? as usize;
2800
2801 if index >= arr.len() {
2802 return Err(JsonnetError::runtime_error("Index out of bounds"));
2803 }
2804
2805 let mut result = arr.clone();
2806 result.remove(index);
2807 Ok(JsonnetValue::array(result))
2808 }
2809
2810 fn flatten_arrays(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2811 Self::check_args(&args, 1, "flattenArrays")?;
2812 let arr = args[0].as_array()?;
2813
2814 let mut result = Vec::new();
2815 Self::flatten_array_recursive(arr, &mut result);
2816 Ok(JsonnetValue::array(result))
2817 }
2818
2819 fn flatten_array_recursive(arr: &[JsonnetValue], result: &mut Vec<JsonnetValue>) {
2820 for item in arr {
2821 match item {
2822 JsonnetValue::Array(sub_arr) => {
2823 Self::flatten_array_recursive(sub_arr, result);
2824 }
2825 _ => result.push(item.clone()),
2826 }
2827 }
2828 }
2829
2830 fn object_keys_values(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2832 Self::check_args(&args, 1, "objectKeysValues")?;
2833 let obj = args[0].as_object()?;
2834
2835 let mut result = Vec::new();
2836 for (key, value) in obj {
2837 if !key.starts_with('_') {
2838 result.push(JsonnetValue::object(HashMap::from([
2839 ("key".to_string(), JsonnetValue::string(key.clone())),
2840 ("value".to_string(), value.clone()),
2841 ])));
2842 }
2843 }
2844
2845 Ok(JsonnetValue::array(result))
2846 }
2847
2848 fn object_remove_key(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2849 Self::check_args(&args, 2, "objectRemoveKey")?;
2850 let obj = args[0].as_object()?;
2851 let key_to_remove = args[1].as_string()?;
2852
2853 let mut result = obj.clone();
2854 result.remove(key_to_remove);
2855 Ok(JsonnetValue::object(result))
2856 }
2857
2858 fn is_integer(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2860 Self::check_args(&args, 1, "isInteger")?;
2861 match &args[0] {
2862 JsonnetValue::Number(n) => Ok(JsonnetValue::boolean(n.fract() == 0.0)),
2863 _ => Ok(JsonnetValue::boolean(false)),
2864 }
2865 }
2866
2867 fn is_decimal(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2868 Self::check_args(&args, 1, "isDecimal")?;
2869 match &args[0] {
2870 JsonnetValue::Number(n) => Ok(JsonnetValue::boolean(n.fract() != 0.0)),
2871 _ => Ok(JsonnetValue::boolean(false)),
2872 }
2873 }
2874
2875 fn is_even(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2876 Self::check_args(&args, 1, "isEven")?;
2877 match &args[0] {
2878 JsonnetValue::Number(n) if n.fract() == 0.0 => {
2879 Ok(JsonnetValue::boolean((*n as i64) % 2 == 0))
2880 }
2881 _ => Ok(JsonnetValue::boolean(false)),
2882 }
2883 }
2884
2885 fn is_odd(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2886 Self::check_args(&args, 1, "isOdd")?;
2887 match &args[0] {
2888 JsonnetValue::Number(n) if n.fract() == 0.0 => {
2889 Ok(JsonnetValue::boolean((*n as i64) % 2 != 0))
2890 }
2891 _ => Ok(JsonnetValue::boolean(false)),
2892 }
2893 }
2894
2895 fn check_args(args: &[JsonnetValue], expected: usize, func_name: &str) -> Result<()> {
2897 if args.len() != expected {
2898 return Err(JsonnetError::invalid_function_call(format!(
2899 "{}() expects {} arguments, got {}",
2900 func_name, expected, args.len()
2901 )));
2902 }
2903 Ok(())
2904 }
2905
2906 fn check_args_range(args: &[JsonnetValue], min: usize, max: usize, func_name: &str) -> Result<()> {
2908 if args.len() < min || args.len() > max {
2909 return Err(JsonnetError::invalid_function_call(format!(
2910 "{}() expects {} to {} arguments, got {}",
2911 func_name, min, max, args.len()
2912 )));
2913 }
2914 Ok(())
2915 }
2916
2917 pub fn call_function(name: &str, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2919 Err(JsonnetError::runtime_error(format!("StdLib function '{}' not implemented", name)))
2922 }
2923}
2924
2925impl JsonnetValue {
2926 pub fn from_json_value(value: serde_json::Value) -> Self {
2928 match value {
2929 serde_json::Value::Null => JsonnetValue::Null,
2930 serde_json::Value::Bool(b) => JsonnetValue::boolean(b),
2931 serde_json::Value::Number(n) => JsonnetValue::number(n.as_f64().unwrap_or(0.0)),
2932 serde_json::Value::String(s) => JsonnetValue::string(s),
2933 serde_json::Value::Array(arr) => {
2934 let jsonnet_arr: Vec<JsonnetValue> = arr.into_iter()
2935 .map(JsonnetValue::from_json_value)
2936 .collect();
2937 JsonnetValue::array(jsonnet_arr)
2938 }
2939 serde_json::Value::Object(obj) => {
2940 let mut jsonnet_obj = HashMap::new();
2941 for (k, v) in obj {
2942 jsonnet_obj.insert(k, JsonnetValue::from_json_value(v));
2943 }
2944 JsonnetValue::object(jsonnet_obj)
2945 }
2946 }
2947 }
2948
2949 pub fn slice(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2953 StdLib::check_args(&args, 2, "slice")?;
2954 let start = args[1].as_number()? as usize;
2955
2956 match &args[0] {
2957 JsonnetValue::Array(arr) => {
2958 let end = if args.len() > 2 {
2959 args[2].as_number()? as usize
2960 } else {
2961 arr.len()
2962 };
2963 let start = start.min(arr.len());
2964 let end = end.min(arr.len());
2965 if start > end {
2966 Ok(JsonnetValue::array(vec![]))
2967 } else {
2968 Ok(JsonnetValue::array(arr[start..end].to_vec()))
2969 }
2970 }
2971 JsonnetValue::String(s) => {
2972 let end = if args.len() > 2 {
2973 args[2].as_number()? as usize
2974 } else {
2975 s.chars().count()
2976 };
2977 let chars: Vec<char> = s.chars().collect();
2978 let start = start.min(chars.len());
2979 let end = end.min(chars.len());
2980 if start > end {
2981 Ok(JsonnetValue::string("".to_string()))
2982 } else {
2983 let sliced: String = chars[start..end].iter().collect();
2984 Ok(JsonnetValue::string(sliced))
2985 }
2986 }
2987 _ => Err(JsonnetError::invalid_function_call("slice() expects array or string as first argument".to_string())),
2988 }
2989 }
2990
2991 pub fn zip(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2993 if args.is_empty() {
2994 return Err(JsonnetError::invalid_function_call("zip() expects at least one argument".to_string()));
2995 }
2996
2997 let arrays: Result<Vec<Vec<JsonnetValue>>> = args.into_iter()
2999 .map(|arg| arg.as_array().cloned())
3000 .collect();
3001
3002 let arrays = arrays?;
3003 if arrays.is_empty() {
3004 return Ok(JsonnetValue::array(vec![]));
3005 }
3006
3007 let min_len = arrays.iter().map(|arr| arr.len()).min().unwrap_or(0);
3009
3010 let mut result = Vec::new();
3012 for i in 0..min_len {
3013 let mut tuple = Vec::new();
3014 for arr in &arrays {
3015 tuple.push(arr[i].clone());
3016 }
3017 result.push(JsonnetValue::array(tuple));
3018 }
3019
3020 Ok(JsonnetValue::array(result))
3021 }
3022
3023 pub fn transpose(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3025 StdLib::check_args(&args, 1, "transpose")?;
3026 let matrix = args[0].as_array()?;
3027
3028 if matrix.is_empty() {
3029 return Ok(JsonnetValue::array(vec![]));
3030 }
3031
3032 let mut max_len = 0;
3034 for row in matrix {
3035 match row {
3036 JsonnetValue::Array(arr) => {
3037 max_len = max_len.max(arr.len());
3038 }
3039 _ => return Err(JsonnetError::invalid_function_call("transpose() expects array of arrays".to_string())),
3040 }
3041 }
3042
3043 if max_len == 0 {
3044 return Ok(JsonnetValue::array(vec![]));
3045 }
3046
3047 let mut result = Vec::new();
3049 for col in 0..max_len {
3050 let mut new_row = Vec::new();
3051 for row in matrix {
3052 if let JsonnetValue::Array(arr) = row {
3053 if col < arr.len() {
3054 new_row.push(arr[col].clone());
3055 } else {
3056 new_row.push(JsonnetValue::Null);
3057 }
3058 }
3059 }
3060 result.push(JsonnetValue::array(new_row));
3061 }
3062
3063 Ok(JsonnetValue::array(result))
3064 }
3065
3066 pub fn flatten(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3068 StdLib::check_args(&args, 1, "flatten")?;
3069 let depth = if args.len() > 1 {
3070 args[1].as_number()? as usize
3071 } else {
3072 usize::MAX
3073 };
3074
3075 fn flatten_recursive(arr: &Vec<JsonnetValue>, current_depth: usize, max_depth: usize) -> Vec<JsonnetValue> {
3076 let mut result = Vec::new();
3077 for item in arr {
3078 match item {
3079 JsonnetValue::Array(nested) if current_depth < max_depth => {
3080 result.extend(flatten_recursive(nested, current_depth + 1, max_depth));
3081 }
3082 _ => result.push(item.clone()),
3083 }
3084 }
3085 result
3086 }
3087
3088 let arr = args[0].as_array()?;
3089 let flattened = flatten_recursive(arr, 0, depth);
3090 Ok(JsonnetValue::array(flattened))
3091 }
3092
3093 pub fn sum(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3095 StdLib::check_args(&args, 1, "sum")?;
3096 let arr = args[0].as_array()?;
3097
3098 let mut total = 0.0;
3099 for item in arr {
3100 total += item.as_number()?;
3101 }
3102
3103 Ok(JsonnetValue::number(total))
3104 }
3105
3106 pub fn product(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3108 StdLib::check_args(&args, 1, "product")?;
3109 let arr = args[0].as_array()?;
3110
3111 let mut result = 1.0;
3112 for item in arr {
3113 result *= item.as_number()?;
3114 }
3115
3116 Ok(JsonnetValue::number(result))
3117 }
3118
3119 pub fn all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3121 StdLib::check_args(&args, 1, "all")?;
3122 let arr = args[0].as_array()?;
3123
3124 for item in arr {
3125 if !item.is_truthy() {
3126 return Ok(JsonnetValue::boolean(false));
3127 }
3128 }
3129
3130 Ok(JsonnetValue::boolean(true))
3131 }
3132
3133 pub fn any(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3135 StdLib::check_args(&args, 1, "any")?;
3136 let arr = args[0].as_array()?;
3137
3138 for item in arr {
3139 if item.is_truthy() {
3140 return Ok(JsonnetValue::boolean(true));
3141 }
3142 }
3143
3144 Ok(JsonnetValue::boolean(false))
3145 }
3146
3147 pub fn sort_by(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3149 StdLib::check_args(&args, 2, "sortBy")?;
3150 let _arr = args[0].as_array()?.clone();
3151 let _key_func = &args[1];
3152
3153 Err(JsonnetError::runtime_error("sortBy() requires function calling mechanism - placeholder implementation".to_string()))
3156 }
3157
3158 pub fn group_by(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3160 StdLib::check_args(&args, 2, "groupBy")?;
3161 Err(JsonnetError::runtime_error("groupBy() requires function calling mechanism - placeholder implementation".to_string()))
3163 }
3164
3165 pub fn partition(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3167 StdLib::check_args(&args, 2, "partition")?;
3168 Err(JsonnetError::runtime_error("partition() requires function calling mechanism - placeholder implementation".to_string()))
3170 }
3171
3172 pub fn chunk(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3174 StdLib::check_args(&args, 2, "chunk")?;
3175 let arr = args[0].as_array()?;
3176 let size = args[1].as_number()? as usize;
3177
3178 if size == 0 {
3179 return Err(JsonnetError::invalid_function_call("chunk() size must be positive".to_string()));
3180 }
3181
3182 let mut result = Vec::new();
3183 for chunk in arr.chunks(size) {
3184 result.push(JsonnetValue::array(chunk.to_vec()));
3185 }
3186
3187 Ok(JsonnetValue::array(result))
3188 }
3189
3190 pub fn unique(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3192 StdLib::check_args(&args, 1, "unique")?;
3193 let arr = args[0].as_array()?;
3194
3195 let mut seen = std::collections::HashSet::new();
3196 let mut result = Vec::new();
3197
3198 for item in arr {
3199 if !seen.contains(&format!("{:?}", item)) {
3201 seen.insert(format!("{:?}", item));
3202 result.push(item.clone());
3203 }
3204 }
3205
3206 Ok(JsonnetValue::array(result))
3207 }
3208
3209 pub fn difference(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3211 if args.is_empty() {
3212 return Ok(JsonnetValue::array(vec![]));
3213 }
3214
3215 let first = args[0].as_array()?;
3216 let mut result = first.clone();
3217
3218 for arg in &args[1..] {
3219 let other = arg.as_array()?;
3220 let other_set: std::collections::HashSet<String> = other.iter()
3221 .map(|v| format!("{:?}", v))
3222 .collect();
3223
3224 result.retain(|item| !other_set.contains(&format!("{:?}", item)));
3225 }
3226
3227 Ok(JsonnetValue::array(result))
3228 }
3229
3230 pub fn intersection(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3232 if args.is_empty() {
3233 return Ok(JsonnetValue::array(vec![]));
3234 }
3235
3236 let first = args[0].as_array()?;
3237 let mut result = first.clone();
3238
3239 for arg in &args[1..] {
3240 let other = arg.as_array()?;
3241 let other_set: std::collections::HashSet<String> = other.iter()
3242 .map(|v| format!("{:?}", v))
3243 .collect();
3244
3245 result.retain(|item| other_set.contains(&format!("{:?}", item)));
3246 }
3247
3248 Ok(JsonnetValue::array(result))
3249 }
3250
3251 pub fn symmetric_difference(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3253 StdLib::check_args(&args, 2, "symmetricDifference")?;
3254 let a = args[0].as_array()?;
3255 let b = args[1].as_array()?;
3256
3257 let a_set: std::collections::HashSet<String> = a.iter()
3258 .map(|v| format!("{:?}", v))
3259 .collect();
3260 let b_set: std::collections::HashSet<String> = b.iter()
3261 .map(|v| format!("{:?}", v))
3262 .collect();
3263
3264 let symmetric_diff: std::collections::HashSet<_> = a_set.symmetric_difference(&b_set).cloned().collect();
3265
3266 let mut result: Vec<JsonnetValue> = a.iter()
3267 .filter(|item| symmetric_diff.contains(&format!("{:?}", item)))
3268 .chain(b.iter().filter(|item| symmetric_diff.contains(&format!("{:?}", item))))
3269 .cloned()
3270 .collect();
3271
3272 Ok(JsonnetValue::array(result))
3273 }
3274
3275 pub fn is_subset(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3277 StdLib::check_args(&args, 2, "isSubset")?;
3278 let a = args[0].as_array()?;
3279 let b = args[1].as_array()?;
3280
3281 let b_set: std::collections::HashSet<String> = b.iter()
3282 .map(|v| format!("{:?}", v))
3283 .collect();
3284
3285 let is_subset = a.iter().all(|item| b_set.contains(&format!("{:?}", item)));
3286
3287 Ok(JsonnetValue::boolean(is_subset))
3288 }
3289
3290 pub fn is_superset(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3292 StdLib::check_args(&args, 2, "isSuperset")?;
3293 let a = args[0].as_array()?;
3294 let b = args[1].as_array()?;
3295
3296 let a_set: std::collections::HashSet<String> = a.iter()
3297 .map(|v| format!("{:?}", v))
3298 .collect();
3299
3300 let is_superset = b.iter().all(|item| a_set.contains(&format!("{:?}", item)));
3301
3302 Ok(JsonnetValue::boolean(is_superset))
3303 }
3304
3305 pub fn is_disjoint(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3307 StdLib::check_args(&args, 2, "isDisjoint")?;
3308 let a = args[0].as_array()?;
3309 let b = args[1].as_array()?;
3310
3311 let a_set: std::collections::HashSet<String> = a.iter()
3312 .map(|v| format!("{:?}", v))
3313 .collect();
3314 let b_set: std::collections::HashSet<String> = b.iter()
3315 .map(|v| format!("{:?}", v))
3316 .collect();
3317
3318 let is_disjoint = a_set.intersection(&b_set).count() == 0;
3319
3320 Ok(JsonnetValue::boolean(is_disjoint))
3321 }
3322
3323 pub fn cartesian(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3325 StdLib::check_args(&args, 1, "cartesian")?;
3326 let arrays = args[0].as_array()?;
3327
3328 if arrays.is_empty() {
3329 return Ok(JsonnetValue::array(vec![JsonnetValue::array(vec![])]));
3330 }
3331
3332 let mut vec_arrays = Vec::new();
3334 for arr in arrays {
3335 vec_arrays.push(arr.as_array()?.clone());
3336 }
3337
3338 fn cartesian_product(arrays: &[Vec<JsonnetValue>]) -> Vec<Vec<JsonnetValue>> {
3339 if arrays.is_empty() {
3340 return vec![vec![]];
3341 }
3342
3343 let mut result = Vec::new();
3344 let first = &arrays[0];
3345 let rest = &arrays[1..];
3346
3347 for item in first {
3348 for mut combo in cartesian_product(rest) {
3349 combo.insert(0, item.clone());
3350 result.push(combo);
3351 }
3352 }
3353
3354 result
3355 }
3356
3357 let products = cartesian_product(&vec_arrays);
3358 let result: Vec<JsonnetValue> = products.into_iter()
3359 .map(|combo| JsonnetValue::array(combo))
3360 .collect();
3361
3362 Ok(JsonnetValue::array(result))
3363 }
3364
3365 pub fn cross(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3367 StdLib::check_args(&args, 2, "cross")?;
3368 let a = args[0].as_array()?;
3369 let b = args[1].as_array()?;
3370
3371 let mut result = Vec::new();
3372 for item_a in a {
3373 for item_b in b {
3374 result.push(JsonnetValue::array(vec![item_a.clone(), item_b.clone()]));
3375 }
3376 }
3377
3378 Ok(JsonnetValue::array(result))
3379 }
3380
3381 pub fn dot(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3383 StdLib::check_args(&args, 2, "dot")?;
3384 let a = args[0].as_array()?;
3385 let b = args[1].as_array()?;
3386
3387 if a.len() != b.len() {
3388 return Err(JsonnetError::invalid_function_call("dot() arrays must have same length".to_string()));
3389 }
3390
3391 let mut sum = 0.0;
3392 for (x, y) in a.iter().zip(b.iter()) {
3393 sum += x.as_number()? * y.as_number()?;
3394 }
3395
3396 Ok(JsonnetValue::number(sum))
3397 }
3398
3399 pub fn norm(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3401 StdLib::check_args(&args, 1, "norm")?;
3402 let arr = args[0].as_array()?;
3403
3404 let mut sum_squares = 0.0;
3405 for item in arr {
3406 let val = item.as_number()?;
3407 sum_squares += val * val;
3408 }
3409
3410 Ok(JsonnetValue::number(sum_squares.sqrt()))
3411 }
3412
3413 pub fn normalize(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3415 StdLib::check_args(&args, 1, "normalize")?;
3416 let arr = args[0].as_array()?;
3417
3418 let mut sum_squares = 0.0;
3420 for item in arr {
3421 let val = item.as_number()?;
3422 sum_squares += val * val;
3423 }
3424 let norm_val = sum_squares.sqrt();
3425 if norm_val == 0.0 {
3426 return Ok(args[0].clone());
3427 }
3428
3429 let mut result = Vec::new();
3430 for item in arr {
3431 let val = item.as_number()?;
3432 result.push(JsonnetValue::number(val / norm_val));
3433 }
3434
3435 Ok(JsonnetValue::array(result))
3436 }
3437
3438 pub fn distance(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3440 StdLib::check_args(&args, 2, "distance")?;
3441 let a = args[0].as_array()?;
3442 let b = args[1].as_array()?;
3443
3444 if a.len() != b.len() {
3445 return Err(JsonnetError::invalid_function_call("distance() arrays must have same length".to_string()));
3446 }
3447
3448 let mut sum_squares = 0.0;
3449 for (x, y) in a.iter().zip(b.iter()) {
3450 let diff = x.as_number()? - y.as_number()?;
3451 sum_squares += diff * diff;
3452 }
3453
3454 Ok(JsonnetValue::number(sum_squares.sqrt()))
3455 }
3456
3457 pub fn angle(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3459 StdLib::check_args(&args, 2, "angle")?;
3460 let a = args[0].as_array()?;
3461 let b = args[1].as_array()?;
3462
3463 if a.len() != b.len() {
3464 return Err(JsonnetError::invalid_function_call("angle() arrays must have same length".to_string()));
3465 }
3466
3467 let mut dot_product = 0.0;
3469 for (x, y) in a.iter().zip(b.iter()) {
3470 dot_product += x.as_number()? * y.as_number()?;
3471 }
3472
3473 let mut norm_a_sq = 0.0;
3475 for item in a {
3476 let val = item.as_number()?;
3477 norm_a_sq += val * val;
3478 }
3479 let norm_a = norm_a_sq.sqrt();
3480
3481 let mut norm_b_sq = 0.0;
3482 for item in b {
3483 let val = item.as_number()?;
3484 norm_b_sq += val * val;
3485 }
3486 let norm_b = norm_b_sq.sqrt();
3487
3488 if norm_a == 0.0 || norm_b == 0.0 {
3489 return Ok(JsonnetValue::number(0.0));
3490 }
3491
3492 let cos_theta = dot_product / (norm_a * norm_b);
3493 let cos_theta = cos_theta.max(-1.0).min(1.0); Ok(JsonnetValue::number(cos_theta.acos()))
3496 }
3497
3498 pub fn rotate(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3500 StdLib::check_args(&args, 2, "rotate")?;
3501 let point = args[0].as_array()?;
3502 let angle = args[1].as_number()?;
3503
3504 if point.len() != 2 {
3505 return Err(JsonnetError::invalid_function_call("rotate() point must be 2D".to_string()));
3506 }
3507
3508 let center = if args.len() > 2 {
3509 args[2].as_array()?.to_vec()
3510 } else {
3511 vec![JsonnetValue::number(0.0), JsonnetValue::number(0.0)]
3512 };
3513
3514 if center.len() != 2 {
3515 return Err(JsonnetError::invalid_function_call("rotate() center must be 2D".to_string()));
3516 }
3517
3518 let x = point[0].as_number()? - center[0].as_number()?;
3519 let y = point[1].as_number()? - center[1].as_number()?;
3520
3521 let cos_a = angle.cos();
3522 let sin_a = angle.sin();
3523
3524 let new_x = x * cos_a - y * sin_a + center[0].as_number()?;
3525 let new_y = x * sin_a + y * cos_a + center[1].as_number()?;
3526
3527 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3528 }
3529
3530 pub fn scale(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3532 StdLib::check_args(&args, 2, "scale")?;
3533 let point = args[0].as_array()?;
3534 let factor = args[1].as_number()?;
3535
3536 if point.len() != 2 {
3537 return Err(JsonnetError::invalid_function_call("scale() point must be 2D".to_string()));
3538 }
3539
3540 let center = if args.len() > 2 {
3541 args[2].as_array()?.to_vec()
3542 } else {
3543 vec![JsonnetValue::number(0.0), JsonnetValue::number(0.0)]
3544 };
3545
3546 if center.len() != 2 {
3547 return Err(JsonnetError::invalid_function_call("scale() center must be 2D".to_string()));
3548 }
3549
3550 let x = point[0].as_number()? - center[0].as_number()?;
3551 let y = point[1].as_number()? - center[1].as_number()?;
3552
3553 let new_x = x * factor + center[0].as_number()?;
3554 let new_y = y * factor + center[1].as_number()?;
3555
3556 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3557 }
3558
3559 pub fn translate(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3561 StdLib::check_args(&args, 2, "translate")?;
3562 let point = args[0].as_array()?;
3563 let offset = args[1].as_array()?;
3564
3565 if point.len() != 2 || offset.len() != 2 {
3566 return Err(JsonnetError::invalid_function_call("translate() requires 2D point and offset".to_string()));
3567 }
3568
3569 let new_x = point[0].as_number()? + offset[0].as_number()?;
3570 let new_y = point[1].as_number()? + offset[1].as_number()?;
3571
3572 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3573 }
3574
3575 pub fn reflect(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3577 StdLib::check_args(&args, 2, "reflect")?;
3578 let point = args[0].as_array()?;
3579 let axis = args[1].as_number()?; if point.len() != 2 {
3582 return Err(JsonnetError::invalid_function_call("reflect() point must be 2D".to_string()));
3583 }
3584
3585 let x = point[0].as_number()?;
3586 let y = point[1].as_number()?;
3587
3588 let cos_2a = (2.0 * axis).cos();
3589 let sin_2a = (2.0 * axis).sin();
3590
3591 let new_x = x * cos_2a + y * sin_2a;
3592 let new_y = x * sin_2a - y * cos_2a;
3593
3594 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3595 }
3596
3597 pub fn affine(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3599 StdLib::check_args(&args, 2, "affine")?;
3600 let point = args[0].as_array()?;
3601 let matrix = args[1].as_array()?;
3602
3603 if point.len() != 2 {
3604 return Err(JsonnetError::invalid_function_call("affine() point must be 2D".to_string()));
3605 }
3606
3607 if matrix.len() != 6 {
3608 return Err(JsonnetError::invalid_function_call("affine() matrix must be 6 elements [a,b,c,d,e,f]".to_string()));
3609 }
3610
3611 let x = point[0].as_number()?;
3612 let y = point[1].as_number()?;
3613
3614 let a = matrix[0].as_number()?;
3615 let b = matrix[1].as_number()?;
3616 let c = matrix[2].as_number()?;
3617 let d = matrix[3].as_number()?;
3618 let e = matrix[4].as_number()?;
3619 let f = matrix[5].as_number()?;
3620
3621 let new_x = a * x + b * y + e;
3622 let new_y = c * x + d * y + f;
3623
3624 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3625 }
3626
3627 pub fn split_limit(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3629 StdLib::check_args(&args, 3, "splitLimit")?;
3630 let s = args[0].as_string()?;
3631 let sep = args[1].as_string()?;
3632 let limit = args[2].as_number()? as usize;
3633
3634 if sep.is_empty() {
3635 let chars: Vec<String> = s.chars().take(limit).map(|c| c.to_string()).collect();
3637 let result: Vec<JsonnetValue> = chars.into_iter().map(JsonnetValue::string).collect();
3638 return Ok(JsonnetValue::array(result));
3639 }
3640
3641 let mut parts: Vec<&str> = s.splitn(limit + 1, &sep).collect();
3642 if parts.len() > limit {
3643 let remaining = parts.split_off(limit);
3645 parts.push(&s[(s.len() - remaining.join(&sep).len())..]);
3646 }
3647
3648 let result: Vec<JsonnetValue> = parts.into_iter().map(|s| JsonnetValue::string(s.to_string())).collect();
3649 Ok(JsonnetValue::array(result))
3650 }
3651
3652 pub fn join_variadic(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3654 if args.is_empty() {
3655 return Err(JsonnetError::invalid_function_call("join() expects at least one argument".to_string()));
3656 }
3657
3658 let sep = args[0].as_string()?;
3659 let arrays: Result<Vec<Vec<JsonnetValue>>> = args[1..].iter()
3660 .map(|arg| arg.as_array().cloned())
3661 .collect();
3662
3663 let arrays = arrays?;
3664 let mut result = Vec::new();
3665
3666 for (i, arr) in arrays.iter().enumerate() {
3667 if i > 0 && !sep.is_empty() {
3668 result.push(JsonnetValue::string(sep.clone()));
3669 }
3670 result.extend(arr.iter().cloned());
3671 }
3672
3673 Ok(JsonnetValue::array(result))
3674 }
3675
3676 pub fn replace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3678 StdLib::check_args(&args, 3, "replace")?;
3679 let s = args[0].as_string()?;
3680 let old = args[1].as_string()?;
3681 let new = args[2].as_string()?;
3682
3683 let result = s.replace(&old, &new);
3684 Ok(JsonnetValue::string(result))
3685 }
3686
3687 pub fn contains_variadic(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3689 StdLib::check_args(&args, 2, "contains")?;
3690
3691 match &args[0] {
3692 JsonnetValue::Array(arr) => {
3693 let target = format!("{:?}", &args[1]);
3695 for item in arr {
3696 if format!("{:?}", item) == target {
3697 return Ok(JsonnetValue::boolean(true));
3698 }
3699 }
3700 Ok(JsonnetValue::boolean(false))
3701 }
3702 JsonnetValue::String(s) => {
3703 let substr = args[1].as_string()?;
3704 Ok(JsonnetValue::boolean(s.contains(&substr)))
3705 }
3706 JsonnetValue::Object(obj) => {
3707 let key = args[1].as_string()?;
3708 Ok(JsonnetValue::boolean(obj.contains_key(&*key)))
3709 }
3710 _ => Err(JsonnetError::invalid_function_call("contains() expects array, string, or object".to_string())),
3711 }
3712 }
3713
3714 pub fn ai_http_get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3720 StdLib::check_args_range(&args, 1, 2, "ai.httpGet")?;
3721 let url = args[0].as_string()?;
3722 let headers = if args.len() > 1 {
3723 args[1].as_object()?.clone()
3724 } else {
3725 HashMap::new()
3726 };
3727
3728 let result = json!({
3731 "url": url,
3732 "method": "GET",
3733 "headers": headers,
3734 "status": "pending",
3735 "body": "HTTP request will be executed by runtime"
3736 });
3737 Ok(JsonnetValue::from_json_value(result))
3738 }
3739
3740 pub fn ai_http_post(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3742 StdLib::check_args_range(&args, 2, 3, "ai.httpPost")?;
3743 let url = args[0].as_string()?;
3744 let body = args[1].clone();
3745 let headers = if args.len() > 2 {
3746 args[2].as_object()?.clone()
3747 } else {
3748 HashMap::new()
3749 };
3750
3751 let result = json!({
3753 "url": url,
3754 "method": "POST",
3755 "body": body,
3756 "headers": headers,
3757 "status": "pending"
3758 });
3759 Ok(JsonnetValue::from_json_value(result))
3760 }
3761
3762 pub fn ai_call_model(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3764 StdLib::check_args_range(&args, 2, 3, "ai.callModel")?;
3765 let model = args[0].as_string()?;
3766 let messages = args[1].as_array()?.clone();
3767 let options = if args.len() > 2 {
3768 args[2].as_object()?.clone()
3769 } else {
3770 HashMap::new()
3771 };
3772
3773 let result = json!({
3775 "model": model,
3776 "messages": messages,
3777 "options": options,
3778 "status": "pending",
3779 "response": "AI model response will be generated by runtime"
3780 });
3781 Ok(JsonnetValue::from_json_value(result))
3782 }
3783
3784 pub fn tool_execute(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3786 StdLib::check_args_range(&args, 1, 3, "tool.execute")?;
3787 let command = args[0].as_string()?;
3788 let cmd_args = if args.len() > 1 {
3789 args[1].as_array()?.clone()
3790 } else {
3791 Vec::new()
3792 };
3793 let env = if args.len() > 2 {
3794 args[2].as_object()?.clone()
3795 } else {
3796 HashMap::new()
3797 };
3798
3799 let result = json!({
3801 "command": command,
3802 "args": cmd_args,
3803 "env": env,
3804 "status": "pending",
3805 "output": "Command will be executed by runtime"
3806 });
3807 Ok(JsonnetValue::from_json_value(result))
3808 }
3809
3810 pub fn memory_get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3812 StdLib::check_args(&args, 1, "memory.get")?;
3813 let key = args[0].as_string()?;
3814
3815 let result = json!({
3817 "key": key,
3818 "operation": "get",
3819 "status": "pending",
3820 "value": null
3821 });
3822 Ok(JsonnetValue::from_json_value(result))
3823 }
3824
3825 pub fn memory_set(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3827 StdLib::check_args(&args, 2, "memory.set")?;
3828 let key = args[0].as_string()?;
3829 let value = args[1].clone();
3830
3831 let result = json!({
3833 "key": key,
3834 "value": value,
3835 "operation": "set",
3836 "status": "pending"
3837 });
3838 Ok(JsonnetValue::from_json_value(result))
3839 }
3840
3841 pub fn agent_create(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3843 StdLib::check_args(&args, 2, "agent.create")?;
3844 let agent_type = args[0].as_string()?;
3845 let config = args[1].as_object()?.clone();
3846
3847 let result = json!({
3849 "type": agent_type,
3850 "config": config,
3851 "id": "agent_id_placeholder",
3852 "status": "created"
3853 });
3854 Ok(JsonnetValue::from_json_value(result))
3855 }
3856
3857 pub fn agent_execute(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3859 StdLib::check_args(&args, 2, "agent.execute")?;
3860 let agent = args[0].clone();
3861 let input = args[1].as_string()?;
3862
3863 let result = json!({
3865 "agent": agent,
3866 "input": input,
3867 "status": "pending",
3868 "output": "Agent execution will be handled by runtime"
3869 });
3870 Ok(JsonnetValue::from_json_value(result))
3871 }
3872
3873 pub fn chain_create(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3875 StdLib::check_args(&args, 1, "chain.create")?;
3876 let steps = args[0].as_array()?.clone();
3877
3878 let result = json!({
3880 "steps": steps,
3881 "id": "chain_id_placeholder",
3882 "status": "created"
3883 });
3884 Ok(JsonnetValue::from_json_value(result))
3885 }
3886
3887 pub fn chain_execute(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3889 StdLib::check_args(&args, 2, "chain.execute")?;
3890 let chain = args[0].clone();
3891 let input = args[1].clone();
3892
3893 let result = json!({
3895 "chain": chain,
3896 "input": input,
3897 "status": "pending",
3898 "output": "Chain execution will be handled by runtime"
3899 });
3900 Ok(JsonnetValue::from_json_value(result))
3901 }
3902
3903}