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 pub fn to_string(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1230 Self::check_args(&args, 1, "toString")?;
1231 Ok(JsonnetValue::string(args[0].to_string()))
1232 }
1233
1234 pub fn join(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1236 Self::check_args(&args, 2, "join")?;
1237 let sep = args[0].as_string()?;
1238 let arr = args[1].as_array()?;
1239
1240 let mut result = String::new();
1241 for (i, item) in arr.iter().enumerate() {
1242 if i > 0 {
1243 result.push_str(&sep);
1244 }
1245 result.push_str(&item.to_string());
1246 }
1247
1248 Ok(JsonnetValue::string(result))
1249 }
1250
1251 pub fn substr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1253 Self::check_args(&args, 3, "substr")?;
1254 let s = args[0].as_string()?;
1255 let from = args[1].as_number()? as usize;
1256 let len = args[2].as_number()? as usize;
1257
1258 if from >= s.len() {
1259 Ok(JsonnetValue::string(String::new()))
1260 } else {
1261 let end = (from + len).min(s.len());
1262 Ok(JsonnetValue::string(s[from..end].to_string()))
1263 }
1264 }
1265
1266 pub fn split(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1268 Self::check_args(&args, 2, "split")?;
1269 let s = args[0].as_string()?;
1270 let sep = args[1].as_string()?;
1271
1272 let parts: Vec<JsonnetValue> = s.split(&sep)
1273 .map(|part| JsonnetValue::string(part.to_string()))
1274 .collect();
1275
1276 Ok(JsonnetValue::array(parts))
1277 }
1278
1279 pub fn starts_with(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1281 Self::check_args(&args, 2, "startsWith")?;
1282 let s = args[0].as_string()?;
1283 let prefix = args[1].as_string()?;
1284
1285 Ok(JsonnetValue::boolean(s.starts_with(&prefix)))
1286 }
1287
1288 pub fn ends_with(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1290 Self::check_args(&args, 2, "endsWith")?;
1291 let s = args[0].as_string()?;
1292 let suffix = args[1].as_string()?;
1293
1294 Ok(JsonnetValue::boolean(s.ends_with(&suffix)))
1295 }
1296
1297 pub fn string_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1299 Self::check_args(&args, 1, "stringChars")?;
1300 let s = args[0].as_string()?;
1301
1302 let chars: Vec<JsonnetValue> = s.chars()
1303 .map(|c| JsonnetValue::string(c.to_string()))
1304 .collect();
1305
1306 Ok(JsonnetValue::array(chars))
1307 }
1308
1309 pub fn ascii_lower(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1311 Self::check_args(&args, 1, "asciiLower")?;
1312 let s = args[0].as_string()?;
1313 Ok(JsonnetValue::string(s.to_ascii_lowercase()))
1314 }
1315
1316 pub fn ascii_upper(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1318 Self::check_args(&args, 1, "asciiUpper")?;
1319 let s = args[0].as_string()?;
1320 Ok(JsonnetValue::string(s.to_ascii_uppercase()))
1321 }
1322
1323 pub fn flat_map(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1325 Self::check_args(&args, 2, "flatMap")?;
1326 let arr = args[1].as_array()?;
1329 Ok(JsonnetValue::array(arr.clone()))
1330 }
1331
1332 pub fn map_with_index(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1334 Self::check_args(&args, 2, "mapWithIndex")?;
1335 let arr = args[1].as_array()?;
1337
1338 let mut result = Vec::new();
1339 for (i, item) in arr.iter().enumerate() {
1340 let pair = JsonnetValue::array(vec![
1341 JsonnetValue::number(i as f64),
1342 item.clone()
1343 ]);
1344 result.push(pair);
1345 }
1346
1347 Ok(JsonnetValue::array(result))
1348 }
1349
1350 pub fn lstrip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1352 Self::check_args(&args, 2, "lstripChars")?;
1353 let s = args[0].as_string()?;
1354 let chars = args[1].as_string()?;
1355
1356 let trimmed = s.trim_start_matches(|c| chars.contains(c));
1357 Ok(JsonnetValue::string(trimmed.to_string()))
1358 }
1359
1360 pub fn rstrip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1362 Self::check_args(&args, 2, "rstripChars")?;
1363 let s = args[0].as_string()?;
1364 let chars = args[1].as_string()?;
1365
1366 let trimmed = s.trim_end_matches(|c| chars.contains(c));
1367 Ok(JsonnetValue::string(trimmed.to_string()))
1368 }
1369
1370 pub fn strip_chars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1372 Self::check_args(&args, 2, "stripChars")?;
1373 let s = args[0].as_string()?;
1374 let chars = args[1].as_string()?;
1375
1376 let trimmed = s.trim_matches(|c| chars.contains(c));
1377 Ok(JsonnetValue::string(trimmed.to_string()))
1378 }
1379
1380 pub fn find_substr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1382 Self::check_args(&args, 2, "findSubstr")?;
1383 let pat = args[0].as_string()?;
1384 let s = args[1].as_string()?;
1385
1386 let mut positions = Vec::new();
1387 let mut start = 0;
1388
1389 while let Some(pos) = s[start..].find(&pat) {
1390 positions.push(JsonnetValue::number((start + pos) as f64));
1391 start += pos + pat.len();
1392 if start >= s.len() {
1393 break;
1394 }
1395 }
1396
1397 Ok(JsonnetValue::array(positions))
1398 }
1399
1400 pub fn repeat(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1402 Self::check_args(&args, 2, "repeat")?;
1403 let what = &args[0];
1404 let count = args[1].as_number()? as usize;
1405
1406 match what {
1407 JsonnetValue::String(s) => {
1408 let repeated = s.repeat(count);
1409 Ok(JsonnetValue::string(repeated))
1410 }
1411 JsonnetValue::Array(arr) => {
1412 let mut result = Vec::new();
1413 for _ in 0..count {
1414 result.extend(arr.clone());
1415 }
1416 Ok(JsonnetValue::array(result))
1417 }
1418 _ => Err(JsonnetError::type_error("repeat expects string or array as first argument")),
1419 }
1420 }
1421
1422 pub fn set(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1424 Self::check_args(&args, 1, "set")?;
1425 let arr = args[0].as_array()?;
1426
1427 let mut seen = std::collections::HashSet::new();
1428 let mut result = Vec::new();
1429
1430 for item in arr {
1431 let key = format!("{:?}", item);
1434 if seen.insert(key) {
1435 result.push(item.clone());
1436 }
1437 }
1438
1439 Ok(JsonnetValue::array(result))
1440 }
1441
1442 pub fn set_member(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1444 Self::check_args(&args, 2, "setMember")?;
1445 let x = &args[0];
1446 let arr = args[1].as_array()?;
1447
1448 let contains = arr.iter().any(|item| item.equals(x));
1449 Ok(JsonnetValue::boolean(contains))
1450 }
1451
1452 pub fn set_inter(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1454 Self::check_args(&args, 2, "setInter")?;
1455 let a = args[0].as_array()?;
1456 let b = args[1].as_array()?;
1457
1458 let mut result = Vec::new();
1459 for item_a in a {
1460 if b.iter().any(|item_b| item_a.equals(item_b)) && !result.iter().any(|item_r| item_a.equals(item_r)) {
1461 result.push(item_a.clone());
1462 }
1463 }
1464
1465 Ok(JsonnetValue::array(result))
1466 }
1467
1468 pub fn set_union(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1470 Self::check_args(&args, 2, "setUnion")?;
1471 let a = args[0].as_array()?;
1472 let b = args[1].as_array()?;
1473
1474 let mut result = a.clone();
1475
1476 for item_b in b {
1477 if !result.iter().any(|item_r| item_b.equals(item_r)) {
1478 result.push(item_b.clone());
1479 }
1480 }
1481
1482 Ok(JsonnetValue::array(result))
1483 }
1484
1485 pub fn set_diff(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1487 Self::check_args(&args, 2, "setDiff")?;
1488 let a = args[0].as_array()?;
1489 let b = args[1].as_array()?;
1490
1491 let mut result = Vec::new();
1492 for item_a in a {
1493 if !b.iter().any(|item_b| item_a.equals(item_b)) {
1494 result.push(item_a.clone());
1495 }
1496 }
1497
1498 Ok(JsonnetValue::array(result))
1499 }
1500
1501 fn type_of(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1503 Self::check_args(&args, 1, "type")?;
1504 let type_str = args[0].type_name();
1505 Ok(JsonnetValue::string(type_str))
1506 }
1507
1508 fn make_array(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1510 Self::check_args(&args, 2, "makeArray")?;
1511 let n = args[0].as_number()? as usize;
1512 let _func = &args[1];
1513
1514 let mut result = Vec::new();
1517 for i in 0..n {
1518 result.push(JsonnetValue::number(i as f64));
1520 }
1521
1522 Ok(JsonnetValue::array(result))
1523 }
1524
1525 fn filter(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1527 Self::check_args(&args, 2, "filter")?;
1528 let _func = &args[0];
1529 let _arr = args[1].as_array()?;
1530 Ok(args[1].clone())
1533 }
1534
1535 fn map(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1537 Self::check_args(&args, 2, "map")?;
1538 let _func = &args[0];
1539 let _arr = args[1].as_array()?;
1540 Ok(args[1].clone())
1543 }
1544
1545 fn foldl(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1547 Self::check_args(&args, 3, "foldl")?;
1548 let _func = &args[0];
1549 let _arr = args[1].as_array()?;
1550 Ok(args[2].clone())
1553 }
1554
1555 fn foldr(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1557 Self::check_args(&args, 3, "foldr")?;
1558 let _func = &args[0];
1559 let _arr = args[1].as_array()?;
1560 Ok(args[2].clone())
1563 }
1564
1565 fn range(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1567 Self::check_args(&args, 1, "range")?;
1568 let n = args[0].as_number()? as usize;
1569 let arr: Vec<JsonnetValue> = (0..n).map(|i| JsonnetValue::number(i as f64)).collect();
1570 Ok(JsonnetValue::array(arr))
1571 }
1572
1573
1574
1575 fn contains(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1577 Self::check_args(&args, 2, "contains")?;
1578 let arr = args[0].as_array()?;
1579 let contains = arr.iter().any(|item| item.equals(&args[1]));
1580 Ok(JsonnetValue::boolean(contains))
1581 }
1582
1583
1584
1585
1586 fn char_fn(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1588 Self::check_args(&args, 1, "char")?;
1589 let n = args[0].as_number()? as u32;
1590 match char::from_u32(n) {
1591 Some(c) => Ok(JsonnetValue::string(c.to_string())),
1592 None => Err(JsonnetError::runtime_error("Invalid codepoint")),
1593 }
1594 }
1595
1596 fn codepoint(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1598 Self::check_args(&args, 1, "codepoint")?;
1599 let s = args[0].as_string()?;
1600 match s.chars().next() {
1601 Some(c) => Ok(JsonnetValue::number(c as u32 as f64)),
1602 None => Err(JsonnetError::runtime_error("Empty string")),
1603 }
1604 }
1605
1606
1607 fn parse_int(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1609 Self::check_args(&args, 1, "parseInt")?;
1610 let s = args[0].as_string()?;
1611 match s.parse::<f64>() {
1612 Ok(n) => Ok(JsonnetValue::number(n)),
1613 Err(_) => Err(JsonnetError::runtime_error("Invalid number format")),
1614 }
1615 }
1616
1617 fn parse_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1619 Self::check_args(&args, 1, "parseJson")?;
1620 let s = args[0].as_string()?;
1621 match serde_json::from_str::<serde_json::Value>(s) {
1622 Ok(value) => Ok(JsonnetValue::from_json_value(value)),
1623 Err(_) => Err(JsonnetError::runtime_error("Invalid JSON")),
1624 }
1625 }
1626
1627 fn encode_utf8(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1629 Self::check_args(&args, 1, "encodeUTF8")?;
1630 let s = args[0].as_string()?;
1631 let bytes: Vec<JsonnetValue> = s.as_bytes().iter().map(|&b| JsonnetValue::number(b as f64)).collect();
1632 Ok(JsonnetValue::array(bytes))
1633 }
1634
1635 fn decode_utf8(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1637 Self::check_args(&args, 1, "decodeUTF8")?;
1638 let arr = args[0].as_array()?;
1639 let mut bytes = Vec::new();
1640 for item in arr {
1641 let b = item.as_number()? as u8;
1642 bytes.push(b);
1643 }
1644 match String::from_utf8(bytes) {
1645 Ok(s) => Ok(JsonnetValue::string(s)),
1646 Err(_) => Err(JsonnetError::runtime_error("Invalid UTF-8 sequence")),
1647 }
1648 }
1649
1650 fn md5(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1652 Self::check_args(&args, 1, "md5")?;
1653 let s = args[0].as_string()?;
1654 use md5::{Md5, Digest};
1655 let mut hasher = Md5::new();
1656 hasher.update(s.as_bytes());
1657 let result = hasher.finalize();
1658 Ok(JsonnetValue::string(format!("{:x}", result)))
1659 }
1660
1661 fn base64(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1663 Self::check_args(&args, 1, "base64")?;
1664 let s = args[0].as_string()?;
1665 use base64::{Engine as _, engine::general_purpose};
1666 let encoded = general_purpose::STANDARD.encode(s.as_bytes());
1667 Ok(JsonnetValue::string(encoded))
1668 }
1669
1670 fn base64_decode(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1672 Self::check_args(&args, 1, "base64Decode")?;
1673 let s = args[0].as_string()?;
1674 use base64::{Engine as _, engine::general_purpose};
1675 match general_purpose::STANDARD.decode(s.as_bytes()) {
1676 Ok(bytes) => match String::from_utf8(bytes) {
1677 Ok(decoded) => Ok(JsonnetValue::string(decoded)),
1678 Err(_) => Err(JsonnetError::runtime_error("Invalid UTF-8 in decoded data")),
1679 },
1680 Err(_) => Err(JsonnetError::runtime_error("Invalid base64")),
1681 }
1682 }
1683
1684 fn manifest_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1686 Self::check_args(&args, 1, "manifestJson")?;
1687 let json = serde_json::to_string_pretty(&args[0].to_json_value())?;
1688 Ok(JsonnetValue::string(json))
1689 }
1690
1691 fn manifest_json_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1693 Self::check_args(&args, 2, "manifestJsonEx")?;
1694 let value = &args[0];
1695 let indent = args[1].as_string()?;
1696
1697 match serde_json::to_string_pretty(&value.to_json_value()) {
1700 Ok(json) => {
1701 if indent.is_empty() {
1702 Ok(JsonnetValue::string(json))
1703 } else {
1704 let indented = json.lines()
1706 .map(|line| {
1707 let leading_spaces = line.chars().take_while(|c| *c == ' ').count();
1708 if leading_spaces > 0 {
1709 let indent_level = leading_spaces / 2;
1710 format!("{}{}", indent.repeat(indent_level), &line[leading_spaces..])
1711 } else {
1712 line.to_string()
1713 }
1714 })
1715 .collect::<Vec<_>>()
1716 .join("\n");
1717 Ok(JsonnetValue::string(indented))
1718 }
1719 }
1720 Err(_) => Err(JsonnetError::runtime_error("Failed to serialize to JSON")),
1721 }
1722 }
1723
1724 #[cfg(feature = "yaml")]
1726 fn manifest_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1727 Self::check_args(&args, 1, "manifestYaml")?;
1728 let yaml = serde_yaml::to_string(&args[0].to_json_value())?;
1729 Ok(JsonnetValue::string(yaml))
1730 }
1731
1732 #[cfg(not(feature = "yaml"))]
1734 fn manifest_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1735 Self::check_args(&args, 1, "manifestYaml")?;
1736 Self::manifest_json(args)
1738 }
1739
1740 fn escape_string_json(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1742 Self::check_args(&args, 1, "escapeStringJson")?;
1743 let s = args[0].as_string()?;
1744 let escaped = serde_json::to_string(s)?;
1745 Ok(JsonnetValue::string(escaped))
1746 }
1747
1748 fn escape_string_yaml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1749 Self::check_args(&args, 1, "escapeStringYaml")?;
1750 let s = args[0].as_string()?;
1751
1752 let mut escaped = String::new();
1755 for ch in s.chars() {
1756 match ch {
1757 '"' => escaped.push_str("\\\""),
1758 '\\' => escaped.push_str("\\\\"),
1759 '\n' => escaped.push_str("\\n"),
1760 '\r' => escaped.push_str("\\r"),
1761 '\t' => escaped.push_str("\\t"),
1762 '\0' => escaped.push_str("\\0"),
1763 _ => escaped.push(ch),
1764 }
1765 }
1766
1767 let needs_quotes = s.contains(' ') || s.contains('\t') || s.contains('\n') ||
1769 s.contains(':') || s.contains('#') || s.contains('-') ||
1770 s.starts_with('[') || s.starts_with('{') ||
1771 s.starts_with('"') || s.starts_with('\'');
1772
1773 if needs_quotes {
1774 Ok(JsonnetValue::string(format!("\"{}\"", escaped)))
1775 } else {
1776 Ok(JsonnetValue::string(escaped))
1777 }
1778 }
1779
1780 fn escape_string_python(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1781 Self::check_args(&args, 1, "escapeStringPython")?;
1782 let s = args[0].as_string()?;
1783 let escaped = s.escape_default().to_string();
1784 Ok(JsonnetValue::string(format!("'{}'", escaped)))
1785 }
1786
1787 fn escape_string_bash(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1788 Self::check_args(&args, 1, "escapeStringBash")?;
1789 let s = args[0].as_string()?;
1790 let escaped = s.replace("'", "'\"'\"'").replace("\\", "\\\\");
1791 Ok(JsonnetValue::string(format!("'{}'", escaped)))
1792 }
1793
1794 fn escape_string_dollars(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1795 Self::check_args(&args, 1, "escapeStringDollars")?;
1796 let s = args[0].as_string()?;
1797 let escaped = s.replace("$$", "$").replace("$", "$$");
1798 Ok(JsonnetValue::string(escaped))
1799 }
1800
1801
1802 fn string_bytes(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1803 Self::check_args(&args, 1, "stringBytes")?;
1804 let s = args[0].as_string()?;
1805 let bytes: Vec<JsonnetValue> = s.as_bytes().iter().map(|&b| JsonnetValue::number(b as f64)).collect();
1806 Ok(JsonnetValue::array(bytes))
1807 }
1808
1809 fn format(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1810 Self::check_args(&args, 2, "format")?;
1811 let format_str = args[0].as_string()?;
1812 let values = args[1].as_array()?;
1813
1814 let mut result = format_str.to_string();
1816 for (i, value) in values.iter().enumerate() {
1817 let placeholder = format!("%{}", i + 1);
1818 let value_str = match value {
1819 JsonnetValue::String(s) => s.clone(),
1820 JsonnetValue::Number(n) => n.to_string(),
1821 JsonnetValue::Boolean(b) => b.to_string(),
1822 _ => value.to_string(),
1823 };
1824 result = result.replace(&placeholder, &value_str);
1825 }
1826
1827 Ok(JsonnetValue::string(result))
1828 }
1829
1830 fn is_array(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1832 Self::check_args(&args, 1, "isArray")?;
1833 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Array(_))))
1834 }
1835
1836 fn is_boolean(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1837 Self::check_args(&args, 1, "isBoolean")?;
1838 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Boolean(_))))
1839 }
1840
1841 fn is_function(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1842 Self::check_args(&args, 1, "isFunction")?;
1843 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Function(_))))
1844 }
1845
1846 fn is_number(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1847 Self::check_args(&args, 1, "isNumber")?;
1848 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Number(_))))
1849 }
1850
1851 fn is_object(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1852 Self::check_args(&args, 1, "isObject")?;
1853 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::Object(_))))
1854 }
1855
1856 fn is_string(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1857 Self::check_args(&args, 1, "isString")?;
1858 Ok(JsonnetValue::boolean(matches!(args[0], JsonnetValue::String(_))))
1859 }
1860
1861 fn count(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1863 Self::check_args(&args, 2, "count")?;
1864 let arr = args[0].as_array()?;
1865 let elem = &args[1];
1866 let count = arr.iter().filter(|item| item.equals(elem)).count() as f64;
1867 Ok(JsonnetValue::number(count))
1868 }
1869
1870 fn find(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1871 Self::check_args(&args, 2, "find")?;
1872 match (&args[0], &args[1]) {
1873 (JsonnetValue::Array(arr), value) => {
1874 let mut indices = Vec::new();
1875 for (i, item) in arr.iter().enumerate() {
1876 if item == value {
1877 indices.push(JsonnetValue::Number(i as f64));
1878 }
1879 }
1880 Ok(JsonnetValue::array(indices))
1881 }
1882 _ => Err(JsonnetError::runtime_error("find expects array and search value")),
1883 }
1884 }
1885
1886 fn member(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1887 Self::contains(args)
1888 }
1889
1890 fn modulo(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1892 Self::check_args(&args, 2, "modulo")?;
1893 let a = args[0].as_number()?;
1894 let b = args[1].as_number()?;
1895 if b == 0.0 {
1896 return Err(JsonnetError::DivisionByZero);
1897 }
1898 Ok(JsonnetValue::number(a % b))
1899 }
1900
1901 fn pow(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1902 Self::check_args(&args, 2, "pow")?;
1903 let a = args[0].as_number()?;
1904 let b = args[1].as_number()?;
1905 Ok(JsonnetValue::number(a.powf(b)))
1906 }
1907
1908 fn exp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1909 Self::check_args(&args, 1, "exp")?;
1910 let x = args[0].as_number()?;
1911 Ok(JsonnetValue::number(x.exp()))
1912 }
1913
1914 fn log(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1915 Self::check_args(&args, 1, "log")?;
1916 let x = args[0].as_number()?;
1917 if x <= 0.0 {
1918 return Err(JsonnetError::runtime_error("log of non-positive number"));
1919 }
1920 Ok(JsonnetValue::number(x.ln()))
1921 }
1922
1923 fn sqrt(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1924 Self::check_args(&args, 1, "sqrt")?;
1925 let x = args[0].as_number()?;
1926 if x < 0.0 {
1927 return Err(JsonnetError::runtime_error("sqrt of negative number"));
1928 }
1929 Ok(JsonnetValue::number(x.sqrt()))
1930 }
1931
1932 fn sin(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1933 Self::check_args(&args, 1, "sin")?;
1934 let x = args[0].as_number()?;
1935 Ok(JsonnetValue::number(x.sin()))
1936 }
1937
1938 fn cos(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1939 Self::check_args(&args, 1, "cos")?;
1940 let x = args[0].as_number()?;
1941 Ok(JsonnetValue::number(x.cos()))
1942 }
1943
1944 fn tan(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1945 Self::check_args(&args, 1, "tan")?;
1946 let x = args[0].as_number()?;
1947 Ok(JsonnetValue::number(x.tan()))
1948 }
1949
1950 fn asin(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1951 Self::check_args(&args, 1, "asin")?;
1952 let x = args[0].as_number()?;
1953 Ok(JsonnetValue::number(x.asin()))
1954 }
1955
1956 fn acos(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1957 Self::check_args(&args, 1, "acos")?;
1958 let x = args[0].as_number()?;
1959 Ok(JsonnetValue::number(x.acos()))
1960 }
1961
1962 fn atan(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1963 Self::check_args(&args, 1, "atan")?;
1964 let x = args[0].as_number()?;
1965 Ok(JsonnetValue::number(x.atan()))
1966 }
1967
1968 fn floor(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1969 Self::check_args(&args, 1, "floor")?;
1970 let x = args[0].as_number()?;
1971 Ok(JsonnetValue::number(x.floor()))
1972 }
1973
1974 fn ceil(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1975 Self::check_args(&args, 1, "ceil")?;
1976 let x = args[0].as_number()?;
1977 Ok(JsonnetValue::number(x.ceil()))
1978 }
1979
1980 fn round(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1981 Self::check_args(&args, 1, "round")?;
1982 let x = args[0].as_number()?;
1983 Ok(JsonnetValue::number(x.round()))
1984 }
1985
1986 fn abs(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1987 Self::check_args(&args, 1, "abs")?;
1988 let x = args[0].as_number()?;
1989 Ok(JsonnetValue::number(x.abs()))
1990 }
1991
1992 fn max(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
1993 Self::check_args(&args, 1, "max")?;
1994 let arr = args[0].as_array()?;
1995 if arr.is_empty() {
1996 return Err(JsonnetError::runtime_error("max() called on empty array"));
1997 }
1998 let mut max_val = f64::NEG_INFINITY;
1999 for item in arr {
2000 let val = item.as_number()?;
2001 if val > max_val {
2002 max_val = val;
2003 }
2004 }
2005 Ok(JsonnetValue::number(max_val))
2006 }
2007
2008 fn min(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2009 Self::check_args(&args, 1, "min")?;
2010 let arr = args[0].as_array()?;
2011 if arr.is_empty() {
2012 return Err(JsonnetError::runtime_error("min() called on empty array"));
2013 }
2014 let mut min_val = f64::INFINITY;
2015 for item in arr {
2016 let val = item.as_number()?;
2017 if val < min_val {
2018 min_val = val;
2019 }
2020 }
2021 Ok(JsonnetValue::number(min_val))
2022 }
2023
2024 fn clamp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2025 Self::check_args(&args, 3, "clamp")?;
2026 let x = args[0].as_number()?;
2027 let min = args[1].as_number()?;
2028 let max = args[2].as_number()?;
2029 let clamped = x.max(min).min(max);
2030 Ok(JsonnetValue::number(clamped))
2031 }
2032
2033 fn assert_equal(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2034 Self::check_args(&args, 2, "assertEqual")?;
2035 if !args[0].equals(&args[1]) {
2036 return Err(JsonnetError::assertion_failed(format!(
2037 "Assertion failed: {} != {}\n Left: {:?}\n Right: {:?}",
2038 args[0], args[1], args[0], args[1]
2039 )));
2040 }
2041 Ok(JsonnetValue::boolean(true))
2042 }
2043
2044 fn trace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2045 Self::check_args(&args, 2, "trace")?;
2046 eprintln!("TRACE: {:?}", args[1]);
2048 Ok(args[0].clone())
2050 }
2051
2052 fn sort(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2054 Self::check_args(&args, 1, "sort")?;
2055 let arr = args[0].as_array()?;
2056
2057 if arr.is_empty() {
2058 return Ok(JsonnetValue::array(vec![]));
2059 }
2060
2061 let mut sorted = arr.clone();
2064 sorted.sort_by(|a, b| Self::compare_values(a, b));
2065
2066 Ok(JsonnetValue::array(sorted))
2067 }
2068
2069 fn compare_values(a: &JsonnetValue, b: &JsonnetValue) -> std::cmp::Ordering {
2070 match (a, b) {
2071 (JsonnetValue::Null, JsonnetValue::Null) => std::cmp::Ordering::Equal,
2072 (JsonnetValue::Null, _) => std::cmp::Ordering::Less,
2073 (_, JsonnetValue::Null) => std::cmp::Ordering::Greater,
2074 (JsonnetValue::Boolean(x), JsonnetValue::Boolean(y)) => x.cmp(y),
2075 (JsonnetValue::Boolean(_), _) => std::cmp::Ordering::Less,
2076 (_, JsonnetValue::Boolean(_)) => std::cmp::Ordering::Greater,
2077 (JsonnetValue::Number(x), JsonnetValue::Number(y)) => {
2078 x.partial_cmp(y).unwrap_or(std::cmp::Ordering::Equal)
2079 }
2080 (JsonnetValue::Number(_), _) => std::cmp::Ordering::Less,
2081 (_, JsonnetValue::Number(_)) => std::cmp::Ordering::Greater,
2082 (JsonnetValue::String(x), JsonnetValue::String(y)) => x.cmp(y),
2083 (JsonnetValue::String(_), _) => std::cmp::Ordering::Less,
2084 (_, JsonnetValue::String(_)) => std::cmp::Ordering::Greater,
2085 (JsonnetValue::Array(x), JsonnetValue::Array(y)) => {
2086 for (_i, (a_item, b_item)) in x.iter().zip(y.iter()).enumerate() {
2087 let cmp = Self::compare_values(a_item, b_item);
2088 if cmp != std::cmp::Ordering::Equal {
2089 return cmp;
2090 }
2091 }
2092 x.len().cmp(&y.len())
2093 }
2094 (JsonnetValue::Array(_), _) => std::cmp::Ordering::Less,
2095 (_, JsonnetValue::Array(_)) => std::cmp::Ordering::Greater,
2096 (JsonnetValue::Object(x), JsonnetValue::Object(y)) => {
2097 let mut x_keys: Vec<_> = x.keys().collect();
2099 let mut y_keys: Vec<_> = y.keys().collect();
2100 x_keys.sort();
2101 y_keys.sort();
2102
2103 for (x_key, y_key) in x_keys.iter().zip(y_keys.iter()) {
2104 let key_cmp = x_key.cmp(y_key);
2105 if key_cmp != std::cmp::Ordering::Equal {
2106 return key_cmp;
2107 }
2108 if let (Some(x_val), Some(y_val)) = (x.get(*x_key), y.get(*y_key)) {
2109 let val_cmp = Self::compare_values(x_val, y_val);
2110 if val_cmp != std::cmp::Ordering::Equal {
2111 return val_cmp;
2112 }
2113 }
2114 }
2115 x.len().cmp(&y.len())
2116 }
2117 _ => std::cmp::Ordering::Equal, }
2119 }
2120
2121 fn uniq(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2122 Self::check_args(&args, 1, "uniq")?;
2123 let arr = args[0].as_array()?;
2124
2125 let mut result: Vec<JsonnetValue> = Vec::new();
2126 for item in arr {
2127 let mut found = false;
2129 for existing in &result {
2130 if existing.equals(item) {
2131 found = true;
2132 break;
2133 }
2134 }
2135 if !found {
2136 result.push(item.clone());
2137 }
2138 }
2139
2140 Ok(JsonnetValue::array(result))
2141 }
2142
2143 fn reverse(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2144 Self::check_args(&args, 1, "reverse")?;
2145 let arr = args[0].as_array()?;
2146 let reversed: Vec<JsonnetValue> = arr.iter().rev().cloned().collect();
2147 Ok(JsonnetValue::array(reversed))
2148 }
2149
2150 fn merge_patch(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2152 Self::check_args(&args, 2, "mergePatch")?;
2153 let target = args[0].as_object()?;
2154 let patch = args[1].as_object()?;
2155
2156 let mut result = target.clone();
2157
2158 for (key, patch_value) in patch {
2159 match patch_value {
2160 JsonnetValue::Null => {
2161 result.remove(key);
2163 }
2164 JsonnetValue::Object(patch_obj) => {
2165 if let Some(JsonnetValue::Object(target_obj)) = result.get(key) {
2167 let merged = Self::merge_patch(vec![
2168 JsonnetValue::object(target_obj.clone()),
2169 JsonnetValue::object(patch_obj.clone())
2170 ])?;
2171 if let JsonnetValue::Object(merged_obj) = merged {
2172 result.insert(key.clone(), JsonnetValue::object(merged_obj));
2173 }
2174 } else {
2175 result.insert(key.clone(), JsonnetValue::object(patch_obj.clone()));
2177 }
2178 }
2179 _ => {
2180 result.insert(key.clone(), patch_value.clone());
2182 }
2183 }
2184 }
2185
2186 Ok(JsonnetValue::object(result))
2187 }
2188
2189 fn get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2190 Self::check_args(&args, 3, "get")?;
2191 let obj = args[0].as_object()?;
2192 let key = args[1].as_string()?;
2193 let default = &args[2];
2194 Ok(obj.get(key).unwrap_or(default).clone())
2195 }
2196
2197 fn object_fields(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2198 Self::check_args(&args, 1, "objectFields")?;
2199 let obj = args[0].as_object()?;
2200 let fields: Vec<JsonnetValue> = obj.keys()
2201 .filter(|&k| !k.starts_with('_')) .map(|k| JsonnetValue::string(k.clone()))
2203 .collect();
2204 Ok(JsonnetValue::array(fields))
2205 }
2206
2207 fn object_fields_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2208 Self::check_args(&args, 1, "objectFieldsAll")?;
2209 let obj = args[0].as_object()?;
2210 let fields: Vec<JsonnetValue> = obj.keys()
2211 .map(|k| JsonnetValue::string(k.clone()))
2212 .collect();
2213 Ok(JsonnetValue::array(fields))
2214 }
2215
2216 fn object_has(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2217 Self::check_args(&args, 2, "objectHas")?;
2218 let obj = args[0].as_object()?;
2219 let key = args[1].as_string()?;
2220 Ok(JsonnetValue::boolean(obj.contains_key(key) && !key.starts_with('_')))
2221 }
2222
2223 fn object_has_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2224 Self::check_args(&args, 2, "objectHasAll")?;
2225 let obj = args[0].as_object()?;
2226 let key = args[1].as_string()?;
2227 Ok(JsonnetValue::boolean(obj.contains_key(key)))
2228 }
2229
2230 fn object_values(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2231 Self::check_args(&args, 1, "objectValues")?;
2232 let obj = args[0].as_object()?;
2233 let values: Vec<JsonnetValue> = obj.iter()
2234 .filter(|(k, _)| !k.starts_with('_'))
2235 .map(|(_, v)| v.clone())
2236 .collect();
2237 Ok(JsonnetValue::array(values))
2238 }
2239
2240 fn object_values_all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2241 Self::check_args(&args, 1, "objectValuesAll")?;
2242 let obj = args[0].as_object()?;
2243 let values: Vec<JsonnetValue> = obj.values().cloned().collect();
2244 Ok(JsonnetValue::array(values))
2245 }
2246
2247 fn prune(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2248 Self::check_args(&args, 1, "prune")?;
2249 Self::prune_value(&args[0])
2250 }
2251
2252 fn prune_value(value: &JsonnetValue) -> Result<JsonnetValue> {
2253 match value {
2254 JsonnetValue::Null => Ok(JsonnetValue::Null),
2255 JsonnetValue::Array(arr) => {
2256 let pruned: Vec<JsonnetValue> = arr.iter()
2257 .map(|item| Self::prune_value(item))
2258 .collect::<Result<Vec<_>>>()?
2259 .into_iter()
2260 .filter(|item| !matches!(item, JsonnetValue::Null))
2261 .collect();
2262 Ok(JsonnetValue::array(pruned))
2263 }
2264 JsonnetValue::Object(obj) => {
2265 let mut pruned_obj = HashMap::new();
2266 for (key, val) in obj {
2267 let pruned_val = Self::prune_value(val)?;
2268 if !matches!(pruned_val, JsonnetValue::Null) {
2269 pruned_obj.insert(key.clone(), pruned_val);
2270 }
2271 }
2272 Ok(JsonnetValue::object(pruned_obj))
2273 }
2274 _ => Ok(value.clone()),
2275 }
2276 }
2277
2278 fn map_with_key(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2279 Self::check_args(&args, 2, "mapWithKey")?;
2280 let _func = &args[0];
2281 let obj = args[1].as_object()?;
2282
2283 let mut result = HashMap::new();
2286 for (key, value) in obj {
2287 if !key.starts_with('_') {
2288 result.insert(key.clone(), JsonnetValue::array(vec![
2291 JsonnetValue::string(key.clone()),
2292 value.clone()
2293 ]));
2294 }
2295 }
2296
2297 Ok(JsonnetValue::object(result))
2298 }
2299
2300 fn object_fields_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2301 Self::check_args(&args, 2, "objectFieldsEx")?;
2302 let obj = args[0].as_object()?;
2303 let include_hidden = args[1].as_boolean()?;
2304
2305 let fields: Vec<JsonnetValue> = obj.keys()
2306 .filter(|&k| include_hidden || !k.starts_with('_'))
2307 .map(|k| JsonnetValue::string(k.clone()))
2308 .collect();
2309
2310 Ok(JsonnetValue::array(fields))
2311 }
2312
2313 fn object_values_ex(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2314 Self::check_args(&args, 2, "objectValuesEx")?;
2315 let obj = args[0].as_object()?;
2316 let include_hidden = args[1].as_boolean()?;
2317
2318 let values: Vec<JsonnetValue> = obj.iter()
2319 .filter(|(k, _)| include_hidden || !k.starts_with('_'))
2320 .map(|(_, v)| v.clone())
2321 .collect();
2322
2323 Ok(JsonnetValue::array(values))
2324 }
2325
2326 fn to_lower(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2327 Self::check_args(&args, 1, "toLower")?;
2328 match &args[0] {
2329 JsonnetValue::String(s) => Ok(JsonnetValue::string(s.to_lowercase())),
2330 _ => Err(JsonnetError::runtime_error("toLower expects a string argument")),
2331 }
2332 }
2333
2334 fn to_upper(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2335 Self::check_args(&args, 1, "toUpper")?;
2336 match &args[0] {
2337 JsonnetValue::String(s) => Ok(JsonnetValue::string(s.to_uppercase())),
2338 _ => Err(JsonnetError::runtime_error("toUpper expects a string argument")),
2339 }
2340 }
2341
2342 fn trim(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2343 Self::check_args(&args, 1, "trim")?;
2344 match &args[0] {
2345 JsonnetValue::String(s) => Ok(JsonnetValue::string(s.trim().to_string())),
2346 _ => Err(JsonnetError::runtime_error("trim expects a string argument")),
2347 }
2348 }
2349
2350 fn all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2351 Self::check_args(&args, 1, "all")?;
2352 match &args[0] {
2353 JsonnetValue::Array(arr) => {
2354 let result = arr.iter().all(|item| item.is_truthy());
2355 Ok(JsonnetValue::boolean(result))
2356 }
2357 _ => Err(JsonnetError::runtime_error("all expects an array argument")),
2358 }
2359 }
2360
2361 fn any(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2362 Self::check_args(&args, 1, "any")?;
2363 match &args[0] {
2364 JsonnetValue::Array(arr) => {
2365 let result = arr.iter().any(|item| item.is_truthy());
2366 Ok(JsonnetValue::boolean(result))
2367 }
2368 _ => Err(JsonnetError::runtime_error("any expects an array argument")),
2369 }
2370 }
2371
2372 fn id(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2373 Self::check_args(&args, 1, "id")?;
2374 Ok(args[0].clone())
2375 }
2376
2377 fn equals(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2378 Self::check_args(&args, 2, "equals")?;
2379 let a = &args[0];
2380 let b = &args[1];
2381
2382 if a == b {
2384 return Ok(JsonnetValue::boolean(true));
2385 }
2386
2387 let ta = a.type_name();
2389 let tb = b.type_name();
2390 if ta != tb {
2391 return Ok(JsonnetValue::boolean(false));
2392 }
2393
2394 match (a, b) {
2395 (JsonnetValue::Array(arr_a), JsonnetValue::Array(arr_b)) => {
2396 if arr_a.len() != arr_b.len() {
2397 return Ok(JsonnetValue::boolean(false));
2398 }
2399 for (i, item_a) in arr_a.iter().enumerate() {
2400 let eq_args = vec![item_a.clone(), arr_b[i].clone()];
2401 if let Ok(JsonnetValue::Boolean(false)) = Self::equals(eq_args) {
2402 return Ok(JsonnetValue::boolean(false));
2403 }
2404 }
2405 Ok(JsonnetValue::boolean(true))
2406 }
2407 (JsonnetValue::Object(obj_a), JsonnetValue::Object(obj_b)) => {
2408 let fields_a: Vec<String> = obj_a.keys().cloned().collect();
2410 let fields_b: Vec<String> = obj_b.keys().cloned().collect();
2411
2412 if fields_a.len() != fields_b.len() {
2413 return Ok(JsonnetValue::boolean(false));
2414 }
2415
2416 let mut sorted_a = fields_a.clone();
2418 sorted_a.sort();
2419 let mut sorted_b = fields_b.clone();
2420 sorted_b.sort();
2421
2422 if sorted_a != sorted_b {
2423 return Ok(JsonnetValue::boolean(false));
2424 }
2425
2426 for field in sorted_a {
2428 let val_a = &obj_a[&field];
2429 let val_b = &obj_b[&field];
2430 let eq_args = vec![val_a.clone(), val_b.clone()];
2431 if let Ok(JsonnetValue::Boolean(false)) = Self::equals(eq_args) {
2432 return Ok(JsonnetValue::boolean(false));
2433 }
2434 }
2435 Ok(JsonnetValue::boolean(true))
2436 }
2437 _ => Ok(JsonnetValue::boolean(false)),
2438 }
2439 }
2440
2441 fn lines(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2442 Self::check_args(&args, 1, "lines")?;
2443 match &args[0] {
2444 JsonnetValue::Array(arr) => {
2445 let mut lines = Vec::new();
2446 for item in arr {
2447 match item {
2449 JsonnetValue::String(s) => lines.push(s.clone()),
2450 JsonnetValue::Number(n) => lines.push(n.to_string()),
2451 JsonnetValue::Boolean(b) => lines.push(b.to_string()),
2452 _ => lines.push(format!("{}", item)),
2453 }
2454 }
2455 lines.push("".to_string()); Ok(JsonnetValue::string(lines.join("\n")))
2457 }
2458 _ => Err(JsonnetError::runtime_error("lines expects an array argument")),
2459 }
2460 }
2461
2462 fn str_replace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2463 Self::check_args(&args, 3, "strReplace")?;
2464
2465 let str_val = &args[0];
2466 let from_val = &args[1];
2467 let to_val = &args[2];
2468
2469 let str = str_val.as_string()?.to_string();
2470 let from = from_val.as_string()?.to_string();
2471 let to = to_val.as_string()?.to_string();
2472
2473 if from.is_empty() {
2474 return Err(JsonnetError::runtime_error("'from' string must not be zero length"));
2475 }
2476
2477 let result = str.replace(&from, &to);
2481 Ok(JsonnetValue::string(result))
2482 }
2483
2484 fn sha1(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2485 Self::check_args(&args, 1, "sha1")?;
2486 let input = args[0].as_string()?.as_bytes();
2487 let mut hasher = Sha1::new();
2488 hasher.update(input);
2489 let result = hasher.finalize();
2490 Ok(JsonnetValue::string(hex::encode(result)))
2491 }
2492
2493 fn sha256(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2494 Self::check_args(&args, 1, "sha256")?;
2495 let input = args[0].as_string()?.as_bytes();
2496 let mut hasher = Sha256::new();
2497 hasher.update(input);
2498 let result = hasher.finalize();
2499 Ok(JsonnetValue::string(hex::encode(result)))
2500 }
2501
2502 fn sha3(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2503 Self::check_args(&args, 1, "sha3")?;
2504 let input = args[0].as_string()?.as_bytes();
2505 let mut hasher = Sha3_256::new();
2506 hasher.update(input);
2507 let result = hasher.finalize();
2508 Ok(JsonnetValue::string(hex::encode(result)))
2509 }
2510
2511 fn sha512(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2512 Self::check_args(&args, 1, "sha512")?;
2513 let input = args[0].as_string()?.as_bytes();
2514 let mut hasher = Sha512::new();
2515 hasher.update(input);
2516 let result = hasher.finalize();
2517 Ok(JsonnetValue::string(hex::encode(result)))
2518 }
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533 fn manifest_ini(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2537 Self::check_args(&args, 1, "manifestIni")?;
2538 match &args[0] {
2540 JsonnetValue::Object(obj) => {
2541 let mut result = String::new();
2542 for (key, value) in obj {
2543 if !key.starts_with('_') {
2544 result.push_str(&format!("[{}]\n", key));
2545 if let JsonnetValue::Object(section) = value {
2546 for (k, v) in section {
2547 if !k.starts_with('_') {
2548 result.push_str(&format!("{}={}\n", k, v));
2549 }
2550 }
2551 }
2552 result.push('\n');
2553 }
2554 }
2555 Ok(JsonnetValue::string(result.trim().to_string()))
2556 }
2557 _ => Err(JsonnetError::runtime_error("manifestIni expects an object")),
2558 }
2559 }
2560
2561 fn manifest_python(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2562 Self::check_args(&args, 1, "manifestPython")?;
2563 let json_str = serde_json::to_string(&args[0].to_json_value())?;
2565 let python_str = json_str
2567 .replace("null", "None")
2568 .replace("true", "True")
2569 .replace("false", "False");
2570 Ok(JsonnetValue::string(python_str))
2571 }
2572
2573 fn manifest_cpp(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2574 Self::check_args(&args, 1, "manifestCpp")?;
2575 let json_str = serde_json::to_string(&args[0].to_json_value())?;
2577 let cpp_str = format!("// Generated C++ code\nconst char* jsonData = R\"json(\n{}\n)json\";", json_str);
2578 Ok(JsonnetValue::string(cpp_str))
2579 }
2580
2581 fn manifest_xml_jsonml(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2582 Self::check_args(&args, 1, "manifestXmlJsonml")?;
2583 match &args[0] {
2585 JsonnetValue::Array(arr) if !arr.is_empty() => {
2586 if let JsonnetValue::String(tag) = &arr[0] {
2587 let mut xml = format!("<{}", tag);
2588
2589 let mut child_start = 1;
2591 if arr.len() > 1 {
2592 if let JsonnetValue::Object(attrs) = &arr[1] {
2593 for (key, value) in attrs {
2594 if !key.starts_with('_') {
2595 let value_str = match value {
2596 JsonnetValue::String(s) => s.clone(),
2597 _ => format!("{}", value),
2598 };
2599 xml.push_str(&format!(" {}=\"{}\"", key, value_str));
2600 }
2601 }
2602 child_start = 2;
2603 }
2604 }
2605
2606 xml.push('>');
2607
2608 for child in &arr[child_start..] {
2610 match child {
2611 JsonnetValue::String(s) => xml.push_str(s),
2612 JsonnetValue::Array(_) => {
2613 let child_xml = Self::manifest_xml_jsonml(vec![child.clone()])?;
2615 if let JsonnetValue::String(child_str) = child_xml {
2616 xml.push_str(&child_str);
2617 }
2618 }
2619 _ => xml.push_str(&format!("{}", child)),
2620 }
2621 }
2622
2623 xml.push_str(&format!("</{}>", tag));
2624 Ok(JsonnetValue::string(xml))
2625 } else {
2626 Err(JsonnetError::runtime_error("JsonML array must start with string tag name"))
2627 }
2628 }
2629 _ => Err(JsonnetError::runtime_error("manifestXmlJsonml expects a JsonML array")),
2630 }
2631 }
2632
2633 fn log2(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2635 Self::check_args(&args, 1, "log2")?;
2636 let x = args[0].as_number()?;
2637 if x <= 0.0 {
2638 return Err(JsonnetError::runtime_error("log2 of non-positive number"));
2639 }
2640 Ok(JsonnetValue::number(x.log2()))
2641 }
2642
2643 fn log10(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2644 Self::check_args(&args, 1, "log10")?;
2645 let x = args[0].as_number()?;
2646 if x <= 0.0 {
2647 return Err(JsonnetError::runtime_error("log10 of non-positive number"));
2648 }
2649 Ok(JsonnetValue::number(x.log10()))
2650 }
2651
2652 fn log1p(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2653 Self::check_args(&args, 1, "log1p")?;
2654 let x = args[0].as_number()?;
2655 if x < -1.0 {
2656 return Err(JsonnetError::runtime_error("log1p of number less than -1"));
2657 }
2658 Ok(JsonnetValue::number((x + 1.0).ln()))
2659 }
2660
2661 fn expm1(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2662 Self::check_args(&args, 1, "expm1")?;
2663 let x = args[0].as_number()?;
2664 Ok(JsonnetValue::number(x.exp() - 1.0))
2665 }
2666
2667 fn remove(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2671 Self::check_args(&args, 2, "remove")?;
2672 let arr = args[0].as_array()?;
2673 let value_to_remove = &args[1];
2674
2675 let filtered: Vec<JsonnetValue> = arr.iter()
2676 .filter(|item| !item.equals(value_to_remove))
2677 .cloned()
2678 .collect();
2679
2680 Ok(JsonnetValue::array(filtered))
2681 }
2682
2683 fn remove_at(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2684 Self::check_args(&args, 2, "removeAt")?;
2685 let arr = args[0].as_array()?;
2686 let index = args[1].as_number()? as usize;
2687
2688 if index >= arr.len() {
2689 return Err(JsonnetError::runtime_error("Index out of bounds"));
2690 }
2691
2692 let mut result = arr.clone();
2693 result.remove(index);
2694 Ok(JsonnetValue::array(result))
2695 }
2696
2697 fn flatten_arrays(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2698 Self::check_args(&args, 1, "flattenArrays")?;
2699 let arr = args[0].as_array()?;
2700
2701 let mut result = Vec::new();
2702 Self::flatten_array_recursive(arr, &mut result);
2703 Ok(JsonnetValue::array(result))
2704 }
2705
2706 fn flatten_array_recursive(arr: &[JsonnetValue], result: &mut Vec<JsonnetValue>) {
2707 for item in arr {
2708 match item {
2709 JsonnetValue::Array(sub_arr) => {
2710 Self::flatten_array_recursive(sub_arr, result);
2711 }
2712 _ => result.push(item.clone()),
2713 }
2714 }
2715 }
2716
2717 fn object_keys_values(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2719 Self::check_args(&args, 1, "objectKeysValues")?;
2720 let obj = args[0].as_object()?;
2721
2722 let mut result = Vec::new();
2723 for (key, value) in obj {
2724 if !key.starts_with('_') {
2725 result.push(JsonnetValue::object(HashMap::from([
2726 ("key".to_string(), JsonnetValue::string(key.clone())),
2727 ("value".to_string(), value.clone()),
2728 ])));
2729 }
2730 }
2731
2732 Ok(JsonnetValue::array(result))
2733 }
2734
2735 fn object_remove_key(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2736 Self::check_args(&args, 2, "objectRemoveKey")?;
2737 let obj = args[0].as_object()?;
2738 let key_to_remove = args[1].as_string()?;
2739
2740 let mut result = obj.clone();
2741 result.remove(key_to_remove);
2742 Ok(JsonnetValue::object(result))
2743 }
2744
2745 fn is_integer(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2747 Self::check_args(&args, 1, "isInteger")?;
2748 match &args[0] {
2749 JsonnetValue::Number(n) => Ok(JsonnetValue::boolean(n.fract() == 0.0)),
2750 _ => Ok(JsonnetValue::boolean(false)),
2751 }
2752 }
2753
2754 fn is_decimal(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2755 Self::check_args(&args, 1, "isDecimal")?;
2756 match &args[0] {
2757 JsonnetValue::Number(n) => Ok(JsonnetValue::boolean(n.fract() != 0.0)),
2758 _ => Ok(JsonnetValue::boolean(false)),
2759 }
2760 }
2761
2762 fn is_even(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2763 Self::check_args(&args, 1, "isEven")?;
2764 match &args[0] {
2765 JsonnetValue::Number(n) if n.fract() == 0.0 => {
2766 Ok(JsonnetValue::boolean((*n as i64) % 2 == 0))
2767 }
2768 _ => Ok(JsonnetValue::boolean(false)),
2769 }
2770 }
2771
2772 fn is_odd(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2773 Self::check_args(&args, 1, "isOdd")?;
2774 match &args[0] {
2775 JsonnetValue::Number(n) if n.fract() == 0.0 => {
2776 Ok(JsonnetValue::boolean((*n as i64) % 2 != 0))
2777 }
2778 _ => Ok(JsonnetValue::boolean(false)),
2779 }
2780 }
2781
2782 fn check_args(args: &[JsonnetValue], expected: usize, func_name: &str) -> Result<()> {
2784 if args.len() != expected {
2785 return Err(JsonnetError::invalid_function_call(format!(
2786 "{}() expects {} arguments, got {}",
2787 func_name, expected, args.len()
2788 )));
2789 }
2790 Ok(())
2791 }
2792
2793 fn check_args_range(args: &[JsonnetValue], min: usize, max: usize, func_name: &str) -> Result<()> {
2795 if args.len() < min || args.len() > max {
2796 return Err(JsonnetError::invalid_function_call(format!(
2797 "{}() expects {} to {} arguments, got {}",
2798 func_name, min, max, args.len()
2799 )));
2800 }
2801 Ok(())
2802 }
2803
2804 pub fn call_function(name: &str, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2806 Err(JsonnetError::runtime_error(format!("StdLib function '{}' not implemented", name)))
2809 }
2810}
2811
2812impl JsonnetValue {
2813 pub fn from_json_value(value: serde_json::Value) -> Self {
2815 match value {
2816 serde_json::Value::Null => JsonnetValue::Null,
2817 serde_json::Value::Bool(b) => JsonnetValue::boolean(b),
2818 serde_json::Value::Number(n) => JsonnetValue::number(n.as_f64().unwrap_or(0.0)),
2819 serde_json::Value::String(s) => JsonnetValue::string(s),
2820 serde_json::Value::Array(arr) => {
2821 let jsonnet_arr: Vec<JsonnetValue> = arr.into_iter()
2822 .map(JsonnetValue::from_json_value)
2823 .collect();
2824 JsonnetValue::array(jsonnet_arr)
2825 }
2826 serde_json::Value::Object(obj) => {
2827 let mut jsonnet_obj = HashMap::new();
2828 for (k, v) in obj {
2829 jsonnet_obj.insert(k, JsonnetValue::from_json_value(v));
2830 }
2831 JsonnetValue::object(jsonnet_obj)
2832 }
2833 }
2834 }
2835
2836 pub fn slice(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2840 StdLib::check_args(&args, 2, "slice")?;
2841 let start = args[1].as_number()? as usize;
2842
2843 match &args[0] {
2844 JsonnetValue::Array(arr) => {
2845 let end = if args.len() > 2 {
2846 args[2].as_number()? as usize
2847 } else {
2848 arr.len()
2849 };
2850 let start = start.min(arr.len());
2851 let end = end.min(arr.len());
2852 if start > end {
2853 Ok(JsonnetValue::array(vec![]))
2854 } else {
2855 Ok(JsonnetValue::array(arr[start..end].to_vec()))
2856 }
2857 }
2858 JsonnetValue::String(s) => {
2859 let end = if args.len() > 2 {
2860 args[2].as_number()? as usize
2861 } else {
2862 s.chars().count()
2863 };
2864 let chars: Vec<char> = s.chars().collect();
2865 let start = start.min(chars.len());
2866 let end = end.min(chars.len());
2867 if start > end {
2868 Ok(JsonnetValue::string("".to_string()))
2869 } else {
2870 let sliced: String = chars[start..end].iter().collect();
2871 Ok(JsonnetValue::string(sliced))
2872 }
2873 }
2874 _ => Err(JsonnetError::invalid_function_call("slice() expects array or string as first argument".to_string())),
2875 }
2876 }
2877
2878 pub fn zip(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2880 if args.is_empty() {
2881 return Err(JsonnetError::invalid_function_call("zip() expects at least one argument".to_string()));
2882 }
2883
2884 let arrays: Result<Vec<Vec<JsonnetValue>>> = args.into_iter()
2886 .map(|arg| arg.as_array().cloned())
2887 .collect();
2888
2889 let arrays = arrays?;
2890 if arrays.is_empty() {
2891 return Ok(JsonnetValue::array(vec![]));
2892 }
2893
2894 let min_len = arrays.iter().map(|arr| arr.len()).min().unwrap_or(0);
2896
2897 let mut result = Vec::new();
2899 for i in 0..min_len {
2900 let mut tuple = Vec::new();
2901 for arr in &arrays {
2902 tuple.push(arr[i].clone());
2903 }
2904 result.push(JsonnetValue::array(tuple));
2905 }
2906
2907 Ok(JsonnetValue::array(result))
2908 }
2909
2910 pub fn transpose(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2912 StdLib::check_args(&args, 1, "transpose")?;
2913 let matrix = args[0].as_array()?;
2914
2915 if matrix.is_empty() {
2916 return Ok(JsonnetValue::array(vec![]));
2917 }
2918
2919 let mut max_len = 0;
2921 for row in matrix {
2922 match row {
2923 JsonnetValue::Array(arr) => {
2924 max_len = max_len.max(arr.len());
2925 }
2926 _ => return Err(JsonnetError::invalid_function_call("transpose() expects array of arrays".to_string())),
2927 }
2928 }
2929
2930 if max_len == 0 {
2931 return Ok(JsonnetValue::array(vec![]));
2932 }
2933
2934 let mut result = Vec::new();
2936 for col in 0..max_len {
2937 let mut new_row = Vec::new();
2938 for row in matrix {
2939 if let JsonnetValue::Array(arr) = row {
2940 if col < arr.len() {
2941 new_row.push(arr[col].clone());
2942 } else {
2943 new_row.push(JsonnetValue::Null);
2944 }
2945 }
2946 }
2947 result.push(JsonnetValue::array(new_row));
2948 }
2949
2950 Ok(JsonnetValue::array(result))
2951 }
2952
2953 pub fn flatten(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2955 StdLib::check_args(&args, 1, "flatten")?;
2956 let depth = if args.len() > 1 {
2957 args[1].as_number()? as usize
2958 } else {
2959 usize::MAX
2960 };
2961
2962 fn flatten_recursive(arr: &Vec<JsonnetValue>, current_depth: usize, max_depth: usize) -> Vec<JsonnetValue> {
2963 let mut result = Vec::new();
2964 for item in arr {
2965 match item {
2966 JsonnetValue::Array(nested) if current_depth < max_depth => {
2967 result.extend(flatten_recursive(nested, current_depth + 1, max_depth));
2968 }
2969 _ => result.push(item.clone()),
2970 }
2971 }
2972 result
2973 }
2974
2975 let arr = args[0].as_array()?;
2976 let flattened = flatten_recursive(arr, 0, depth);
2977 Ok(JsonnetValue::array(flattened))
2978 }
2979
2980 pub fn sum(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2982 StdLib::check_args(&args, 1, "sum")?;
2983 let arr = args[0].as_array()?;
2984
2985 let mut total = 0.0;
2986 for item in arr {
2987 total += item.as_number()?;
2988 }
2989
2990 Ok(JsonnetValue::number(total))
2991 }
2992
2993 pub fn product(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
2995 StdLib::check_args(&args, 1, "product")?;
2996 let arr = args[0].as_array()?;
2997
2998 let mut result = 1.0;
2999 for item in arr {
3000 result *= item.as_number()?;
3001 }
3002
3003 Ok(JsonnetValue::number(result))
3004 }
3005
3006 pub fn all(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3008 StdLib::check_args(&args, 1, "all")?;
3009 let arr = args[0].as_array()?;
3010
3011 for item in arr {
3012 if !item.is_truthy() {
3013 return Ok(JsonnetValue::boolean(false));
3014 }
3015 }
3016
3017 Ok(JsonnetValue::boolean(true))
3018 }
3019
3020 pub fn any(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3022 StdLib::check_args(&args, 1, "any")?;
3023 let arr = args[0].as_array()?;
3024
3025 for item in arr {
3026 if item.is_truthy() {
3027 return Ok(JsonnetValue::boolean(true));
3028 }
3029 }
3030
3031 Ok(JsonnetValue::boolean(false))
3032 }
3033
3034 pub fn sort_by(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3036 StdLib::check_args(&args, 2, "sortBy")?;
3037 let _arr = args[0].as_array()?.clone();
3038 let _key_func = &args[1];
3039
3040 Err(JsonnetError::runtime_error("sortBy() requires function calling mechanism - placeholder implementation".to_string()))
3043 }
3044
3045 pub fn group_by(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3047 StdLib::check_args(&args, 2, "groupBy")?;
3048 Err(JsonnetError::runtime_error("groupBy() requires function calling mechanism - placeholder implementation".to_string()))
3050 }
3051
3052 pub fn partition(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3054 StdLib::check_args(&args, 2, "partition")?;
3055 Err(JsonnetError::runtime_error("partition() requires function calling mechanism - placeholder implementation".to_string()))
3057 }
3058
3059 pub fn chunk(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3061 StdLib::check_args(&args, 2, "chunk")?;
3062 let arr = args[0].as_array()?;
3063 let size = args[1].as_number()? as usize;
3064
3065 if size == 0 {
3066 return Err(JsonnetError::invalid_function_call("chunk() size must be positive".to_string()));
3067 }
3068
3069 let mut result = Vec::new();
3070 for chunk in arr.chunks(size) {
3071 result.push(JsonnetValue::array(chunk.to_vec()));
3072 }
3073
3074 Ok(JsonnetValue::array(result))
3075 }
3076
3077 pub fn unique(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3079 StdLib::check_args(&args, 1, "unique")?;
3080 let arr = args[0].as_array()?;
3081
3082 let mut seen = std::collections::HashSet::new();
3083 let mut result = Vec::new();
3084
3085 for item in arr {
3086 if !seen.contains(&format!("{:?}", item)) {
3088 seen.insert(format!("{:?}", item));
3089 result.push(item.clone());
3090 }
3091 }
3092
3093 Ok(JsonnetValue::array(result))
3094 }
3095
3096 pub fn difference(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3098 if args.is_empty() {
3099 return Ok(JsonnetValue::array(vec![]));
3100 }
3101
3102 let first = args[0].as_array()?;
3103 let mut result = first.clone();
3104
3105 for arg in &args[1..] {
3106 let other = arg.as_array()?;
3107 let other_set: std::collections::HashSet<String> = other.iter()
3108 .map(|v| format!("{:?}", v))
3109 .collect();
3110
3111 result.retain(|item| !other_set.contains(&format!("{:?}", item)));
3112 }
3113
3114 Ok(JsonnetValue::array(result))
3115 }
3116
3117 pub fn intersection(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3119 if args.is_empty() {
3120 return Ok(JsonnetValue::array(vec![]));
3121 }
3122
3123 let first = args[0].as_array()?;
3124 let mut result = first.clone();
3125
3126 for arg in &args[1..] {
3127 let other = arg.as_array()?;
3128 let other_set: std::collections::HashSet<String> = other.iter()
3129 .map(|v| format!("{:?}", v))
3130 .collect();
3131
3132 result.retain(|item| other_set.contains(&format!("{:?}", item)));
3133 }
3134
3135 Ok(JsonnetValue::array(result))
3136 }
3137
3138 pub fn symmetric_difference(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3140 StdLib::check_args(&args, 2, "symmetricDifference")?;
3141 let a = args[0].as_array()?;
3142 let b = args[1].as_array()?;
3143
3144 let a_set: std::collections::HashSet<String> = a.iter()
3145 .map(|v| format!("{:?}", v))
3146 .collect();
3147 let b_set: std::collections::HashSet<String> = b.iter()
3148 .map(|v| format!("{:?}", v))
3149 .collect();
3150
3151 let symmetric_diff: std::collections::HashSet<_> = a_set.symmetric_difference(&b_set).cloned().collect();
3152
3153 let mut result: Vec<JsonnetValue> = a.iter()
3154 .filter(|item| symmetric_diff.contains(&format!("{:?}", item)))
3155 .chain(b.iter().filter(|item| symmetric_diff.contains(&format!("{:?}", item))))
3156 .cloned()
3157 .collect();
3158
3159 Ok(JsonnetValue::array(result))
3160 }
3161
3162 pub fn is_subset(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3164 StdLib::check_args(&args, 2, "isSubset")?;
3165 let a = args[0].as_array()?;
3166 let b = args[1].as_array()?;
3167
3168 let b_set: std::collections::HashSet<String> = b.iter()
3169 .map(|v| format!("{:?}", v))
3170 .collect();
3171
3172 let is_subset = a.iter().all(|item| b_set.contains(&format!("{:?}", item)));
3173
3174 Ok(JsonnetValue::boolean(is_subset))
3175 }
3176
3177 pub fn is_superset(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3179 StdLib::check_args(&args, 2, "isSuperset")?;
3180 let a = args[0].as_array()?;
3181 let b = args[1].as_array()?;
3182
3183 let a_set: std::collections::HashSet<String> = a.iter()
3184 .map(|v| format!("{:?}", v))
3185 .collect();
3186
3187 let is_superset = b.iter().all(|item| a_set.contains(&format!("{:?}", item)));
3188
3189 Ok(JsonnetValue::boolean(is_superset))
3190 }
3191
3192 pub fn is_disjoint(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3194 StdLib::check_args(&args, 2, "isDisjoint")?;
3195 let a = args[0].as_array()?;
3196 let b = args[1].as_array()?;
3197
3198 let a_set: std::collections::HashSet<String> = a.iter()
3199 .map(|v| format!("{:?}", v))
3200 .collect();
3201 let b_set: std::collections::HashSet<String> = b.iter()
3202 .map(|v| format!("{:?}", v))
3203 .collect();
3204
3205 let is_disjoint = a_set.intersection(&b_set).count() == 0;
3206
3207 Ok(JsonnetValue::boolean(is_disjoint))
3208 }
3209
3210 pub fn cartesian(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3212 StdLib::check_args(&args, 1, "cartesian")?;
3213 let arrays = args[0].as_array()?;
3214
3215 if arrays.is_empty() {
3216 return Ok(JsonnetValue::array(vec![JsonnetValue::array(vec![])]));
3217 }
3218
3219 let mut vec_arrays = Vec::new();
3221 for arr in arrays {
3222 vec_arrays.push(arr.as_array()?.clone());
3223 }
3224
3225 fn cartesian_product(arrays: &[Vec<JsonnetValue>]) -> Vec<Vec<JsonnetValue>> {
3226 if arrays.is_empty() {
3227 return vec![vec![]];
3228 }
3229
3230 let mut result = Vec::new();
3231 let first = &arrays[0];
3232 let rest = &arrays[1..];
3233
3234 for item in first {
3235 for mut combo in cartesian_product(rest) {
3236 combo.insert(0, item.clone());
3237 result.push(combo);
3238 }
3239 }
3240
3241 result
3242 }
3243
3244 let products = cartesian_product(&vec_arrays);
3245 let result: Vec<JsonnetValue> = products.into_iter()
3246 .map(|combo| JsonnetValue::array(combo))
3247 .collect();
3248
3249 Ok(JsonnetValue::array(result))
3250 }
3251
3252 pub fn cross(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3254 StdLib::check_args(&args, 2, "cross")?;
3255 let a = args[0].as_array()?;
3256 let b = args[1].as_array()?;
3257
3258 let mut result = Vec::new();
3259 for item_a in a {
3260 for item_b in b {
3261 result.push(JsonnetValue::array(vec![item_a.clone(), item_b.clone()]));
3262 }
3263 }
3264
3265 Ok(JsonnetValue::array(result))
3266 }
3267
3268 pub fn dot(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3270 StdLib::check_args(&args, 2, "dot")?;
3271 let a = args[0].as_array()?;
3272 let b = args[1].as_array()?;
3273
3274 if a.len() != b.len() {
3275 return Err(JsonnetError::invalid_function_call("dot() arrays must have same length".to_string()));
3276 }
3277
3278 let mut sum = 0.0;
3279 for (x, y) in a.iter().zip(b.iter()) {
3280 sum += x.as_number()? * y.as_number()?;
3281 }
3282
3283 Ok(JsonnetValue::number(sum))
3284 }
3285
3286 pub fn norm(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3288 StdLib::check_args(&args, 1, "norm")?;
3289 let arr = args[0].as_array()?;
3290
3291 let mut sum_squares = 0.0;
3292 for item in arr {
3293 let val = item.as_number()?;
3294 sum_squares += val * val;
3295 }
3296
3297 Ok(JsonnetValue::number(sum_squares.sqrt()))
3298 }
3299
3300 pub fn normalize(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3302 StdLib::check_args(&args, 1, "normalize")?;
3303 let arr = args[0].as_array()?;
3304
3305 let mut sum_squares = 0.0;
3307 for item in arr {
3308 let val = item.as_number()?;
3309 sum_squares += val * val;
3310 }
3311 let norm_val = sum_squares.sqrt();
3312 if norm_val == 0.0 {
3313 return Ok(args[0].clone());
3314 }
3315
3316 let mut result = Vec::new();
3317 for item in arr {
3318 let val = item.as_number()?;
3319 result.push(JsonnetValue::number(val / norm_val));
3320 }
3321
3322 Ok(JsonnetValue::array(result))
3323 }
3324
3325 pub fn distance(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3327 StdLib::check_args(&args, 2, "distance")?;
3328 let a = args[0].as_array()?;
3329 let b = args[1].as_array()?;
3330
3331 if a.len() != b.len() {
3332 return Err(JsonnetError::invalid_function_call("distance() arrays must have same length".to_string()));
3333 }
3334
3335 let mut sum_squares = 0.0;
3336 for (x, y) in a.iter().zip(b.iter()) {
3337 let diff = x.as_number()? - y.as_number()?;
3338 sum_squares += diff * diff;
3339 }
3340
3341 Ok(JsonnetValue::number(sum_squares.sqrt()))
3342 }
3343
3344 pub fn angle(&mut self, args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3346 StdLib::check_args(&args, 2, "angle")?;
3347 let a = args[0].as_array()?;
3348 let b = args[1].as_array()?;
3349
3350 if a.len() != b.len() {
3351 return Err(JsonnetError::invalid_function_call("angle() arrays must have same length".to_string()));
3352 }
3353
3354 let mut dot_product = 0.0;
3356 for (x, y) in a.iter().zip(b.iter()) {
3357 dot_product += x.as_number()? * y.as_number()?;
3358 }
3359
3360 let mut norm_a_sq = 0.0;
3362 for item in a {
3363 let val = item.as_number()?;
3364 norm_a_sq += val * val;
3365 }
3366 let norm_a = norm_a_sq.sqrt();
3367
3368 let mut norm_b_sq = 0.0;
3369 for item in b {
3370 let val = item.as_number()?;
3371 norm_b_sq += val * val;
3372 }
3373 let norm_b = norm_b_sq.sqrt();
3374
3375 if norm_a == 0.0 || norm_b == 0.0 {
3376 return Ok(JsonnetValue::number(0.0));
3377 }
3378
3379 let cos_theta = dot_product / (norm_a * norm_b);
3380 let cos_theta = cos_theta.max(-1.0).min(1.0); Ok(JsonnetValue::number(cos_theta.acos()))
3383 }
3384
3385 pub fn rotate(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3387 StdLib::check_args(&args, 2, "rotate")?;
3388 let point = args[0].as_array()?;
3389 let angle = args[1].as_number()?;
3390
3391 if point.len() != 2 {
3392 return Err(JsonnetError::invalid_function_call("rotate() point must be 2D".to_string()));
3393 }
3394
3395 let center = if args.len() > 2 {
3396 args[2].as_array()?.to_vec()
3397 } else {
3398 vec![JsonnetValue::number(0.0), JsonnetValue::number(0.0)]
3399 };
3400
3401 if center.len() != 2 {
3402 return Err(JsonnetError::invalid_function_call("rotate() center must be 2D".to_string()));
3403 }
3404
3405 let x = point[0].as_number()? - center[0].as_number()?;
3406 let y = point[1].as_number()? - center[1].as_number()?;
3407
3408 let cos_a = angle.cos();
3409 let sin_a = angle.sin();
3410
3411 let new_x = x * cos_a - y * sin_a + center[0].as_number()?;
3412 let new_y = x * sin_a + y * cos_a + center[1].as_number()?;
3413
3414 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3415 }
3416
3417 pub fn scale(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3419 StdLib::check_args(&args, 2, "scale")?;
3420 let point = args[0].as_array()?;
3421 let factor = args[1].as_number()?;
3422
3423 if point.len() != 2 {
3424 return Err(JsonnetError::invalid_function_call("scale() point must be 2D".to_string()));
3425 }
3426
3427 let center = if args.len() > 2 {
3428 args[2].as_array()?.to_vec()
3429 } else {
3430 vec![JsonnetValue::number(0.0), JsonnetValue::number(0.0)]
3431 };
3432
3433 if center.len() != 2 {
3434 return Err(JsonnetError::invalid_function_call("scale() center must be 2D".to_string()));
3435 }
3436
3437 let x = point[0].as_number()? - center[0].as_number()?;
3438 let y = point[1].as_number()? - center[1].as_number()?;
3439
3440 let new_x = x * factor + center[0].as_number()?;
3441 let new_y = y * factor + center[1].as_number()?;
3442
3443 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3444 }
3445
3446 pub fn translate(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3448 StdLib::check_args(&args, 2, "translate")?;
3449 let point = args[0].as_array()?;
3450 let offset = args[1].as_array()?;
3451
3452 if point.len() != 2 || offset.len() != 2 {
3453 return Err(JsonnetError::invalid_function_call("translate() requires 2D point and offset".to_string()));
3454 }
3455
3456 let new_x = point[0].as_number()? + offset[0].as_number()?;
3457 let new_y = point[1].as_number()? + offset[1].as_number()?;
3458
3459 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3460 }
3461
3462 pub fn reflect(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3464 StdLib::check_args(&args, 2, "reflect")?;
3465 let point = args[0].as_array()?;
3466 let axis = args[1].as_number()?; if point.len() != 2 {
3469 return Err(JsonnetError::invalid_function_call("reflect() point must be 2D".to_string()));
3470 }
3471
3472 let x = point[0].as_number()?;
3473 let y = point[1].as_number()?;
3474
3475 let cos_2a = (2.0 * axis).cos();
3476 let sin_2a = (2.0 * axis).sin();
3477
3478 let new_x = x * cos_2a + y * sin_2a;
3479 let new_y = x * sin_2a - y * cos_2a;
3480
3481 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3482 }
3483
3484 pub fn affine(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3486 StdLib::check_args(&args, 2, "affine")?;
3487 let point = args[0].as_array()?;
3488 let matrix = args[1].as_array()?;
3489
3490 if point.len() != 2 {
3491 return Err(JsonnetError::invalid_function_call("affine() point must be 2D".to_string()));
3492 }
3493
3494 if matrix.len() != 6 {
3495 return Err(JsonnetError::invalid_function_call("affine() matrix must be 6 elements [a,b,c,d,e,f]".to_string()));
3496 }
3497
3498 let x = point[0].as_number()?;
3499 let y = point[1].as_number()?;
3500
3501 let a = matrix[0].as_number()?;
3502 let b = matrix[1].as_number()?;
3503 let c = matrix[2].as_number()?;
3504 let d = matrix[3].as_number()?;
3505 let e = matrix[4].as_number()?;
3506 let f = matrix[5].as_number()?;
3507
3508 let new_x = a * x + b * y + e;
3509 let new_y = c * x + d * y + f;
3510
3511 Ok(JsonnetValue::array(vec![JsonnetValue::number(new_x), JsonnetValue::number(new_y)]))
3512 }
3513
3514 pub fn split_limit(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3516 StdLib::check_args(&args, 3, "splitLimit")?;
3517 let s = args[0].as_string()?;
3518 let sep = args[1].as_string()?;
3519 let limit = args[2].as_number()? as usize;
3520
3521 if sep.is_empty() {
3522 let chars: Vec<String> = s.chars().take(limit).map(|c| c.to_string()).collect();
3524 let result: Vec<JsonnetValue> = chars.into_iter().map(JsonnetValue::string).collect();
3525 return Ok(JsonnetValue::array(result));
3526 }
3527
3528 let mut parts: Vec<&str> = s.splitn(limit + 1, &sep).collect();
3529 if parts.len() > limit {
3530 let remaining = parts.split_off(limit);
3532 parts.push(&s[(s.len() - remaining.join(&sep).len())..]);
3533 }
3534
3535 let result: Vec<JsonnetValue> = parts.into_iter().map(|s| JsonnetValue::string(s.to_string())).collect();
3536 Ok(JsonnetValue::array(result))
3537 }
3538
3539 pub fn join_variadic(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3541 if args.is_empty() {
3542 return Err(JsonnetError::invalid_function_call("join() expects at least one argument".to_string()));
3543 }
3544
3545 let sep = args[0].as_string()?;
3546 let arrays: Result<Vec<Vec<JsonnetValue>>> = args[1..].iter()
3547 .map(|arg| arg.as_array().cloned())
3548 .collect();
3549
3550 let arrays = arrays?;
3551 let mut result = Vec::new();
3552
3553 for (i, arr) in arrays.iter().enumerate() {
3554 if i > 0 && !sep.is_empty() {
3555 result.push(JsonnetValue::string(sep.clone()));
3556 }
3557 result.extend(arr.iter().cloned());
3558 }
3559
3560 Ok(JsonnetValue::array(result))
3561 }
3562
3563 pub fn replace(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3565 StdLib::check_args(&args, 3, "replace")?;
3566 let s = args[0].as_string()?;
3567 let old = args[1].as_string()?;
3568 let new = args[2].as_string()?;
3569
3570 let result = s.replace(&old, &new);
3571 Ok(JsonnetValue::string(result))
3572 }
3573
3574 pub fn contains_variadic(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3576 StdLib::check_args(&args, 2, "contains")?;
3577
3578 match &args[0] {
3579 JsonnetValue::Array(arr) => {
3580 let target = format!("{:?}", &args[1]);
3582 for item in arr {
3583 if format!("{:?}", item) == target {
3584 return Ok(JsonnetValue::boolean(true));
3585 }
3586 }
3587 Ok(JsonnetValue::boolean(false))
3588 }
3589 JsonnetValue::String(s) => {
3590 let substr = args[1].as_string()?;
3591 Ok(JsonnetValue::boolean(s.contains(&substr)))
3592 }
3593 JsonnetValue::Object(obj) => {
3594 let key = args[1].as_string()?;
3595 Ok(JsonnetValue::boolean(obj.contains_key(&*key)))
3596 }
3597 _ => Err(JsonnetError::invalid_function_call("contains() expects array, string, or object".to_string())),
3598 }
3599 }
3600
3601 pub fn ai_http_get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3607 StdLib::check_args_range(&args, 1, 2, "ai.httpGet")?;
3608 let url = args[0].as_string()?;
3609 let headers = if args.len() > 1 {
3610 args[1].as_object()?.clone()
3611 } else {
3612 HashMap::new()
3613 };
3614
3615 let result = json!({
3618 "url": url,
3619 "method": "GET",
3620 "headers": headers,
3621 "status": "pending",
3622 "body": "HTTP request will be executed by runtime"
3623 });
3624 Ok(JsonnetValue::from_json_value(result))
3625 }
3626
3627 pub fn ai_http_post(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3629 StdLib::check_args_range(&args, 2, 3, "ai.httpPost")?;
3630 let url = args[0].as_string()?;
3631 let body = args[1].clone();
3632 let headers = if args.len() > 2 {
3633 args[2].as_object()?.clone()
3634 } else {
3635 HashMap::new()
3636 };
3637
3638 let result = json!({
3640 "url": url,
3641 "method": "POST",
3642 "body": body,
3643 "headers": headers,
3644 "status": "pending"
3645 });
3646 Ok(JsonnetValue::from_json_value(result))
3647 }
3648
3649 pub fn ai_call_model(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3651 StdLib::check_args_range(&args, 2, 3, "ai.callModel")?;
3652 let model = args[0].as_string()?;
3653 let messages = args[1].as_array()?.clone();
3654 let options = if args.len() > 2 {
3655 args[2].as_object()?.clone()
3656 } else {
3657 HashMap::new()
3658 };
3659
3660 let result = json!({
3662 "model": model,
3663 "messages": messages,
3664 "options": options,
3665 "status": "pending",
3666 "response": "AI model response will be generated by runtime"
3667 });
3668 Ok(JsonnetValue::from_json_value(result))
3669 }
3670
3671 pub fn tool_execute(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3673 StdLib::check_args_range(&args, 1, 3, "tool.execute")?;
3674 let command = args[0].as_string()?;
3675 let cmd_args = if args.len() > 1 {
3676 args[1].as_array()?.clone()
3677 } else {
3678 Vec::new()
3679 };
3680 let env = if args.len() > 2 {
3681 args[2].as_object()?.clone()
3682 } else {
3683 HashMap::new()
3684 };
3685
3686 let result = json!({
3688 "command": command,
3689 "args": cmd_args,
3690 "env": env,
3691 "status": "pending",
3692 "output": "Command will be executed by runtime"
3693 });
3694 Ok(JsonnetValue::from_json_value(result))
3695 }
3696
3697 pub fn memory_get(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3699 StdLib::check_args(&args, 1, "memory.get")?;
3700 let key = args[0].as_string()?;
3701
3702 let result = json!({
3704 "key": key,
3705 "operation": "get",
3706 "status": "pending",
3707 "value": null
3708 });
3709 Ok(JsonnetValue::from_json_value(result))
3710 }
3711
3712 pub fn memory_set(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3714 StdLib::check_args(&args, 2, "memory.set")?;
3715 let key = args[0].as_string()?;
3716 let value = args[1].clone();
3717
3718 let result = json!({
3720 "key": key,
3721 "value": value,
3722 "operation": "set",
3723 "status": "pending"
3724 });
3725 Ok(JsonnetValue::from_json_value(result))
3726 }
3727
3728 pub fn agent_create(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3730 StdLib::check_args(&args, 2, "agent.create")?;
3731 let agent_type = args[0].as_string()?;
3732 let config = args[1].as_object()?.clone();
3733
3734 let result = json!({
3736 "type": agent_type,
3737 "config": config,
3738 "id": "agent_id_placeholder",
3739 "status": "created"
3740 });
3741 Ok(JsonnetValue::from_json_value(result))
3742 }
3743
3744 pub fn agent_execute(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3746 StdLib::check_args(&args, 2, "agent.execute")?;
3747 let agent = args[0].clone();
3748 let input = args[1].as_string()?;
3749
3750 let result = json!({
3752 "agent": agent,
3753 "input": input,
3754 "status": "pending",
3755 "output": "Agent execution will be handled by runtime"
3756 });
3757 Ok(JsonnetValue::from_json_value(result))
3758 }
3759
3760 pub fn chain_create(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3762 StdLib::check_args(&args, 1, "chain.create")?;
3763 let steps = args[0].as_array()?.clone();
3764
3765 let result = json!({
3767 "steps": steps,
3768 "id": "chain_id_placeholder",
3769 "status": "created"
3770 });
3771 Ok(JsonnetValue::from_json_value(result))
3772 }
3773
3774 pub fn chain_execute(args: Vec<JsonnetValue>) -> Result<JsonnetValue> {
3776 StdLib::check_args(&args, 2, "chain.execute")?;
3777 let chain = args[0].clone();
3778 let input = args[1].clone();
3779
3780 let result = json!({
3782 "chain": chain,
3783 "input": input,
3784 "status": "pending",
3785 "output": "Chain execution will be handled by runtime"
3786 });
3787 Ok(JsonnetValue::from_json_value(result))
3788 }
3789
3790}