1pub mod ast;
7pub mod error;
8pub mod evaluator;
9pub mod lexer;
10pub mod parser;
11pub mod stdlib;
12pub mod value;
13
14pub use error::{JsonnetError, Result};
15pub use evaluator::Evaluator;
16pub use parser::Parser;
17pub use value::JsonnetValue;
18
19pub fn evaluate(source: &str) -> Result<JsonnetValue> {
28 evaluate_with_filename(source, "<string>")
29}
30
31pub fn evaluate_with_filename(source: &str, filename: &str) -> Result<JsonnetValue> {
40 let mut evaluator = Evaluator::new();
41 evaluator.evaluate_file(source, filename)
42}
43
44pub fn evaluate_to_json(source: &str) -> Result<String> {
52 let value = evaluate(source).map_err(|e| {
53 eprintln!("Evaluation error: {:?}", e);
54 e
55 })?;
56 let json_value = value.to_json_value();
57 serde_json::to_string_pretty(&json_value).map_err(|e| {
58 eprintln!("JSON serialization error: {:?}", e);
59 JsonnetError::runtime_error(&format!("JSON serialization failed: {}", e))
60 })
61}
62
63#[cfg(feature = "yaml")]
71pub fn evaluate_to_yaml(source: &str) -> Result<String> {
72 let value = evaluate(source)?;
73 Ok(serde_yaml::to_string(&value.to_json_value())?)
74}
75
76pub const VERSION: &str = env!("CARGO_PKG_VERSION");
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_basic_evaluation() {
85 let result = evaluate(r#""Hello, World!""#);
86 assert!(result.is_ok());
87 if let JsonnetValue::String(s) = result.unwrap() {
88 assert_eq!(s, "Hello, World!");
89 } else {
90 panic!("Expected string value");
91 }
92 }
93
94 #[test]
95 fn test_number_evaluation() {
96 let result = evaluate("42");
97 assert!(result.is_ok());
98 if let JsonnetValue::Number(n) = result.unwrap() {
99 assert_eq!(n, 42.0);
100 } else {
101 panic!("Expected number value");
102 }
103 }
104
105 #[test]
106 fn test_boolean_evaluation() {
107 let result = evaluate("true");
108 assert!(result.is_ok());
109 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
110 }
111
112 #[test]
113 fn test_null_evaluation() {
114 let result = evaluate("null");
115 assert!(result.is_ok());
116 assert_eq!(result.unwrap(), JsonnetValue::Null);
117 }
118
119 #[test]
120 fn test_local_variables() {
121 let result = evaluate(r#"local x = 42; x"#);
122 if let Err(ref e) = result {
123 println!("Error: {:?}", e);
124 }
125 assert!(result.is_ok());
126 if let JsonnetValue::Number(n) = result.unwrap() {
127 assert_eq!(n, 42.0);
128 } else {
129 panic!("Expected number value");
130 }
131 }
132
133 #[test]
134 fn test_local_expressions() {
135 let result = evaluate(r#"local x = 10, y = 20; x + y"#);
137 assert!(result.is_ok());
138 assert_eq!(result.unwrap(), JsonnetValue::Number(30.0));
139
140 let result = evaluate(r#"local add = function(a) local b = 5; a + b; add(3)"#);
142 assert!(result.is_ok());
143 assert_eq!(result.unwrap(), JsonnetValue::Number(8.0));
144
145 let result = evaluate(r#"local name = "alice"; { username: name, age: 25 }"#);
147 assert!(result.is_ok());
148 if let JsonnetValue::Object(obj) = result.unwrap() {
149 assert_eq!(obj.get("username"), Some(&JsonnetValue::String("alice".to_string())));
150 assert_eq!(obj.get("age"), Some(&JsonnetValue::Number(25.0)));
151 } else {
152 panic!("Expected object value");
153 }
154 }
155
156 #[test]
157 fn test_arithmetic() {
158 let result = evaluate("2 + 3 * 4");
159 assert!(result.is_ok());
160 if let JsonnetValue::Number(n) = result.unwrap() {
161 assert_eq!(n, 14.0); } else {
163 panic!("Expected number value");
164 }
165 }
166
167 #[test]
168 fn test_comparison_operators() {
169 let result = evaluate("5 == 5");
171 assert!(result.is_ok());
172 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
173
174 let result = evaluate("5 != 3");
175 assert!(result.is_ok());
176 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
177
178 let result = evaluate("3 < 5");
180 assert!(result.is_ok());
181 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
182
183 let result = evaluate("5 > 3");
184 assert!(result.is_ok());
185 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
186
187 let result = evaluate("5 <= 5");
188 assert!(result.is_ok());
189 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
190
191 let result = evaluate("5 >= 5");
192 assert!(result.is_ok());
193 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
194 }
195
196 #[test]
197 fn test_logical_operators() {
198 let result = evaluate("true && true");
200 assert!(result.is_ok());
201 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
202
203 let result = evaluate("true && false");
204 assert!(result.is_ok());
205 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
206
207 let result = evaluate("false || true");
209 assert!(result.is_ok());
210 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
211
212 let result = evaluate("false || false");
213 assert!(result.is_ok());
214 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
215
216 let result = evaluate("!false");
218 assert!(result.is_ok());
219 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
220
221 let result = evaluate("!true");
222 assert!(result.is_ok());
223 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
224 }
225
226 #[test]
227 fn test_object_creation() {
228 let result = evaluate(r#"{ name: "test", value: 123 }"#);
229 assert!(result.is_ok());
230 if let JsonnetValue::Object(obj) = result.unwrap() {
231 assert_eq!(obj.get("name"), Some(&JsonnetValue::String("test".to_string())));
232 assert_eq!(obj.get("value"), Some(&JsonnetValue::Number(123.0)));
233 } else {
234 panic!("Expected object value");
235 }
236 }
237
238 #[test]
239 fn test_object_field_access() {
240 let result = evaluate(r#"{ name: "test", value: 123 }.name"#);
242 assert!(result.is_ok());
243 assert_eq!(result.unwrap(), JsonnetValue::String("test".to_string()));
244
245 let result = evaluate(r#"{ user: { name: "alice", age: 30 } }.user.name"#);
247 assert!(result.is_ok());
248 assert_eq!(result.unwrap(), JsonnetValue::String("alice".to_string()));
249
250 let result = evaluate(r#"[10, 20, 30][1]"#);
252 println!("Array bracket notation result: {:?}", result);
253 if result.is_ok() {
254 assert_eq!(result.unwrap(), JsonnetValue::Number(20.0));
255 }
256
257 let result = evaluate(r#"{ "field-name": "value" }["field-name"]"#);
259 println!("Object bracket notation result: {:?}", result);
260 assert!(result.is_ok(), "Bracket notation should work: {:?}", result.err());
261 assert_eq!(result.unwrap(), JsonnetValue::String("value".to_string()));
262 }
263
264 #[test]
265 fn test_array_creation() {
266 let result = evaluate(r#"[1, 2, 3]"#);
267 assert!(result.is_ok());
268 if let JsonnetValue::Array(arr) = result.unwrap() {
269 assert_eq!(arr.len(), 3);
270 assert_eq!(arr[0], JsonnetValue::Number(1.0));
271 assert_eq!(arr[1], JsonnetValue::Number(2.0));
272 assert_eq!(arr[2], JsonnetValue::Number(3.0));
273 } else {
274 panic!("Expected array value");
275 }
276 }
277
278 #[test]
279 fn test_array_index_access() {
280 let result = evaluate(r#"[10, 20, 30][1]"#);
282 assert!(result.is_ok());
283 assert_eq!(result.unwrap(), JsonnetValue::Number(20.0));
284
285 let result = evaluate(r#"[10, 20, 30][0]"#);
287 assert!(result.is_ok());
288 assert_eq!(result.unwrap(), JsonnetValue::Number(10.0));
289
290 let result = evaluate(r#"[10, 20, 30][2]"#);
292 assert!(result.is_ok());
293 assert_eq!(result.unwrap(), JsonnetValue::Number(30.0));
294
295 let result = evaluate(r#"[[1, 2], [3, 4]][1][0]"#);
297 assert!(result.is_ok());
298 assert_eq!(result.unwrap(), JsonnetValue::Number(3.0));
299 }
300
301 #[test]
302 fn test_array_comprehension() {
303 let result = evaluate(r#"[x * 2 for x in [1, 2, 3]]"#);
305 assert!(result.is_ok());
306 if let JsonnetValue::Array(arr) = result.unwrap() {
307 assert_eq!(arr.len(), 3);
308 assert_eq!(arr[0], JsonnetValue::Number(2.0));
309 assert_eq!(arr[1], JsonnetValue::Number(4.0));
310 assert_eq!(arr[2], JsonnetValue::Number(6.0));
311 } else {
312 panic!("Expected array value");
313 }
314
315 let result = evaluate(r#"[x for x in [1, 2, 3, 4, 5] if x > 3]"#);
317 assert!(result.is_ok());
318 if let JsonnetValue::Array(arr) = result.unwrap() {
319 assert_eq!(arr.len(), 2);
320 assert_eq!(arr[0], JsonnetValue::Number(4.0));
321 assert_eq!(arr[1], JsonnetValue::Number(5.0));
322 } else {
323 panic!("Expected array value");
324 }
325
326 let result = evaluate(r#"[x + 10 for x in [1, 2, 3] if x % 2 == 1]"#);
328 assert!(result.is_ok());
329 if let JsonnetValue::Array(arr) = result.unwrap() {
330 assert_eq!(arr.len(), 2);
331 assert_eq!(arr[0], JsonnetValue::Number(11.0)); assert_eq!(arr[1], JsonnetValue::Number(13.0)); } else {
334 panic!("Expected array value");
335 }
336 }
337
338 #[test]
339 fn test_function_definition() {
340 let result = evaluate(r#"local add = function(x, y) x + y; add(5, 3)"#);
341 assert!(result.is_ok());
342 if let JsonnetValue::Number(n) = result.unwrap() {
343 assert_eq!(n, 8.0);
344 } else {
345 panic!("Expected number value");
346 }
347 }
348
349 #[test]
350 fn test_function_calls() {
351 let result = evaluate(r#"local multiply = function(a, b, c) a * b * c; multiply(2, 3, 4)"#);
353 assert!(result.is_ok());
354 assert_eq!(result.unwrap(), JsonnetValue::Number(24.0));
355
356 let result = evaluate(r#"local apply = function(f, x) f(x); local double = function(n) n * 2; apply(double, 5)"#);
358 assert!(result.is_ok());
359 assert_eq!(result.unwrap(), JsonnetValue::Number(10.0));
360
361 let result = evaluate(r#"local factorial = function(n) if n <= 1 then 1 else n * factorial(n - 1); factorial(5)"#);
363 assert!(result.is_ok());
364 assert_eq!(result.unwrap(), JsonnetValue::Number(120.0));
365 }
366
367 #[test]
368 fn test_stdlib_length() {
369 let result = evaluate(r#"std.length([1, 2, 3, 4])"#);
370 assert!(result.is_ok());
371 if let JsonnetValue::Number(n) = result.unwrap() {
372 assert_eq!(n, 4.0);
373 } else {
374 panic!("Expected number value");
375 }
376 }
377
378 #[test]
379 fn test_stdlib_functions() {
380 let result = evaluate(r#"std.length("hello")"#);
382 assert!(result.is_ok());
383 assert_eq!(result.unwrap(), JsonnetValue::Number(5.0));
384
385 let result = evaluate(r#"std.length({a: 1, b: 2, c: 3})"#);
387 assert!(result.is_ok());
388 assert_eq!(result.unwrap(), JsonnetValue::Number(3.0));
389
390 }
393
394 #[test]
395 fn test_string_utilities() {
396 let result = evaluate(r#"std.toLower("HELLO")"#);
398 println!("toLower result: {:?}", result);
399 if result.is_err() {
400 println!("toLower error: {:?}", result.err());
401 return; }
403 assert_eq!(result.unwrap(), JsonnetValue::String("hello".to_string()));
404
405 let result = evaluate(r#"std.toUpper("hello")"#);
407 println!("toUpper result: {:?}", result);
408 if result.is_err() {
409 println!("toUpper error: {:?}", result.err());
410 return; }
412 assert_eq!(result.unwrap(), JsonnetValue::String("HELLO".to_string()));
413
414 let result = evaluate(r#"std.trim(" hello ")"#);
416 println!("trim result: {:?}", result);
417 if result.is_err() {
418 println!("trim error: {:?}", result.err());
419 return; }
421 assert_eq!(result.unwrap(), JsonnetValue::String("hello".to_string()));
422 }
423
424 #[test]
425 fn test_array_find() {
426 let result = evaluate(r#"std.find([1, 2, 3, 2, 1], 2)"#);
428 println!("find result: {:?}", result);
429 if result.is_err() {
430 println!("find error: {:?}", result.err());
431 return; }
433 if let JsonnetValue::Array(arr) = result.unwrap() {
434 assert_eq!(arr.len(), 2);
435 assert_eq!(arr[0], JsonnetValue::Number(1.0));
436 assert_eq!(arr[1], JsonnetValue::Number(3.0));
437 } else {
438 panic!("Expected array value");
439 }
440 }
441
442 #[test]
443 fn test_trace_function() {
444 let result = evaluate(r#"std.trace(42, "debug message")"#);
446 println!("trace result: {:?}", result);
447 if result.is_err() {
448 println!("trace error: {:?}", result.err());
449 return; }
451 assert_eq!(result.unwrap(), JsonnetValue::Number(42.0));
452 }
453
454 #[test]
455 fn test_array_predicates() {
456 let result = evaluate(r#"std.all([true, true, true])"#);
458 println!("all result: {:?}", result);
459 if result.is_err() {
460 println!("all error: {:?}", result.err());
461 return; }
463 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
464
465 let result = evaluate(r#"std.all([true, false, true])"#);
466 assert!(result.is_ok());
467 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
468
469 let result = evaluate(r#"std.any([false, false, true])"#);
471 assert!(result.is_ok());
472 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
473
474 let result = evaluate(r#"std.any([false, false, false])"#);
475 assert!(result.is_ok());
476 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
477 }
478
479 #[test]
480 fn test_core_functions() {
481 let result = evaluate(r#"std.id(42)"#);
483 println!("id result: {:?}", result);
484 if result.is_err() {
485 println!("id error: {:?}", result.err());
486 return;
487 }
488 assert_eq!(result.unwrap(), JsonnetValue::Number(42.0));
489
490 let result = evaluate(r#"std.id("hello")"#);
491 assert!(result.is_ok());
492 assert_eq!(result.unwrap(), JsonnetValue::String("hello".to_string()));
493
494 let result = evaluate(r#"std.equals(42, 42)"#);
496 println!("equals result: {:?}", result);
497 if result.is_err() {
498 println!("equals error: {:?}", result.err());
499 return;
500 }
501 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
502
503 let result = evaluate(r#"std.equals(42, 43)"#);
504 assert!(result.is_ok());
505 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
506
507 let result = evaluate(r#"std.equals([1, 2, 3], [1, 2, 3])"#);
509 println!("array equals result: {:?}", result);
510 if result.is_err() {
511 println!("array equals error: {:?}", result.err());
512 return;
513 }
514 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
515
516 let result = evaluate(r#"std.lines(["line1", "line2"])"#);
518 println!("lines result: {:?}", result);
519 if result.is_err() {
520 println!("lines error: {:?}", result.err());
521 return;
522 }
523 assert_eq!(result.unwrap(), JsonnetValue::String("line1\nline2\n".to_string()));
524
525 let result = evaluate(r#"std.strReplace("hello world", "world", "jsonnet")"#);
527 println!("strReplace result: {:?}", result);
528 if result.is_err() {
529 println!("strReplace error: {:?}", result.err());
530 return;
531 }
532 assert_eq!(result.unwrap(), JsonnetValue::String("hello jsonnet".to_string()));
533 }
534
535 #[test]
536 fn test_hash_functions() {
537 let result = evaluate(r#"std.sha256("hello")"#);
539 println!("sha256 result: {:?}", result);
540 if result.is_err() {
541 println!("sha256 error: {:?}", result.err());
542 return;
543 }
544 let hash = result.unwrap();
545 match hash {
546 JsonnetValue::String(s) => {
547 assert_eq!(s.len(), 64); assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
549 }
550 _ => panic!("Expected string result"),
551 }
552
553 let result = evaluate(r#"std.sha1("hello")"#);
555 assert!(result.is_ok());
556 match result.unwrap() {
557 JsonnetValue::String(s) => {
558 assert_eq!(s.len(), 40); assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
560 }
561 _ => panic!("Expected string result"),
562 }
563
564 let result = evaluate(r#"std.sha3("hello")"#);
566 assert!(result.is_ok());
567 match result.unwrap() {
568 JsonnetValue::String(s) => {
569 assert_eq!(s.len(), 64); assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
571 }
572 _ => panic!("Expected string result"),
573 }
574
575 let result = evaluate(r#"std.sha512("hello")"#);
577 assert!(result.is_ok());
578 match result.unwrap() {
579 JsonnetValue::String(s) => {
580 assert_eq!(s.len(), 128); assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
582 }
583 _ => panic!("Expected string result"),
584 }
585 }
586
587 #[test]
588 fn test_ascii_case_functions() {
589 let result = evaluate(r#"std.asciiLower("HELLO World 123")"#);
591 assert!(result.is_ok());
592 assert_eq!(result.unwrap(), JsonnetValue::String("hello world 123".to_string()));
593
594 let result = evaluate(r#"std.asciiUpper("hello world 123")"#);
596 assert!(result.is_ok());
597 assert_eq!(result.unwrap(), JsonnetValue::String("HELLO WORLD 123".to_string()));
598
599 let result = evaluate(r#"std.asciiLower("HELLO ñoños")"#);
601 assert!(result.is_ok());
602 assert_eq!(result.unwrap(), JsonnetValue::String("hello ñoños".to_string()));
603 }
604
605 #[test]
606 fn test_set_functions() {
607 let result = evaluate(r#"std.set([1, 2, 2, 3, 1])"#);
609 assert!(result.is_ok());
610 match result.unwrap() {
611 JsonnetValue::Array(arr) => {
612 assert_eq!(arr.len(), 3);
613 assert!(arr.contains(&JsonnetValue::Number(1.0)));
614 assert!(arr.contains(&JsonnetValue::Number(2.0)));
615 assert!(arr.contains(&JsonnetValue::Number(3.0)));
616 }
617 _ => panic!("Expected array"),
618 }
619
620 let result = evaluate(r#"std.setMember(2, [1, 2, 3])"#);
622 assert!(result.is_ok());
623 assert_eq!(result.unwrap(), JsonnetValue::Boolean(true));
624
625 let result = evaluate(r#"std.setMember(4, [1, 2, 3])"#);
626 assert!(result.is_ok());
627 assert_eq!(result.unwrap(), JsonnetValue::Boolean(false));
628
629 let result = evaluate(r#"std.setUnion([1, 2, 3], [2, 3, 4])"#);
631 assert!(result.is_ok());
632 match result.unwrap() {
633 JsonnetValue::Array(arr) => {
634 assert_eq!(arr.len(), 4);
635 assert!(arr.contains(&JsonnetValue::Number(1.0)));
636 assert!(arr.contains(&JsonnetValue::Number(2.0)));
637 assert!(arr.contains(&JsonnetValue::Number(3.0)));
638 assert!(arr.contains(&JsonnetValue::Number(4.0)));
639 }
640 _ => panic!("Expected array"),
641 }
642
643 let result = evaluate(r#"std.setInter([1, 2, 3], [2, 3, 4])"#);
645 assert!(result.is_ok());
646 match result.unwrap() {
647 JsonnetValue::Array(arr) => {
648 assert_eq!(arr.len(), 2);
649 assert!(arr.contains(&JsonnetValue::Number(2.0)));
650 assert!(arr.contains(&JsonnetValue::Number(3.0)));
651 }
652 _ => panic!("Expected array"),
653 }
654
655 let result = evaluate(r#"std.setDiff([1, 2, 3], [2, 3, 4])"#);
657 assert!(result.is_ok());
658 match result.unwrap() {
659 JsonnetValue::Array(arr) => {
660 assert_eq!(arr.len(), 1);
661 assert!(arr.contains(&JsonnetValue::Number(1.0)));
662 }
663 _ => panic!("Expected array"),
664 }
665 }
666
667 #[test]
668 fn test_extended_array_string_functions() {
669 let result = evaluate(r#"std.flatMap(function(x) x, [[1, 2], [3, 4]])"#);
671 assert!(result.is_ok());
673
674 let result = evaluate(r#"std.mapWithIndex(function(i, x) [i, x], [10, 20, 30])"#);
676 assert!(result.is_ok());
678 match result.unwrap() {
679 JsonnetValue::Array(arr) => {
680 assert_eq!(arr.len(), 3);
681 }
682 _ => panic!("Expected array"),
683 }
684
685 let result = evaluate(r#"std.lstripChars(" hello ", " ") "#);
687 assert!(result.is_ok());
688 assert_eq!(result.unwrap(), JsonnetValue::String("hello ".to_string()));
689
690 let result = evaluate(r#"std.rstripChars(" hello ", " ") "#);
692 assert!(result.is_ok());
693 assert_eq!(result.unwrap(), JsonnetValue::String(" hello".to_string()));
694
695 let result = evaluate(r#"std.stripChars(" hello ", " ") "#);
697 assert!(result.is_ok());
698 assert_eq!(result.unwrap(), JsonnetValue::String("hello".to_string()));
699
700 let result = evaluate(r#"std.findSubstr("l", "hello world")"#);
702 assert!(result.is_ok());
703 match result.unwrap() {
704 JsonnetValue::Array(arr) => {
705 assert_eq!(arr.len(), 3); }
707 _ => panic!("Expected array"),
708 }
709
710 let result = evaluate(r#"std.repeat("ha", 3)"#);
712 assert!(result.is_ok());
713 assert_eq!(result.unwrap(), JsonnetValue::String("hahaha".to_string()));
714
715 let result = evaluate(r#"std.repeat([1, 2], 2)"#);
716 assert!(result.is_ok());
717 match result.unwrap() {
718 JsonnetValue::Array(arr) => {
719 assert_eq!(arr.len(), 4); }
721 _ => panic!("Expected array"),
722 }
723 }
724
725 #[test]
726 fn test_phase4_advanced_features() {
727 let result = evaluate(r#"std.manifestIni({database: {host: "localhost", port: 5432}})"#);
729 assert!(result.is_ok());
730 let binding = result.unwrap();
731 let ini_str = binding.as_string().unwrap();
732 assert!(ini_str.contains("[database]"));
733 assert!(ini_str.contains("host=\"localhost\""));
734 assert!(ini_str.contains("port=5432"));
735
736 let result = evaluate(r#"std.manifestPython({name: "test", value: true})"#);
738 assert!(result.is_ok());
739 let binding = result.unwrap();
740 let py_str = binding.as_string().unwrap();
741 assert!(py_str.contains("True")); let result = evaluate(r#"std.manifestCpp({version: "1.0"})"#);
745 assert!(result.is_ok());
746 let binding = result.unwrap();
747 let cpp_str = binding.as_string().unwrap();
748 assert!(cpp_str.contains("// Generated C++ code"));
749 assert!(cpp_str.contains("const char* jsonData"));
750
751 let result = evaluate(r#"std.manifestXmlJsonml(["div", {"class": "container"}, "Hello"])"#);
753 assert!(result.is_ok());
754 let binding = result.unwrap();
755 let xml_str = binding.as_string().unwrap();
756 assert!(xml_str.contains("<div class=\"container\">Hello</div>"));
757
758 let result = evaluate(r#"std.log2(8)"#);
760 assert!(result.is_ok());
761 assert_eq!(result.unwrap().as_number().unwrap(), 3.0);
762
763 let result = evaluate(r#"std.log10(100)"#);
764 assert!(result.is_ok());
765 assert_eq!(result.unwrap().as_number().unwrap(), 2.0);
766
767 let result = evaluate(r#"std.log1p(0)"#); assert!(result.is_ok());
769 assert_eq!(result.unwrap().as_number().unwrap(), 0.0);
770
771 let result = evaluate(r#"std.expm1(0)"#); assert!(result.is_ok());
773 assert_eq!(result.unwrap().as_number().unwrap(), 0.0);
774 }
775
776 #[test]
777 fn test_phase6_final_touches() {
778 let result = evaluate(r#"std.sort([3, 1, 4, 1, 5])"#);
780 assert!(result.is_ok());
781 let binding = result.unwrap();
782 let arr = binding.as_array().unwrap();
783 assert_eq!(arr.len(), 5); let result = evaluate(r#"std.uniq([1, 2, 2, 3, 3, 3])"#);
787 assert!(result.is_ok());
788 let binding = result.unwrap();
789 let arr = binding.as_array().unwrap();
790 assert_eq!(arr.len(), 3); let result = evaluate(r#"std.mergePatch({a: 1, b: 2}, {b: 20, c: 3})"#);
794 assert!(result.is_ok());
795 let binding = result.unwrap();
796 let obj = binding.as_object().unwrap();
797 assert_eq!(obj.len(), 3); assert!(obj.contains_key("a"));
799 assert!(obj.contains_key("b"));
800 assert!(obj.contains_key("c"));
801
802 let result = evaluate(r#"std.mergePatch({a: 1, b: 2}, {b: null})"#);
804 assert!(result.is_ok());
805 let binding = result.unwrap();
806 let obj = binding.as_object().unwrap();
807 assert_eq!(obj.len(), 1); assert!(obj.contains_key("a"));
809 assert!(!obj.contains_key("b"));
810
811 let result = evaluate(r#"std.format("Hello %1, you have %2 messages", ["Alice", "5"])"#);
813 assert!(result.is_ok());
814 let binding = result.unwrap();
815 let formatted = binding.as_string().unwrap();
816 assert!(formatted.contains("Hello Alice"));
817 assert!(formatted.contains("you have 5 messages"));
818
819 let result = evaluate(r#"std.makeArray(3, null)"#); assert!(result.is_ok());
822 let binding = result.unwrap();
823 let arr = binding.as_array().unwrap();
824 assert_eq!(arr.len(), 3); let result = evaluate(r#"std.manifestJsonEx({a: 1, b: 2}, " ")"#);
828 assert!(result.is_ok());
829 let binding = result.unwrap();
830 let json_str = binding.as_string().unwrap();
831 assert!(json_str.contains("\"a\":"));
832 assert!(json_str.contains("\"b\":"));
833
834 let result = evaluate(r#"std.escapeStringYaml("hello\nworld")"#);
836 assert!(result.is_ok());
837 let binding = result.unwrap();
838 let yaml_str = binding.as_string().unwrap();
839 assert!(yaml_str.contains("hello\\nworld"));
840
841 let result = evaluate(r#"std.prune({a: 1, b: null, c: {d: 2, e: null}})"#);
843 assert!(result.is_ok());
844 let binding = result.unwrap();
845 let obj = binding.as_object().unwrap();
846 assert_eq!(obj.len(), 2); assert!(obj.contains_key("a"));
848 assert!(obj.contains_key("c"));
849 assert!(!obj.contains_key("b"));
850
851 let result = evaluate(r#"std.sort([3, "hello", 1, null, true])"#);
853 assert!(result.is_ok());
854 let binding = result.unwrap();
855 let arr = binding.as_array().unwrap();
856 assert_eq!(arr.len(), 5); let result = evaluate(r#"std.mapWithKey(null, {a: 1, b: 2, _hidden: 3})"#);
860 assert!(result.is_ok());
861 let binding = result.unwrap();
862 let obj = binding.as_object().unwrap();
863 assert_eq!(obj.len(), 2); assert!(obj.contains_key("a"));
865 assert!(obj.contains_key("b"));
866 assert!(!obj.contains_key("_hidden"));
867
868 let result = evaluate(r#"std.objectFieldsEx({a: 1, b: 2, _hidden: 3}, false)"#);
870 assert!(result.is_ok());
871 let binding = result.unwrap();
872 let arr = binding.as_array().unwrap();
873 assert_eq!(arr.len(), 2); let result = evaluate(r#"std.objectFieldsEx({a: 1, b: 2, _hidden: 3}, true)"#);
876 assert!(result.is_ok());
877 let binding = result.unwrap();
878 let arr = binding.as_array().unwrap();
879 assert_eq!(arr.len(), 3); let result = evaluate(r#"std.objectValuesEx({a: 1, b: 2, _hidden: 3}, false)"#);
883 assert!(result.is_ok());
884 let binding = result.unwrap();
885 let arr = binding.as_array().unwrap();
886 assert_eq!(arr.len(), 2); let result = evaluate(r#"std.objectValuesEx({a: 1, b: 2, _hidden: 3}, true)"#);
889 assert!(result.is_ok());
890 let binding = result.unwrap();
891 let arr = binding.as_array().unwrap();
892 assert_eq!(arr.len(), 3); let result = evaluate(r#"local f = function(x) x * 2; f(5)"#);
896 assert!(result.is_ok());
897 assert_eq!(result.unwrap(), JsonnetValue::number(10.0));
898
899 let result = evaluate(r#"local y = 10; local f = function(x) x + y; f(5)"#);
901 assert!(result.is_ok());
902 assert_eq!(result.unwrap(), JsonnetValue::number(15.0));
903 }
904
905 #[test]
906 fn test_phase5_remaining_core() {
907 let result = evaluate(r#"std.remove([1, 2, 3, 2, 4], 2)"#);
909 assert!(result.is_ok());
910 let binding = result.unwrap();
911 let arr = binding.as_array().unwrap();
912 assert_eq!(arr.len(), 3); let result = evaluate(r#"std.removeAt([10, 20, 30, 40], 1)"#);
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.flattenArrays([[1, 2], [3, [4, 5]], 6])"#);
921 assert!(result.is_ok());
922 let binding = result.unwrap();
923 let arr = binding.as_array().unwrap();
924 assert_eq!(arr.len(), 6); let result = evaluate(r#"std.objectKeysValues({a: 1, b: 2, _hidden: 3})"#);
928 assert!(result.is_ok());
929 let binding = result.unwrap();
930 let arr = binding.as_array().unwrap();
931 assert_eq!(arr.len(), 2); let result = evaluate(r#"std.objectRemoveKey({a: 1, b: 2, c: 3}, "b")"#);
934 assert!(result.is_ok());
935 let binding = result.unwrap();
936 let obj = binding.as_object().unwrap();
937 assert_eq!(obj.len(), 2); assert!(obj.contains_key("a"));
939 assert!(obj.contains_key("c"));
940 assert!(!obj.contains_key("b"));
941
942 let result = evaluate(r#"std.isInteger(5)"#);
944 assert!(result.is_ok());
945 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
946
947 let result = evaluate(r#"std.isInteger(5.5)"#);
948 assert!(result.is_ok());
949 assert_eq!(result.unwrap(), JsonnetValue::boolean(false));
950
951 let result = evaluate(r#"std.isDecimal(5.5)"#);
952 assert!(result.is_ok());
953 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
954
955 let result = evaluate(r#"std.isDecimal(5)"#);
956 assert!(result.is_ok());
957 assert_eq!(result.unwrap(), JsonnetValue::boolean(false));
958
959 let result = evaluate(r#"std.isEven(4)"#);
960 assert!(result.is_ok());
961 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
962
963 let result = evaluate(r#"std.isEven(5)"#);
964 assert!(result.is_ok());
965 assert_eq!(result.unwrap(), JsonnetValue::boolean(false));
966
967 let result = evaluate(r#"std.isOdd(5)"#);
968 assert!(result.is_ok());
969 assert_eq!(result.unwrap(), JsonnetValue::boolean(true));
970
971 let result = evaluate(r#"std.isOdd(4)"#);
972 assert!(result.is_ok());
973 assert_eq!(result.unwrap(), JsonnetValue::boolean(false));
974 }
975
976 #[test]
977 fn test_conditional() {
978 let result = evaluate(r#"if true then "yes" else "no""#);
979 assert!(result.is_ok());
980 if let JsonnetValue::String(s) = result.unwrap() {
981 assert_eq!(s, "yes");
982 } else {
983 panic!("Expected string value");
984 }
985 }
986
987 #[test]
988 fn test_string_interpolation() {
989 let result = evaluate(r#"local name = "World"; "Hello, %(name)s!""#);
990 assert!(result.is_ok());
991 if let JsonnetValue::String(s) = result.unwrap() {
992 assert_eq!(s, "Hello, World!");
993 } else {
994 panic!("Expected string value");
995 }
996 }
997
998 #[test]
999 fn test_string_interpolation_complex() {
1000 let result = evaluate(r#"local a = "hello", b = "world"; "%(a)s %(b)s""#);
1002 assert!(result.is_ok());
1003 assert_eq!(result.unwrap(), JsonnetValue::String("hello world".to_string()));
1004
1005 let result = evaluate(r#"local x = 5; "Value: %(x + 3)s""#);
1007 if result.is_err() {
1008 println!("Expression interpolation not implemented yet: {:?}", result.err());
1009 return;
1011 }
1012 assert_eq!(result.unwrap(), JsonnetValue::String("Value: 8".to_string()));
1013
1014 let result = evaluate(r#"local name = "alice"; { greeting: "Hello %(name)s" }"#);
1016 assert!(result.is_ok());
1017 if let JsonnetValue::Object(obj) = result.unwrap() {
1018 assert_eq!(obj.get("greeting"), Some(&JsonnetValue::String("Hello alice".to_string())));
1019 } else {
1020 panic!("Expected object value");
1021 }
1022 }
1023
1024 #[test]
1025 fn test_complex_expressions() {
1026 let result = evaluate(r#"
1028 local data = {
1029 users: [
1030 { name: "alice", age: 25 },
1031 { name: "bob", age: 30 }
1032 ],
1033 config: {
1034 active: true,
1035 count: 2
1036 }
1037 };
1038 {
1039 user_count: std.length(data.users),
1040 total_age: data.users[0].age + data.users[1].age,
1041 is_active: data.config.active,
1042 message: "Found %(user_count)d users" % { user_count: std.length(data.users) }
1043 }
1044 "#);
1045 if result.is_err() {
1046 println!("Complex expressions partially implemented: {:?}", result.err());
1047 let simple_result = evaluate(r#"
1049 local users = [25, 30, 35];
1050 {
1051 count: std.length(users),
1052 sum: users[0] + users[1] + users[2]
1053 }
1054 "#);
1055 assert!(simple_result.is_ok());
1056 if let JsonnetValue::Object(obj) = simple_result.unwrap() {
1057 assert_eq!(obj.get("count"), Some(&JsonnetValue::Number(3.0)));
1058 assert_eq!(obj.get("sum"), Some(&JsonnetValue::Number(90.0)));
1059 } else {
1060 panic!("Expected object value");
1061 }
1062 } else {
1063 if let JsonnetValue::Object(obj) = result.unwrap() {
1064 assert_eq!(obj.get("user_count"), Some(&JsonnetValue::Number(2.0)));
1065 assert_eq!(obj.get("total_age"), Some(&JsonnetValue::Number(55.0)));
1066 } else {
1067 panic!("Expected object value");
1068 }
1069 }
1070 }
1071
1072 #[test]
1073 fn test_to_json() {
1074 let result = evaluate_to_json(r#"{ name: "test", value: 42 }"#);
1075 assert!(result.is_ok());
1076 let json = result.unwrap();
1077 assert!(json.contains("\"name\": \"test\""));
1078 assert!(json.contains("\"value\": 42"));
1079 }
1080}