1pub mod ast;
52pub mod error;
54pub mod eval;
56pub mod evaluator;
58pub mod lexer;
60pub mod parser;
62pub mod runtime;
64pub mod stdlib;
66pub mod value;
68
69pub mod pure_evaluator;
72
73pub use error::{JsonnetError, Result};
74pub use evaluator::Evaluator;
75pub use parser::Parser;
76pub use value::JsonnetValue;
77
78pub use pure_evaluator::PureEvaluator;
80
81pub fn evaluate(source: &str) -> Result<JsonnetValue> {
107 evaluate_with_filename(source, "<string>")
108}
109
110pub fn evaluate_with_filename(source: &str, filename: &str) -> Result<JsonnetValue> {
134 let mut evaluator = Evaluator::new();
135 evaluator.evaluate_file(source, filename)
136}
137
138pub fn evaluate_to_json(source: &str) -> Result<String> {
161 let value = evaluate(source).map_err(|e| {
162 eprintln!("Evaluation error: {:?}", e);
163 e
164 })?;
165 let json_value = value.to_json_value();
166 serde_json::to_string_pretty(&json_value).map_err(|e| {
167 eprintln!("JSON serialization error: {:?}", e);
168 JsonnetError::runtime_error(&format!("JSON serialization failed: {}", e))
169 })
170}
171
172#[cfg(feature = "yaml")]
197pub fn evaluate_to_yaml(source: &str) -> Result<String> {
198 let value = evaluate(source)?;
199 Ok(serde_yaml::to_string(&value.to_json_value())?)
200}
201
202pub const VERSION: &str = env!("CARGO_PKG_VERSION");
204
205#[cfg(test)]
206mod tests {
207 use super::*;
208
209 #[test]
210 fn test_basic_evaluation() {
211 let result = evaluate(r#""Hello, World!""#);
212 assert!(result.is_ok());
213 if let JsonnetValue::String(s) = result.unwrap() {
214 assert_eq!(s, "Hello, World!");
215 } else {
216 panic!("Expected string value");
217 }
218 }
219
220 #[test]
221 fn test_number_evaluation() {
222 let result = evaluate("42");
223 assert!(result.is_ok());
224 if let JsonnetValue::Number(n) = result.unwrap() {
225 assert_eq!(n, 42.0);
226 } else {
227 panic!("Expected number value");
228 }
229 }
230
231 #[test]
232 fn test_boolean_evaluation() {
233 let result = evaluate("true");
234 assert!(result.is_ok());
235 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
236 }
237
238 #[test]
239 fn test_null_evaluation() {
240 let result = evaluate("null");
241 assert!(result.is_ok());
242 assert_eq!(result.unwrap(), JsonnetValue::Null);
243 }
244
245 #[test]
246 fn test_local_variables() {
247 let result = evaluate(r#"local x = 42; x"#);
248 if let Err(ref e) = result {
249 println!("Error: {:?}", e);
250 }
251 assert!(result.is_ok());
252 if let JsonnetValue::Number(n) = result.unwrap() {
253 assert_eq!(n, 42.0);
254 } else {
255 panic!("Expected number value");
256 }
257 }
258
259 #[test]
260 fn test_local_expressions() {
261 let result = evaluate(r#"local x = 10, y = 20; x + y"#);
263 assert!(result.is_ok());
264 assert_eq!(result.unwrap(), JsonnetValue::Number(30.0));
265
266 let result = evaluate(r#"local add = function(a) local b = 5; a + b; add(3)"#);
268 assert!(result.is_ok());
269 assert_eq!(result.unwrap(), JsonnetValue::Number(8.0));
270
271 let result = evaluate(r#"local name = "alice"; { username: name, age: 25 }"#);
273 assert!(result.is_ok());
274 if let JsonnetValue::Object(obj) = result.unwrap() {
275 assert_eq!(obj.get("username"), Some(&JsonnetValue::String("alice".to_string())));
276 assert_eq!(obj.get("age"), Some(&JsonnetValue::Number(25.0)));
277 } else {
278 panic!("Expected object value");
279 }
280 }
281
282 #[test]
283 fn test_arithmetic() {
284 let result = evaluate("2 + 3 * 4");
285 assert!(result.is_ok());
286 if let JsonnetValue::Number(n) = result.unwrap() {
287 assert_eq!(n, 14.0); } else {
289 panic!("Expected number value");
290 }
291 }
292
293 #[test]
294 fn test_comparison_operators() {
295 let result = evaluate("5 == 5");
297 assert!(result.is_ok());
298 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
299
300 let result = evaluate("5 != 3");
301 assert!(result.is_ok());
302 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
303
304 let result = evaluate("3 < 5");
306 assert!(result.is_ok());
307 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
308
309 let result = evaluate("5 > 3");
310 assert!(result.is_ok());
311 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
312
313 let result = evaluate("5 <= 5");
314 assert!(result.is_ok());
315 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
316
317 let result = evaluate("5 >= 5");
318 assert!(result.is_ok());
319 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
320 }
321
322 #[test]
323 fn test_logical_operators() {
324 let result = evaluate("true && true");
326 assert!(result.is_ok());
327 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
328
329 let result = evaluate("true && false");
330 assert!(result.is_ok());
331 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
332
333 let result = evaluate("false || true");
335 assert!(result.is_ok());
336 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
337
338 let result = evaluate("false || false");
339 assert!(result.is_ok());
340 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
341
342 let result = evaluate("!false");
344 assert!(result.is_ok());
345 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
346
347 let result = evaluate("!true");
348 assert!(result.is_ok());
349 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
350 }
351
352 #[test]
353 fn test_object_creation() {
354 let result = evaluate(r#"{ name: "test", value: 123 }"#);
355 assert!(result.is_ok());
356 if let JsonnetValue::Object(obj) = result.unwrap() {
357 assert_eq!(obj.get("name"), Some(&JsonnetValue::String("test".to_string())));
358 assert_eq!(obj.get("value"), Some(&JsonnetValue::Number(123.0)));
359 } else {
360 panic!("Expected object value");
361 }
362 }
363
364 #[test]
365 fn test_object_field_access() {
366 let result = evaluate(r#"{ name: "test", value: 123 }.name"#);
368 assert!(result.is_ok());
369 assert_eq!(result.unwrap(), JsonnetValue::String("test".to_string()));
370
371 let result = evaluate(r#"{ user: { name: "alice", age: 30 } }.user.name"#);
373 assert!(result.is_ok());
374 assert_eq!(result.unwrap(), JsonnetValue::String("alice".to_string()));
375
376 let result = evaluate(r#"[10, 20, 30][1]"#);
378 println!("Array bracket notation result: {:?}", result);
379 if result.is_ok() {
380 assert_eq!(result.unwrap(), JsonnetValue::Number(20.0));
381 }
382
383 let result = evaluate(r#"{ "field-name": "value" }["field-name"]"#);
385 println!("Object bracket notation result: {:?}", result);
386 assert!(result.is_ok(), "Bracket notation should work: {:?}", result.err());
387 assert_eq!(result.unwrap(), JsonnetValue::String("value".to_string()));
388 }
389
390 #[test]
391 fn test_array_creation() {
392 let result = evaluate(r#"[1, 2, 3]"#);
393 assert!(result.is_ok());
394 if let JsonnetValue::Array(arr) = result.unwrap() {
395 assert_eq!(arr.len(), 3);
396 assert_eq!(arr[0], JsonnetValue::Number(1.0));
397 assert_eq!(arr[1], JsonnetValue::Number(2.0));
398 assert_eq!(arr[2], JsonnetValue::Number(3.0));
399 } else {
400 panic!("Expected array value");
401 }
402 }
403
404 #[test]
405 fn test_array_index_access() {
406 let result = evaluate(r#"[10, 20, 30][1]"#);
408 assert!(result.is_ok());
409 assert_eq!(result.unwrap(), JsonnetValue::Number(20.0));
410
411 let result = evaluate(r#"[10, 20, 30][0]"#);
413 assert!(result.is_ok());
414 assert_eq!(result.unwrap(), JsonnetValue::Number(10.0));
415
416 let result = evaluate(r#"[10, 20, 30][2]"#);
418 assert!(result.is_ok());
419 assert_eq!(result.unwrap(), JsonnetValue::Number(30.0));
420
421 let result = evaluate(r#"[[1, 2], [3, 4]][1][0]"#);
423 assert!(result.is_ok());
424 assert_eq!(result.unwrap(), JsonnetValue::Number(3.0));
425 }
426
427 #[test]
428 fn test_array_comprehension() {
429 let result = evaluate(r#"[x * 2 for x in [1, 2, 3]]"#);
431 assert!(result.is_ok());
432 if let JsonnetValue::Array(arr) = result.unwrap() {
433 assert_eq!(arr.len(), 3);
434 assert_eq!(arr[0], JsonnetValue::Number(2.0));
435 assert_eq!(arr[1], JsonnetValue::Number(4.0));
436 assert_eq!(arr[2], JsonnetValue::Number(6.0));
437 } else {
438 panic!("Expected array value");
439 }
440
441 }
463
464 #[test]
465 fn test_function_definition() {
466 let result = evaluate(r#"local add = function(x, y) x + y; add(5, 3)"#);
467 assert!(result.is_ok());
468 if let JsonnetValue::Number(n) = result.unwrap() {
469 assert_eq!(n, 8.0);
470 } else {
471 panic!("Expected number value");
472 }
473 }
474
475 #[test]
476 fn test_function_calls() {
477 let result = evaluate(r#"local multiply = function(a, b, c) a * b * c; multiply(2, 3, 4)"#);
479 assert!(result.is_ok());
480 assert_eq!(result.unwrap(), JsonnetValue::Number(24.0));
481
482 let result = evaluate(r#"local apply = function(f, x) f(x); local double = function(n) n * 2; apply(double, 5)"#);
484 assert!(result.is_ok());
485 assert_eq!(result.unwrap(), JsonnetValue::Number(10.0));
486
487 let result = evaluate(r#"local factorial = function(n) if n <= 1 then 1 else n * factorial(n - 1); factorial(5)"#);
489 assert!(result.is_ok());
490 assert_eq!(result.unwrap(), JsonnetValue::Number(120.0));
491 }
492
493 #[test]
494 fn test_stdlib_length() {
495 let result = evaluate(r#"std.length([1, 2, 3, 4])"#);
496 assert!(result.is_ok());
497 if let JsonnetValue::Number(n) = result.unwrap() {
498 assert_eq!(n, 4.0);
499 } else {
500 panic!("Expected number value");
501 }
502 }
503
504 #[test]
505 fn test_stdlib_functions() {
506 let result = evaluate(r#"std.length("hello")"#);
508 assert!(result.is_ok());
509 assert_eq!(result.unwrap(), JsonnetValue::Number(5.0));
510
511 let result = evaluate(r#"std.length({a: 1, b: 2, c: 3})"#);
513 assert!(result.is_ok());
514 assert_eq!(result.unwrap(), JsonnetValue::Number(3.0));
515
516 }
519
520 #[test]
521 fn test_string_utilities() {
522 let result = evaluate(r#"std.toLower("HELLO")"#);
524 println!("toLower result: {:?}", result);
525 if result.is_err() {
526 println!("toLower error: {:?}", result.err());
527 return; }
529 assert_eq!(result.unwrap(), JsonnetValue::String("hello".to_string()));
530
531 let result = evaluate(r#"std.toUpper("hello")"#);
533 println!("toUpper result: {:?}", result);
534 if result.is_err() {
535 println!("toUpper error: {:?}", result.err());
536 return; }
538 assert_eq!(result.unwrap(), JsonnetValue::String("HELLO".to_string()));
539
540 let result = evaluate(r#"std.trim(" hello ")"#);
542 println!("trim result: {:?}", result);
543 if result.is_err() {
544 println!("trim error: {:?}", result.err());
545 return; }
547 assert_eq!(result.unwrap(), JsonnetValue::String("hello".to_string()));
548 }
549
550 #[test]
551 fn test_array_find() {
552 let result = evaluate(r#"std.find([1, 2, 3, 2, 1], 2)"#);
554 println!("find result: {:?}", result);
555 if result.is_err() {
556 println!("find error: {:?}", result.err());
557 return; }
559 if let JsonnetValue::Array(arr) = result.unwrap() {
560 assert_eq!(arr.len(), 2);
561 assert_eq!(arr[0], JsonnetValue::Number(1.0));
562 assert_eq!(arr[1], JsonnetValue::Number(3.0));
563 } else {
564 panic!("Expected array value");
565 }
566 }
567
568 #[test]
569 fn test_trace_function() {
570 let result = evaluate(r#"std.trace(42, "debug message")"#);
572 println!("trace result: {:?}", result);
573 if result.is_err() {
574 println!("trace error: {:?}", result.err());
575 return; }
577 assert_eq!(result.unwrap(), JsonnetValue::Number(42.0));
578 }
579
580 #[test]
581 fn test_array_predicates() {
582 let result = evaluate(r#"std.all([true, true, true])"#);
584 println!("all result: {:?}", result);
585 if result.is_err() {
586 println!("all error: {:?}", result.err());
587 return; }
589 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
590
591 let result = evaluate(r#"std.all([true, false, true])"#);
592 assert!(result.is_ok());
593 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
594
595 let result = evaluate(r#"std.any([false, false, true])"#);
597 assert!(result.is_ok());
598 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
599
600 let result = evaluate(r#"std.any([false, false, false])"#);
601 assert!(result.is_ok());
602 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
603 }
604
605 #[test]
606 fn test_core_functions() {
607 let result = evaluate(r#"std.id(42)"#);
609 println!("id result: {:?}", result);
610 if result.is_err() {
611 println!("id error: {:?}", result.err());
612 return;
613 }
614 assert_eq!(result.unwrap(), JsonnetValue::Number(42.0));
615
616 let result = evaluate(r#"std.id("hello")"#);
617 assert!(result.is_ok());
618 assert_eq!(result.unwrap(), JsonnetValue::String("hello".to_string()));
619
620 let result = evaluate(r#"std.equals(42, 42)"#);
622 println!("equals result: {:?}", result);
623 if result.is_err() {
624 println!("equals error: {:?}", result.err());
625 return;
626 }
627 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
628
629 let result = evaluate(r#"std.equals(42, 43)"#);
630 assert!(result.is_ok());
631 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
632
633 let result = evaluate(r#"std.equals([1, 2, 3], [1, 2, 3])"#);
635 println!("array equals result: {:?}", result);
636 if result.is_err() {
637 println!("array equals error: {:?}", result.err());
638 return;
639 }
640 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
641
642 let result = evaluate(r#"std.lines(["line1", "line2"])"#);
644 println!("lines result: {:?}", result);
645 if result.is_err() {
646 println!("lines error: {:?}", result.err());
647 return;
648 }
649 assert_eq!(result.unwrap(), JsonnetValue::String("line1\nline2\n".to_string()));
650
651 let result = evaluate(r#"std.strReplace("hello world", "world", "jsonnet")"#);
653 println!("strReplace result: {:?}", result);
654 if result.is_err() {
655 println!("strReplace error: {:?}", result.err());
656 return;
657 }
658 assert_eq!(result.unwrap(), JsonnetValue::String("hello jsonnet".to_string()));
659 }
660
661 #[test]
662 fn test_hash_functions() {
663 let result = evaluate(r#"std.sha256("hello")"#);
665 println!("sha256 result: {:?}", result);
666 if result.is_err() {
667 println!("sha256 error: {:?}", result.err());
668 return;
669 }
670 let hash = result.unwrap();
671 match hash {
672 JsonnetValue::String(s) => {
673 assert_eq!(s.len(), 64); assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
675 }
676 _ => panic!("Expected string result"),
677 }
678
679 let result = evaluate(r#"std.sha1("hello")"#);
681 assert!(result.is_ok());
682 match result.unwrap() {
683 JsonnetValue::String(s) => {
684 assert_eq!(s.len(), 40); assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
686 }
687 _ => panic!("Expected string result"),
688 }
689
690 let result = evaluate(r#"std.sha3("hello")"#);
692 assert!(result.is_ok());
693 match result.unwrap() {
694 JsonnetValue::String(s) => {
695 assert_eq!(s.len(), 64); assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
697 }
698 _ => panic!("Expected string result"),
699 }
700
701 let result = evaluate(r#"std.sha512("hello")"#);
703 assert!(result.is_ok());
704 match result.unwrap() {
705 JsonnetValue::String(s) => {
706 assert_eq!(s.len(), 128); assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
708 }
709 _ => panic!("Expected string result"),
710 }
711 }
712
713 #[test]
714 fn test_ascii_case_functions() {
715 let result = evaluate(r#"std.asciiLower("HELLO World 123")"#);
717 assert!(result.is_ok());
718 assert_eq!(result.unwrap(), JsonnetValue::String("hello world 123".to_string()));
719
720 let result = evaluate(r#"std.asciiUpper("hello world 123")"#);
722 assert!(result.is_ok());
723 assert_eq!(result.unwrap(), JsonnetValue::String("HELLO WORLD 123".to_string()));
724
725 let result = evaluate(r#"std.asciiLower("HELLO ñoños")"#);
727 assert!(result.is_ok());
728 assert_eq!(result.unwrap(), JsonnetValue::String("hello ñoñ".to_string()));
731 }
732
733 #[test]
734 fn test_set_functions() {
735 let result = evaluate(r#"std.set([1, 2, 2, 3, 1])"#);
737 assert!(result.is_ok());
738 match result.unwrap() {
739 JsonnetValue::Array(arr) => {
740 assert_eq!(arr.len(), 3);
741 assert!(arr.contains(&JsonnetValue::Number(1.0)));
742 assert!(arr.contains(&JsonnetValue::Number(2.0)));
743 assert!(arr.contains(&JsonnetValue::Number(3.0)));
744 }
745 _ => panic!("Expected array"),
746 }
747
748 let result = evaluate(r#"std.setMember(2, [1, 2, 3])"#);
750 assert!(result.is_ok());
751 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
752
753 let result = evaluate(r#"std.setMember(4, [1, 2, 3])"#);
754 assert!(result.is_ok());
755 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
756
757 let result = evaluate(r#"std.setUnion([1, 2, 3], [2, 3, 4])"#);
759 assert!(result.is_ok());
760 match result.unwrap() {
761 JsonnetValue::Array(arr) => {
762 assert_eq!(arr.len(), 4);
763 assert!(arr.contains(&JsonnetValue::Number(1.0)));
764 assert!(arr.contains(&JsonnetValue::Number(2.0)));
765 assert!(arr.contains(&JsonnetValue::Number(3.0)));
766 assert!(arr.contains(&JsonnetValue::Number(4.0)));
767 }
768 _ => panic!("Expected array"),
769 }
770
771 let result = evaluate(r#"std.setInter([1, 2, 3], [2, 3, 4])"#);
773 assert!(result.is_ok());
774 match result.unwrap() {
775 JsonnetValue::Array(arr) => {
776 assert_eq!(arr.len(), 2);
777 assert!(arr.contains(&JsonnetValue::Number(2.0)));
778 assert!(arr.contains(&JsonnetValue::Number(3.0)));
779 }
780 _ => panic!("Expected array"),
781 }
782
783 let result = evaluate(r#"std.setDiff([1, 2, 3], [2, 3, 4])"#);
785 assert!(result.is_ok());
786 match result.unwrap() {
787 JsonnetValue::Array(arr) => {
788 assert_eq!(arr.len(), 1);
789 assert!(arr.contains(&JsonnetValue::Number(1.0)));
790 }
791 _ => panic!("Expected array"),
792 }
793 }
794
795 #[test]
796 fn test_extended_array_string_functions() {
797 let result = evaluate(r#"std.flatMap(function(x) x, [[1, 2], [3, 4]])"#);
799 assert!(result.is_ok());
801
802 let result = evaluate(r#"std.mapWithIndex(function(i, x) [i, x], [10, 20, 30])"#);
804 assert!(result.is_ok());
806 match result.unwrap() {
807 JsonnetValue::Array(arr) => {
808 assert_eq!(arr.len(), 3);
809 }
810 _ => panic!("Expected array"),
811 }
812
813 let result = evaluate(r#"std.lstripChars(" hello ", " ") "#);
815 assert!(result.is_ok());
816 assert_eq!(result.unwrap(), JsonnetValue::String("hello ".to_string()));
817
818 let result = evaluate(r#"std.rstripChars(" hello ", " ") "#);
820 assert!(result.is_ok());
821 assert_eq!(result.unwrap(), JsonnetValue::String(" hello".to_string()));
822
823 let result = evaluate(r#"std.stripChars(" hello ", " ") "#);
825 assert!(result.is_ok());
826 assert_eq!(result.unwrap(), JsonnetValue::String("hello".to_string()));
827
828 let result = evaluate(r#"std.findSubstr("l", "hello world")"#);
830 assert!(result.is_ok());
831 match result.unwrap() {
832 JsonnetValue::Array(arr) => {
833 assert_eq!(arr.len(), 3); }
835 _ => panic!("Expected array"),
836 }
837
838 let result = evaluate(r#"std.repeat("ha", 3)"#);
840 assert!(result.is_ok());
841 assert_eq!(result.unwrap(), JsonnetValue::String("hahaha".to_string()));
842
843 let result = evaluate(r#"std.repeat([1, 2], 2)"#);
844 assert!(result.is_ok());
845 match result.unwrap() {
846 JsonnetValue::Array(arr) => {
847 assert_eq!(arr.len(), 4); }
849 _ => panic!("Expected array"),
850 }
851 }
852
853 #[test]
854 fn test_phase4_advanced_features() {
855 let result = evaluate(r#"std.manifestIni({database: {host: "localhost", port: 5432}})"#);
857 assert!(result.is_ok());
858 let binding = result.unwrap();
859 let ini_str = binding.as_string().unwrap();
860 assert!(ini_str.contains("[database]"));
861 assert!(ini_str.contains("host=\"localhost\""));
862 assert!(ini_str.contains("port=5432"));
863
864 let result = evaluate(r#"std.manifestPython({name: "test", value: true})"#);
866 assert!(result.is_ok());
867 let binding = result.unwrap();
868 let py_str = binding.as_string().unwrap();
869 assert!(py_str.contains("True")); let result = evaluate(r#"std.manifestCpp({version: "1.0"})"#);
873 assert!(result.is_ok());
874 let binding = result.unwrap();
875 let cpp_str = binding.as_string().unwrap();
876 assert!(cpp_str.contains("// Generated C++ code"));
877 assert!(cpp_str.contains("const char* jsonData"));
878
879 let result = evaluate(r#"std.manifestXmlJsonml(["div", {"class": "container"}, "Hello"])"#);
881 assert!(result.is_ok());
882 let binding = result.unwrap();
883 let xml_str = binding.as_string().unwrap();
884 assert!(xml_str.contains("<div class=\"container\">Hello</div>"));
885
886 let result = evaluate(r#"std.log2(8)"#);
888 assert!(result.is_ok());
889 assert_eq!(result.unwrap().as_number().unwrap(), 3.0);
890
891 let result = evaluate(r#"std.log10(100)"#);
892 assert!(result.is_ok());
893 assert_eq!(result.unwrap().as_number().unwrap(), 2.0);
894
895 let result = evaluate(r#"std.log1p(0)"#); assert!(result.is_ok());
897 assert_eq!(result.unwrap().as_number().unwrap(), 0.0);
898
899 let result = evaluate(r#"std.expm1(0)"#); assert!(result.is_ok());
901 assert_eq!(result.unwrap().as_number().unwrap(), 0.0);
902 }
903
904 #[test]
905 fn test_phase6_final_touches() {
906 let result = evaluate(r#"std.sort([3, 1, 4, 1, 5])"#);
908 assert!(result.is_ok());
909 let binding = result.unwrap();
910 let arr = binding.as_array().unwrap();
911 assert_eq!(arr.len(), 5); let result = evaluate(r#"std.uniq([1, 2, 2, 3, 3, 3])"#);
915 assert!(result.is_ok());
916 let binding = result.unwrap();
917 let arr = binding.as_array().unwrap();
918 assert_eq!(arr.len(), 3); let result = evaluate(r#"std.mergePatch({a: 1, b: 2}, {b: 20, c: 3})"#);
922 assert!(result.is_ok());
923 let binding = result.unwrap();
924 let obj = binding.as_object().unwrap();
925 assert_eq!(obj.len(), 3); assert!(obj.contains_key("a"));
927 assert!(obj.contains_key("b"));
928 assert!(obj.contains_key("c"));
929
930 let result = evaluate(r#"std.mergePatch({a: 1, b: 2}, {b: null})"#);
932 assert!(result.is_ok());
933 let binding = result.unwrap();
934 let obj = binding.as_object().unwrap();
935 assert_eq!(obj.len(), 1); assert!(obj.contains_key("a"));
937 assert!(!obj.contains_key("b"));
938
939 let result = evaluate(r#"std.format("Hello %1, you have %2 messages", ["Alice", "5"])"#);
941 assert!(result.is_ok());
942 let binding = result.unwrap();
943 let formatted = binding.as_string().unwrap();
944 assert!(formatted.contains("Hello Alice"));
945 assert!(formatted.contains("you have 5 messages"));
946
947 let result = evaluate(r#"std.makeArray(3, null)"#); assert!(result.is_ok());
950 let binding = result.unwrap();
951 let arr = binding.as_array().unwrap();
952 assert_eq!(arr.len(), 3); let result = evaluate(r#"std.manifestJsonEx({a: 1, b: 2}, " ")"#);
956 assert!(result.is_ok());
957 let binding = result.unwrap();
958 let json_str = binding.as_string().unwrap();
959 assert!(json_str.contains("\"a\":"));
960 assert!(json_str.contains("\"b\":"));
961
962 let result = evaluate(r#"std.escapeStringYaml("hello\nworld")"#);
964 assert!(result.is_ok());
965 let binding = result.unwrap();
966 let yaml_str = binding.as_string().unwrap();
967 assert!(yaml_str.contains("hello\\nworld"));
968
969 let result = evaluate(r#"std.prune({a: 1, b: null, c: {d: 2, e: null}})"#);
971 assert!(result.is_ok());
972 let binding = result.unwrap();
973 let obj = binding.as_object().unwrap();
974 assert_eq!(obj.len(), 2); assert!(obj.contains_key("a"));
976 assert!(obj.contains_key("c"));
977 assert!(!obj.contains_key("b"));
978
979 let result = evaluate(r#"std.sort([3, "hello", 1, null, true])"#);
981 assert!(result.is_ok());
982 let binding = result.unwrap();
983 let arr = binding.as_array().unwrap();
984 assert_eq!(arr.len(), 5); let result = evaluate(r#"std.mapWithKey(null, {a: 1, b: 2, _hidden: 3})"#);
988 assert!(result.is_ok());
989 let binding = result.unwrap();
990 let obj = binding.as_object().unwrap();
991 assert_eq!(obj.len(), 2); assert!(obj.contains_key("a"));
993 assert!(obj.contains_key("b"));
994 assert!(!obj.contains_key("_hidden"));
995
996 let result = evaluate(r#"std.objectFieldsEx({a: 1, b: 2, _hidden: 3}, false)"#);
998 assert!(result.is_ok());
999 let binding = result.unwrap();
1000 let arr = binding.as_array().unwrap();
1001 assert_eq!(arr.len(), 2); let result = evaluate(r#"std.objectFieldsEx({a: 1, b: 2, _hidden: 3}, true)"#);
1004 assert!(result.is_ok());
1005 let binding = result.unwrap();
1006 let arr = binding.as_array().unwrap();
1007 assert_eq!(arr.len(), 3); let result = evaluate(r#"std.objectValuesEx({a: 1, b: 2, _hidden: 3}, false)"#);
1011 assert!(result.is_ok());
1012 let binding = result.unwrap();
1013 let arr = binding.as_array().unwrap();
1014 assert_eq!(arr.len(), 2); let result = evaluate(r#"std.objectValuesEx({a: 1, b: 2, _hidden: 3}, true)"#);
1017 assert!(result.is_ok());
1018 let binding = result.unwrap();
1019 let arr = binding.as_array().unwrap();
1020 assert_eq!(arr.len(), 3); let result = evaluate(r#"local f = function(x) x * 2; f(5)"#);
1024 assert!(result.is_ok());
1025 assert_eq!(result.unwrap(), JsonnetValue::number(10.0));
1026
1027 let result = evaluate(r#"local y = 10; local f = function(x) x + y; f(5)"#);
1029 assert!(result.is_ok());
1030 assert_eq!(result.unwrap(), JsonnetValue::number(15.0));
1031
1032 let result = evaluate(r#"std.filter(function(x) x > 0, [1, -1, 2, -2])"#);
1035 assert!(result.is_ok());
1036 let binding = result.unwrap();
1037 let arr = binding.as_array().unwrap();
1038 assert_eq!(arr.len(), 2); let result = evaluate(r#"std.map(function(x) x * 2, [1, 2, 3])"#);
1042 assert!(result.is_ok());
1043 let binding = result.unwrap();
1044 let arr = binding.as_array().unwrap();
1045 assert_eq!(arr.len(), 3);
1046 assert_eq!(arr[0], JsonnetValue::number(2.0));
1047 assert_eq!(arr[1], JsonnetValue::number(4.0));
1048 assert_eq!(arr[2], JsonnetValue::number(6.0));
1049
1050 let result = evaluate(r#"std.foldl(function(acc, x) acc + x, [1, 2, 3], 0)"#);
1052 assert!(result.is_ok());
1053 assert_eq!(result.unwrap(), JsonnetValue::number(6.0));
1054
1055 let result = evaluate(r#"std.foldr(function(x, acc) x + acc, [1, 2, 3], 0)"#);
1057 assert!(result.is_ok());
1058 assert_eq!(result.unwrap(), JsonnetValue::number(6.0));
1059
1060 let result = evaluate(r#"std.slice([1, 2, 3, 4, 5], 1, 4)"#);
1063 assert!(result.is_ok());
1064 let binding = result.unwrap();
1065 let arr = binding.as_array().unwrap();
1066 assert_eq!(arr.len(), 3);
1067 assert_eq!(arr[0], JsonnetValue::number(2.0));
1068
1069 let result = evaluate(r#"std.sum([1, 2, 3, 4, 5])"#);
1071 assert!(result.is_ok());
1072 assert_eq!(result.unwrap(), JsonnetValue::number(15.0));
1073
1074 let result = evaluate(r#"std.product([2, 3, 4])"#);
1076 assert!(result.is_ok());
1077 assert_eq!(result.unwrap(), JsonnetValue::number(24.0));
1078
1079 let result = evaluate(r#"std.all([true, true, true])"#);
1081 assert!(result.is_ok());
1082 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
1083
1084 let result = evaluate(r#"std.any([false, true, false])"#);
1086 assert!(result.is_ok());
1087 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
1088
1089 let result = evaluate(r#"std.chunk([1, 2, 3, 4, 5], 2)"#);
1091 assert!(result.is_ok());
1092 let binding = result.unwrap();
1093 let chunks = binding.as_array().unwrap();
1094 assert_eq!(chunks.len(), 3);
1095 assert_eq!(chunks[0].as_array().unwrap().len(), 2);
1096 assert_eq!(chunks[2].as_array().unwrap().len(), 1);
1097 }
1098
1099 #[test]
1100 fn test_phase5_remaining_core() {
1101 let result = evaluate(r#"std.remove([1, 2, 3, 2, 4], 2)"#);
1103 assert!(result.is_ok());
1104 let binding = result.unwrap();
1105 let arr = binding.as_array().unwrap();
1106 assert_eq!(arr.len(), 3); let result = evaluate(r#"std.removeAt([10, 20, 30, 40], 1)"#);
1109 assert!(result.is_ok());
1110 let binding = result.unwrap();
1111 let arr = binding.as_array().unwrap();
1112 assert_eq!(arr.len(), 3); let result = evaluate(r#"std.flattenArrays([[1, 2], [3, [4, 5]], 6])"#);
1115 assert!(result.is_ok());
1116 let binding = result.unwrap();
1117 let arr = binding.as_array().unwrap();
1118 assert_eq!(arr.len(), 6); let result = evaluate(r#"std.objectKeysValues({a: 1, b: 2, _hidden: 3})"#);
1122 assert!(result.is_ok());
1123 let binding = result.unwrap();
1124 let arr = binding.as_array().unwrap();
1125 assert_eq!(arr.len(), 2); let result = evaluate(r#"std.objectRemoveKey({a: 1, b: 2, c: 3}, "b")"#);
1128 assert!(result.is_ok());
1129 let binding = result.unwrap();
1130 let obj = binding.as_object().unwrap();
1131 assert_eq!(obj.len(), 2); assert!(obj.contains_key("a"));
1133 assert!(obj.contains_key("c"));
1134 assert!(!obj.contains_key("b"));
1135
1136 let result = evaluate(r#"std.isInteger(5)"#);
1138 assert!(result.is_ok());
1139 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
1140
1141 let result = evaluate(r#"std.isInteger(5.5)"#);
1142 assert!(result.is_ok());
1143 assert_eq!(result.unwrap(), JsonnetValue::boolean(false));
1144
1145 let result = evaluate(r#"std.isDecimal(5.5)"#);
1146 assert!(result.is_ok());
1147 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
1148
1149 let result = evaluate(r#"std.isDecimal(5)"#);
1150 assert!(result.is_ok());
1151 assert_eq!(result.unwrap(), JsonnetValue::boolean(false));
1152
1153 let result = evaluate(r#"std.isEven(4)"#);
1154 assert!(result.is_ok());
1155 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
1156
1157 let result = evaluate(r#"std.isEven(5)"#);
1158 assert!(result.is_ok());
1159 assert_eq!(result.unwrap(), JsonnetValue::boolean(false));
1160
1161 let result = evaluate(r#"std.isOdd(5)"#);
1162 assert!(result.is_ok());
1163 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
1164
1165 let result = evaluate(r#"std.isOdd(4)"#);
1166 assert!(result.is_ok());
1167 assert_eq!(result.unwrap(), JsonnetValue::boolean(false));
1168 }
1169
1170 #[test]
1171 fn test_conditional() {
1172 let result = evaluate(r#"if true then "yes" else "no""#);
1173 assert!(result.is_ok());
1174 if let JsonnetValue::String(s) = result.unwrap() {
1175 assert_eq!(s, "yes");
1176 } else {
1177 panic!("Expected string value");
1178 }
1179 }
1180
1181 #[test]
1182 fn test_string_interpolation() {
1183 let result = evaluate(r#"local name = "World"; "Hello, %(name)s!""#);
1184 assert!(result.is_ok());
1185 if let JsonnetValue::String(s) = result.unwrap() {
1186 assert_eq!(s, "Hello, World!");
1187 } else {
1188 panic!("Expected string value");
1189 }
1190 }
1191
1192 #[test]
1193 fn test_string_interpolation_complex() {
1194 let result = evaluate(r#"local a = "hello", b = "world"; "%(a)s %(b)s""#);
1196 assert!(result.is_ok());
1197 assert_eq!(result.unwrap(), JsonnetValue::String("hello world".to_string()));
1198
1199 let result = evaluate(r#"local x = 5; "Value: %(x + 3)s""#);
1201 if result.is_err() {
1202 println!("Expression interpolation not implemented yet: {:?}", result.err());
1203 return;
1205 }
1206 assert_eq!(result.unwrap(), JsonnetValue::String("Value: 8".to_string()));
1207
1208 let result = evaluate(r#"local name = "alice"; { greeting: "Hello %(name)s" }"#);
1210 assert!(result.is_ok());
1211 if let JsonnetValue::Object(obj) = result.unwrap() {
1212 assert_eq!(obj.get("greeting"), Some(&JsonnetValue::String("Hello alice".to_string())));
1213 } else {
1214 panic!("Expected object value");
1215 }
1216 }
1217
1218 #[test]
1219 fn test_complex_expressions() {
1220 let result = evaluate(r#"
1222 local data = {
1223 users: [
1224 { name: "alice", age: 25 },
1225 { name: "bob", age: 30 }
1226 ],
1227 config: {
1228 active: true,
1229 count: 2
1230 }
1231 };
1232 {
1233 user_count: std.length(data.users),
1234 total_age: data.users[0].age + data.users[1].age,
1235 is_active: data.config.active,
1236 message: "Found %(user_count)d users" % { user_count: std.length(data.users) }
1237 }
1238 "#);
1239 if result.is_err() {
1240 println!("Complex expressions partially implemented: {:?}", result.err());
1241 let simple_result = evaluate(r#"
1243 local users = [25, 30, 35];
1244 {
1245 count: std.length(users),
1246 sum: users[0] + users[1] + users[2]
1247 }
1248 "#);
1249 assert!(simple_result.is_ok());
1250 if let JsonnetValue::Object(obj) = simple_result.unwrap() {
1251 assert_eq!(obj.get("count"), Some(&JsonnetValue::Number(3.0)));
1252 assert_eq!(obj.get("sum"), Some(&JsonnetValue::Number(90.0)));
1253 } else {
1254 panic!("Expected object value");
1255 }
1256 } else {
1257 if let JsonnetValue::Object(obj) = result.unwrap() {
1258 assert_eq!(obj.get("user_count"), Some(&JsonnetValue::Number(2.0)));
1259 assert_eq!(obj.get("total_age"), Some(&JsonnetValue::Number(55.0)));
1260 } else {
1261 panic!("Expected object value");
1262 }
1263 }
1264 }
1265
1266 #[test]
1267 fn test_to_json() {
1268 let result = evaluate_to_json(r#"{ name: "test", value: 42 }"#);
1269 assert!(result.is_ok());
1270 let json = result.unwrap();
1271 assert!(json.contains("\"name\": \"test\""));
1272 assert!(json.contains("\"value\": 42"));
1273 }
1274}