1#[macro_export]
105macro_rules! eure {
106 ({}) => {{
114 $crate::document::EureDocument::new_empty()
115 }};
116
117 ({ $($body:tt)* }) => {{
119 #[allow(unused_mut)]
120 let mut c = $crate::document::constructor::DocumentConstructor::new();
121 $crate::eure!(@stmt c; $($body)*);
122 c.finish()
123 }};
124
125 ($c:ident; { $($body:tt)* }) => {{
128 $crate::eure!(@stmt $c; $($body)*);
129 }};
130
131 (@value_tt null) => { $crate::value::PrimitiveValue::Null };
144
145 (@value_tt true) => { true };
147 (@value_tt false) => { false };
148
149 (@value_tt $v:literal) => { $v };
151
152 (@value_tt $v:expr) => { $v };
154
155 (@array_items $c:ident;) => {};
164
165 (@array_items $c:ident; , $($rest:tt)*) => {{
167 $crate::eure!(@array_items $c; $($rest)*);
168 }};
169
170 (@array_items $c:ident; @ code ($content:literal) $($rest:tt)*) => {{
172 let scope = $c.begin_scope();
173 $c.navigate($crate::path::PathSegment::ArrayIndex(None)).unwrap();
174 $c.bind_from($crate::text::Text::inline_implicit($content)).unwrap();
175 $c.end_scope(scope).unwrap();
176 $crate::eure!(@array_items $c; $($rest)*);
177 }};
178
179 (@array_items $c:ident; @ code ($lang:literal, $content:literal) $($rest:tt)*) => {{
181 let scope = $c.begin_scope();
182 $c.navigate($crate::path::PathSegment::ArrayIndex(None)).unwrap();
183 $c.bind_from($crate::text::Text::inline($content, $lang)).unwrap();
184 $c.end_scope(scope).unwrap();
185 $crate::eure!(@array_items $c; $($rest)*);
186 }};
187
188 (@array_items $c:ident; [$($inner:tt)*] $($rest:tt)*) => {{
190 let scope = $c.begin_scope();
191 $c.navigate($crate::path::PathSegment::ArrayIndex(None)).unwrap();
192 $c.bind_empty_array().unwrap();
193 $crate::eure!(@array_items $c; $($inner)*);
194 $c.end_scope(scope).unwrap();
195 $crate::eure!(@array_items $c; $($rest)*);
196 }};
197
198 (@array_items $c:ident; ($($inner:tt)*) $($rest:tt)*) => {{
200 let scope = $c.begin_scope();
201 $c.navigate($crate::path::PathSegment::ArrayIndex(None)).unwrap();
202 $c.bind_empty_tuple().unwrap();
203 $crate::eure!(@tuple_items $c 0; $($inner)*);
204 $c.end_scope(scope).unwrap();
205 $crate::eure!(@array_items $c; $($rest)*);
206 }};
207
208 (@array_items $c:ident; $item:tt $($rest:tt)*) => {{
210 let scope = $c.begin_scope();
211 $c.navigate($crate::path::PathSegment::ArrayIndex(None)).unwrap();
212 $c.bind_from($crate::eure!(@value_tt $item)).unwrap();
213 $c.end_scope(scope).unwrap();
214 $crate::eure!(@array_items $c; $($rest)*);
215 }};
216
217 (@tuple_items $c:ident $idx:expr;) => {};
226
227 (@tuple_items $c:ident $idx:expr; , $($rest:tt)*) => {{
229 $crate::eure!(@tuple_items $c $idx; $($rest)*);
230 }};
231
232 (@tuple_items $c:ident $idx:expr; @ code ($content:literal) $($rest:tt)*) => {{
234 let scope = $c.begin_scope();
235 $c.navigate($crate::path::PathSegment::TupleIndex($idx)).unwrap();
236 $c.bind_from($crate::text::Text::inline_implicit($content)).unwrap();
237 $c.end_scope(scope).unwrap();
238 $crate::eure!(@tuple_items $c ($idx + 1); $($rest)*);
239 }};
240
241 (@tuple_items $c:ident $idx:expr; @ code ($lang:literal, $content:literal) $($rest:tt)*) => {{
243 let scope = $c.begin_scope();
244 $c.navigate($crate::path::PathSegment::TupleIndex($idx)).unwrap();
245 $c.bind_from($crate::text::Text::inline($content, $lang)).unwrap();
246 $c.end_scope(scope).unwrap();
247 $crate::eure!(@tuple_items $c ($idx + 1); $($rest)*);
248 }};
249
250 (@tuple_items $c:ident $idx:expr; [$($inner:tt)*] $($rest:tt)*) => {{
252 let scope = $c.begin_scope();
253 $c.navigate($crate::path::PathSegment::TupleIndex($idx)).unwrap();
254 $c.bind_empty_array().unwrap();
255 $crate::eure!(@array_items $c; $($inner)*);
256 $c.end_scope(scope).unwrap();
257 $crate::eure!(@tuple_items $c ($idx + 1); $($rest)*);
258 }};
259
260 (@tuple_items $c:ident $idx:expr; ($($inner:tt)*) $($rest:tt)*) => {{
262 let scope = $c.begin_scope();
263 $c.navigate($crate::path::PathSegment::TupleIndex($idx)).unwrap();
264 $c.bind_empty_tuple().unwrap();
265 $crate::eure!(@tuple_items $c 0; $($inner)*);
266 $c.end_scope(scope).unwrap();
267 $crate::eure!(@tuple_items $c ($idx + 1); $($rest)*);
268 }};
269
270 (@tuple_items $c:ident $idx:expr; $item:tt $($rest:tt)*) => {{
272 let scope = $c.begin_scope();
273 $c.navigate($crate::path::PathSegment::TupleIndex($idx)).unwrap();
274 $c.bind_from($crate::eure!(@value_tt $item)).unwrap();
275 $c.end_scope(scope).unwrap();
276 $crate::eure!(@tuple_items $c ($idx + 1); $($rest)*);
277 }};
278
279 (@object_key $key:ident) => { stringify!($key) };
288
289 (@object_key $key:tt) => { $key };
291
292 (@object_items $c:ident;) => {};
300
301 (@object_items $c:ident; , $($rest:tt)*) => {{
303 $crate::eure!(@object_items $c; $($rest)*);
304 }};
305
306 (@object_items $c:ident; $key:tt => @ code ($content:literal) $($rest:tt)*) => {{
308 let scope = $c.begin_scope();
309 $c.navigate($crate::path::PathSegment::Value($crate::eure!(@object_key $key).into())).unwrap();
310 $c.bind_from($crate::text::Text::inline_implicit($content)).unwrap();
311 $c.end_scope(scope).unwrap();
312 $crate::eure!(@object_items $c; $($rest)*);
313 }};
314
315 (@object_items $c:ident; $key:tt => @ code ($lang:literal, $content:literal) $($rest:tt)*) => {{
317 let scope = $c.begin_scope();
318 $c.navigate($crate::path::PathSegment::Value($crate::eure!(@object_key $key).into())).unwrap();
319 $c.bind_from($crate::text::Text::inline($content, $lang)).unwrap();
320 $c.end_scope(scope).unwrap();
321 $crate::eure!(@object_items $c; $($rest)*);
322 }};
323
324 (@object_items $c:ident; $key:tt => [$($inner:tt)*] $($rest:tt)*) => {{
326 let scope = $c.begin_scope();
327 $c.navigate($crate::path::PathSegment::Value($crate::eure!(@object_key $key).into())).unwrap();
328 $c.bind_empty_array().unwrap();
329 $crate::eure!(@array_items $c; $($inner)*);
330 $c.end_scope(scope).unwrap();
331 $crate::eure!(@object_items $c; $($rest)*);
332 }};
333
334 (@object_items $c:ident; $key:tt => ($($inner:tt)*) $($rest:tt)*) => {{
336 let scope = $c.begin_scope();
337 $c.navigate($crate::path::PathSegment::Value($crate::eure!(@object_key $key).into())).unwrap();
338 $c.bind_empty_tuple().unwrap();
339 $crate::eure!(@tuple_items $c 0; $($inner)*);
340 $c.end_scope(scope).unwrap();
341 $crate::eure!(@object_items $c; $($rest)*);
342 }};
343
344 (@object_items $c:ident; $key:tt => $val:tt $($rest:tt)*) => {{
346 let scope = $c.begin_scope();
347 $c.navigate($crate::path::PathSegment::Value($crate::eure!(@object_key $key).into())).unwrap();
348 $c.bind_from($crate::eure!(@value_tt $val)).unwrap();
349 $c.end_scope(scope).unwrap();
350 $crate::eure!(@object_items $c; $($rest)*);
351 }};
352
353 (@stmt $c:ident;) => {};
367
368 (@stmt $c:ident; , $($rest:tt)*) => {{
370 $crate::eure!(@stmt $c; $($rest)*);
371 }};
372
373 (@stmt $c:ident; = ! $($rest:tt)*) => {{
376 $c.bind_hole(None).unwrap();
377 $crate::eure!(@stmt $c; $($rest)*);
378 }};
379
380 (@stmt $c:ident; = - $v:literal $($rest:tt)*) => {{
383 $c.bind_from(-$v).unwrap();
384 $crate::eure!(@stmt $c; $($rest)*);
385 }};
386
387 (@stmt $c:ident; = @ code ($content:literal) $($rest:tt)*) => {{
389 $c.bind_from($crate::text::Text::inline_implicit($content)).unwrap();
390 $crate::eure!(@stmt $c; $($rest)*);
391 }};
392
393 (@stmt $c:ident; = @ code ($lang:literal, $content:literal) $($rest:tt)*) => {{
395 $c.bind_from($crate::text::Text::inline($content, $lang)).unwrap();
396 $crate::eure!(@stmt $c; $($rest)*);
397 }};
398
399 (@stmt $c:ident; = @ block ($content:literal) $($rest:tt)*) => {{
401 $c.bind_from($crate::text::Text::block_implicit($content)).unwrap();
402 $crate::eure!(@stmt $c; $($rest)*);
403 }};
404
405 (@stmt $c:ident; = @ block ($lang:literal, $content:literal) $($rest:tt)*) => {{
407 $c.bind_from($crate::text::Text::block($content, $lang)).unwrap();
408 $crate::eure!(@stmt $c; $($rest)*);
409 }};
410
411 (@stmt $c:ident; = [] $($rest:tt)*) => {{
413 $c.bind_empty_array().unwrap();
414 $crate::eure!(@stmt $c; $($rest)*);
415 }};
416
417 (@stmt $c:ident; = [$($items:tt)+] $($rest:tt)*) => {{
419 $c.bind_empty_array().unwrap();
420 $crate::eure!(@array_items $c; $($items)+);
421 $crate::eure!(@stmt $c; $($rest)*);
422 }};
423
424 (@stmt $c:ident; = () $($rest:tt)*) => {{
426 $c.bind_empty_tuple().unwrap();
427 $crate::eure!(@stmt $c; $($rest)*);
428 }};
429
430 (@stmt $c:ident; = ($($items:tt)+) $($rest:tt)*) => {{
432 $c.bind_empty_tuple().unwrap();
433 $crate::eure!(@tuple_items $c 0; $($items)+);
434 $crate::eure!(@stmt $c; $($rest)*);
435 }};
436
437 (@stmt $c:ident; = { $key:tt => $($inner:tt)+ } $($rest:tt)*) => {{
439 $c.bind_empty_map().unwrap();
440 $crate::eure!(@object_items $c; $key => $($inner)+);
441 $crate::eure!(@stmt $c; $($rest)*);
442 }};
443
444 (@stmt $c:ident; = $v:tt $($rest:tt)*) => {{
446 $c.bind_from($crate::eure!(@value_tt $v)).unwrap();
447 $crate::eure!(@stmt $c; $($rest)*);
448 }};
449
450 (@stmt $c:ident; @ $seg:ident $($rest:tt)*) => {{
452 $c.begin_section();
453 let scope = $c.begin_scope();
454 $c.navigate($crate::path::PathSegment::Ident(
455 $crate::identifier::Identifier::new_unchecked(stringify!($seg))
456 )).unwrap();
457 $crate::eure!(@section_after_seg $c scope; $($rest)*);
458 }};
459
460 (@stmt $c:ident; $($tokens:tt)+) => {{
463 $c.begin_binding();
464 let scope = $c.begin_scope();
465 $crate::eure!(@path $c scope; $($tokens)+);
466 }};
467
468 (@section_after_seg $c:ident $scope:ident; . $seg:ident $($rest:tt)*) => {{
476 $c.navigate($crate::path::PathSegment::Ident(
477 $crate::identifier::Identifier::new_unchecked(stringify!($seg))
478 )).unwrap();
479 $crate::eure!(@section_after_seg $c $scope; $($rest)*);
480 }};
481
482 (@section_after_seg $c:ident $scope:ident; = $v:tt $($rest:tt)*) => {{
484 $c.bind_from($crate::eure!(@value_tt $v)).unwrap();
485 $c.begin_section_items();
486 $crate::eure!(@section_bindings $c $scope; $($rest)*);
488 }};
489
490 (@section_after_seg $c:ident $scope:ident; {} $($rest:tt)*) => {{
492 $c.begin_eure_block();
493 $c.bind_empty_map().unwrap();
494 $c.end_eure_block().unwrap();
495 $c.end_scope($scope).unwrap();
496 $c.end_section_block().unwrap();
497 $crate::eure!(@stmt $c; $($rest)*);
498 }};
499
500 (@section_after_seg $c:ident $scope:ident; { $($inner:tt)+ } $($rest:tt)*) => {{
502 $c.begin_eure_block();
503 $crate::eure!(@stmt $c; $($inner)+);
504 $c.end_eure_block().unwrap();
505 $c.end_scope($scope).unwrap();
506 $c.end_section_block().unwrap();
507 $crate::eure!(@stmt $c; $($rest)*);
508 }};
509
510 (@section_after_seg $c:ident $scope:ident; $($rest:tt)*) => {{
512 $c.begin_section_items();
513 $crate::eure!(@section_bindings $c $scope; $($rest)*);
514 }};
515
516 (@section_bindings $c:ident $scope:ident;) => {{
518 $c.end_section_items().unwrap();
519 $c.end_scope($scope).unwrap();
520 }};
521
522 (@section_bindings $c:ident $scope:ident; , $($rest:tt)*) => {{
524 $crate::eure!(@section_bindings $c $scope; $($rest)*);
525 }};
526
527 (@section_bindings $c:ident $scope:ident; @ $seg:ident $($rest:tt)*) => {{
529 $c.end_section_items().unwrap();
530 $c.end_scope($scope).unwrap();
531 $crate::eure!(@stmt $c; @ $seg $($rest)*);
532 }};
533
534 (@section_bindings $c:ident $scope:ident; $($tokens:tt)+) => {{
536 $c.begin_binding();
537 let inner_scope = $c.begin_scope();
538 $crate::eure!(@section_path $c $scope inner_scope; $($tokens)+);
539 }};
540
541 (@section_path $c:ident $section_scope:ident $scope:ident; $seg:ident $($rest:tt)*) => {{
543 $c.navigate($crate::path::PathSegment::Ident(
544 $crate::identifier::Identifier::new_unchecked(stringify!($seg))
545 )).unwrap();
546 $crate::eure!(@section_after_path $c $section_scope $scope; $($rest)*);
547 }};
548
549 (@section_path $c:ident $section_scope:ident $scope:ident; % $ext:ident $($rest:tt)*) => {{
551 $c.navigate($crate::path::PathSegment::Extension(
552 $crate::identifier::Identifier::new_unchecked(stringify!($ext))
553 )).unwrap();
554 $crate::eure!(@section_after_path $c $section_scope $scope; $($rest)*);
555 }};
556
557 (@section_path $c:ident $section_scope:ident $scope:ident; % $ext:literal $($rest:tt)*) => {{
559 $c.navigate($crate::path::PathSegment::Extension(
560 $ext.parse().unwrap()
561 )).unwrap();
562 $crate::eure!(@section_after_path $c $section_scope $scope; $($rest)*);
563 }};
564
565 (@section_path $c:ident $section_scope:ident $scope:ident; # $idx:literal $($rest:tt)*) => {{
567 $c.navigate($crate::path::PathSegment::TupleIndex($idx)).unwrap();
568 $crate::eure!(@section_after_path $c $section_scope $scope; $($rest)*);
569 }};
570
571 (@section_path $c:ident $section_scope:ident $scope:ident; ($($tuple:tt)*) $($rest:tt)*) => {{
573 let key = $crate::eure!(@build_tuple_key; $($tuple)*);
574 $c.navigate($crate::path::PathSegment::Value(key)).unwrap();
575 $crate::eure!(@section_after_path $c $section_scope $scope; $($rest)*);
576 }};
577
578 (@section_path $c:ident $section_scope:ident $scope:ident; $key:literal $($rest:tt)*) => {{
580 $c.navigate($crate::path::PathSegment::Value($key.into())).unwrap();
581 $crate::eure!(@section_after_path $c $section_scope $scope; $($rest)*);
582 }};
583
584 (@section_after_path $c:ident $section_scope:ident $scope:ident; [$($arr:tt)*] $($rest:tt)*) => {{
586 $crate::eure!(@section_array_marker $c $section_scope $scope [$($arr)*]; $($rest)*);
587 }};
588
589 (@section_after_path $c:ident $section_scope:ident $scope:ident; $($rest:tt)*) => {{
591 $crate::eure!(@section_terminal $c $section_scope $scope; $($rest)*);
592 }};
593
594 (@section_array_marker $c:ident $section_scope:ident $scope:ident []; $($rest:tt)*) => {{
596 $c.navigate($crate::path::PathSegment::ArrayIndex(None)).unwrap();
597 $crate::eure!(@section_terminal $c $section_scope $scope; $($rest)*);
598 }};
599
600 (@section_array_marker $c:ident $section_scope:ident $scope:ident [$idx:literal]; $($rest:tt)*) => {{
602 $c.navigate($crate::path::PathSegment::ArrayIndex(Some($idx))).unwrap();
603 $crate::eure!(@section_terminal $c $section_scope $scope; $($rest)*);
604 }};
605
606 (@section_terminal $c:ident $section_scope:ident $scope:ident; . $($rest:tt)+) => {{
608 $crate::eure!(@section_path $c $section_scope $scope; $($rest)+);
609 }};
610
611 (@section_terminal $c:ident $section_scope:ident $scope:ident; = ! $($rest:tt)*) => {{
613 $c.bind_hole(None).unwrap();
614 $c.end_scope($scope).unwrap();
615 $c.end_binding_value().unwrap();
616 $crate::eure!(@section_bindings $c $section_scope; $($rest)*);
617 }};
618
619 (@section_terminal $c:ident $section_scope:ident $scope:ident; = @ code ($content:literal) $($rest:tt)*) => {{
621 $c.bind_from($crate::text::Text::inline_implicit($content)).unwrap();
622 $c.end_scope($scope).unwrap();
623 $c.end_binding_value().unwrap();
624 $crate::eure!(@section_bindings $c $section_scope; $($rest)*);
625 }};
626
627 (@section_terminal $c:ident $section_scope:ident $scope:ident; = @ code ($lang:literal, $content:literal) $($rest:tt)*) => {{
629 $c.bind_from($crate::text::Text::inline($content, $lang)).unwrap();
630 $c.end_scope($scope).unwrap();
631 $c.end_binding_value().unwrap();
632 $crate::eure!(@section_bindings $c $section_scope; $($rest)*);
633 }};
634
635 (@section_terminal $c:ident $section_scope:ident $scope:ident; = @ block ($content:literal) $($rest:tt)*) => {{
637 $c.bind_from($crate::text::Text::block_implicit($content)).unwrap();
638 $c.end_scope($scope).unwrap();
639 $c.end_binding_value().unwrap();
640 $crate::eure!(@section_bindings $c $section_scope; $($rest)*);
641 }};
642
643 (@section_terminal $c:ident $section_scope:ident $scope:ident; = @ block ($lang:literal, $content:literal) $($rest:tt)*) => {{
645 $c.bind_from($crate::text::Text::block($content, $lang)).unwrap();
646 $c.end_scope($scope).unwrap();
647 $c.end_binding_value().unwrap();
648 $crate::eure!(@section_bindings $c $section_scope; $($rest)*);
649 }};
650
651 (@section_terminal $c:ident $section_scope:ident $scope:ident; = $v:tt $($rest:tt)*) => {{
653 $c.bind_from($crate::eure!(@value_tt $v)).unwrap();
654 $c.end_scope($scope).unwrap();
655 $c.end_binding_value().unwrap();
656 $crate::eure!(@section_bindings $c $section_scope; $($rest)*);
657 }};
658
659 (@section_terminal $c:ident $section_scope:ident $scope:ident; {} $($rest:tt)*) => {{
661 $c.begin_eure_block();
662 $c.bind_empty_map().unwrap();
663 $c.end_eure_block().unwrap();
664 $c.end_scope($scope).unwrap();
665 $c.end_binding_block().unwrap();
666 $crate::eure!(@section_bindings $c $section_scope; $($rest)*);
667 }};
668
669 (@section_terminal $c:ident $section_scope:ident $scope:ident; { $($inner:tt)+ } $($rest:tt)*) => {{
671 $c.begin_eure_block();
672 $crate::eure!(@stmt $c; $($inner)+);
673 $c.end_eure_block().unwrap();
674 $c.end_scope($scope).unwrap();
675 $c.end_binding_block().unwrap();
676 $crate::eure!(@section_bindings $c $section_scope; $($rest)*);
677 }};
678
679 (@path $c:ident $scope:ident; $seg:ident $($rest:tt)*) => {{
695 $c.navigate($crate::path::PathSegment::Ident(
696 $crate::identifier::Identifier::new_unchecked(stringify!($seg))
697 )).unwrap();
698 $crate::eure!(@after_path $c $scope; $($rest)*);
699 }};
700
701 (@path $c:ident $scope:ident; % $ext:ident $($rest:tt)*) => {{
704 $c.navigate($crate::path::PathSegment::Extension(
705 $crate::identifier::Identifier::new_unchecked(stringify!($ext))
706 )).unwrap();
707 $crate::eure!(@after_path $c $scope; $($rest)*);
708 }};
709
710 (@path $c:ident $scope:ident; % $ext:literal $($rest:tt)*) => {{
713 $c.navigate($crate::path::PathSegment::Extension(
714 $ext.parse().unwrap()
715 )).unwrap();
716 $crate::eure!(@after_path $c $scope; $($rest)*);
717 }};
718
719 (@path $c:ident $scope:ident; # $idx:literal $($rest:tt)*) => {{
721 $c.navigate($crate::path::PathSegment::TupleIndex($idx)).unwrap();
722 $crate::eure!(@after_path $c $scope; $($rest)*);
723 }};
724
725 (@path $c:ident $scope:ident; ($($tuple:tt)*) $($rest:tt)*) => {{
728 let key = $crate::eure!(@build_tuple_key; $($tuple)*);
729 $c.navigate($crate::path::PathSegment::Value(key)).unwrap();
730 $crate::eure!(@after_path $c $scope; $($rest)*);
731 }};
732
733 (@path $c:ident $scope:ident; $key:literal $($rest:tt)*) => {{
736 $c.navigate($crate::path::PathSegment::Value($key.into())).unwrap();
737 $crate::eure!(@after_path $c $scope; $($rest)*);
738 }};
739
740 (@build_tuple_key;) => {{
749 $crate::value::ObjectKey::Tuple($crate::value::Tuple(Default::default()))
750 }};
751
752 (@build_tuple_key; $($item:expr),+ $(,)?) => {{
754 $crate::value::ObjectKey::Tuple($crate::value::Tuple::from_iter(
755 [$(<_ as Into<$crate::value::ObjectKey>>::into($item)),+]
756 ))
757 }};
758
759 (@after_path $c:ident $scope:ident; [$($arr:tt)*] $($rest:tt)*) => {{
768 $crate::eure!(@array_marker $c $scope [$($arr)*]; $($rest)*);
769 }};
770
771 (@after_path $c:ident $scope:ident; $($rest:tt)*) => {{
773 $crate::eure!(@terminal $c $scope; $($rest)*);
774 }};
775
776 (@array_marker $c:ident $scope:ident []; $($rest:tt)*) => {{
786 $c.navigate($crate::path::PathSegment::ArrayIndex(None)).unwrap();
787 $crate::eure!(@terminal $c $scope; $($rest)*);
788 }};
789
790 (@array_marker $c:ident $scope:ident [$idx:literal]; $($rest:tt)*) => {{
792 $c.navigate($crate::path::PathSegment::ArrayIndex(Some($idx))).unwrap();
793 $crate::eure!(@terminal $c $scope; $($rest)*);
794 }};
795
796 (@terminal $c:ident $scope:ident; . $($rest:tt)+) => {{
814 $crate::eure!(@path $c $scope; $($rest)+);
815 }};
816
817 (@terminal $c:ident $scope:ident; = ! $($rest:tt)*) => {{
819 $c.bind_hole(None).unwrap();
820 $c.end_scope($scope).unwrap();
821 $c.end_binding_value().unwrap();
822 $crate::eure!(@stmt $c; $($rest)*);
823 }};
824
825 (@terminal $c:ident $scope:ident; = - $v:literal $($rest:tt)*) => {{
827 $c.bind_from(-$v).unwrap();
828 $c.end_scope($scope).unwrap();
829 $c.end_binding_value().unwrap();
830 $crate::eure!(@stmt $c; $($rest)*);
831 }};
832
833 (@terminal $c:ident $scope:ident; = @ code ($content:literal) $($rest:tt)*) => {{
835 $c.bind_from($crate::text::Text::inline_implicit($content)).unwrap();
836 $c.end_scope($scope).unwrap();
837 $c.end_binding_value().unwrap();
838 $crate::eure!(@stmt $c; $($rest)*);
839 }};
840
841 (@terminal $c:ident $scope:ident; = @ code ($lang:literal, $content:literal) $($rest:tt)*) => {{
843 $c.bind_from($crate::text::Text::inline($content, $lang)).unwrap();
844 $c.end_scope($scope).unwrap();
845 $c.end_binding_value().unwrap();
846 $crate::eure!(@stmt $c; $($rest)*);
847 }};
848
849 (@terminal $c:ident $scope:ident; = @ block ($content:literal) $($rest:tt)*) => {{
851 $c.bind_from($crate::text::Text::block_implicit($content)).unwrap();
852 $c.end_scope($scope).unwrap();
853 $c.end_binding_value().unwrap();
854 $crate::eure!(@stmt $c; $($rest)*);
855 }};
856
857 (@terminal $c:ident $scope:ident; = @ block ($lang:literal, $content:literal) $($rest:tt)*) => {{
859 $c.bind_from($crate::text::Text::block($content, $lang)).unwrap();
860 $c.end_scope($scope).unwrap();
861 $c.end_binding_value().unwrap();
862 $crate::eure!(@stmt $c; $($rest)*);
863 }};
864
865 (@terminal $c:ident $scope:ident; = [] $($rest:tt)*) => {{
867 $c.bind_empty_array().unwrap();
868 $c.end_scope($scope).unwrap();
869 $c.end_binding_value().unwrap();
870 $crate::eure!(@stmt $c; $($rest)*);
871 }};
872
873 (@terminal $c:ident $scope:ident; = [$($items:tt)+] $($rest:tt)*) => {{
875 $c.bind_empty_array().unwrap();
876 $crate::eure!(@array_items $c; $($items)+);
877 $c.end_scope($scope).unwrap();
878 $c.end_binding_value().unwrap();
879 $crate::eure!(@stmt $c; $($rest)*);
880 }};
881
882 (@terminal $c:ident $scope:ident; = () $($rest:tt)*) => {{
884 $c.bind_empty_tuple().unwrap();
885 $c.end_scope($scope).unwrap();
886 $c.end_binding_value().unwrap();
887 $crate::eure!(@stmt $c; $($rest)*);
888 }};
889
890 (@terminal $c:ident $scope:ident; = ($($items:tt)+) $($rest:tt)*) => {{
892 $c.bind_empty_tuple().unwrap();
893 $crate::eure!(@tuple_items $c 0; $($items)+);
894 $c.end_scope($scope).unwrap();
895 $c.end_binding_value().unwrap();
896 $crate::eure!(@stmt $c; $($rest)*);
897 }};
898
899 (@terminal $c:ident $scope:ident; = { $key:tt => $($inner:tt)+ } $($rest:tt)*) => {{
901 $c.bind_empty_map().unwrap();
902 $crate::eure!(@object_items $c; $key => $($inner)+);
903 $c.end_scope($scope).unwrap();
904 $c.end_binding_value().unwrap();
905 $crate::eure!(@stmt $c; $($rest)*);
906 }};
907
908 (@terminal $c:ident $scope:ident; = $v:tt $($rest:tt)*) => {{
910 $c.bind_from($crate::eure!(@value_tt $v)).unwrap();
911 $c.end_scope($scope).unwrap();
912 $c.end_binding_value().unwrap();
913 $crate::eure!(@stmt $c; $($rest)*);
914 }};
915
916 (@terminal $c:ident $scope:ident; {} $($rest:tt)*) => {{
918 $c.begin_eure_block();
919 $c.bind_empty_map().unwrap();
920 $c.end_eure_block().unwrap();
921 $c.end_scope($scope).unwrap();
922 $c.end_binding_block().unwrap();
923 $crate::eure!(@stmt $c; $($rest)*);
924 }};
925
926 (@terminal $c:ident $scope:ident; { $($inner:tt)+ } $($rest:tt)*) => {{
928 $c.begin_eure_block();
929 $crate::eure!(@stmt $c; $($inner)+);
930 $c.end_eure_block().unwrap();
931 $c.end_scope($scope).unwrap();
932 $c.end_binding_block().unwrap();
933 $crate::eure!(@stmt $c; $($rest)*);
934 }};
935}
936
937#[macro_export]
957macro_rules! eure_source {
958 ({}) => {{
960 $crate::source::SourceDocument::empty()
961 }};
962
963 ({ $($body:tt)* }) => {{
965 #[allow(unused_mut)]
966 let mut c = $crate::document::source_constructor::SourceConstructor::new();
967 $crate::eure!(c; { $($body)* });
968 c.finish()
969 }};
970}
971
972#[cfg(test)]
973mod tests {
974 use crate::document::EureDocument;
975 use alloc::vec;
976
977 #[test]
978 fn test_eure_empty() {
979 let doc = eure!({});
980 assert_eq!(doc, EureDocument::new_empty());
981 }
982
983 #[test]
984 fn test_eure_simple_assignment() {
985 let doc = eure!({ name = "Alice" });
986
987 let root_id = doc.get_root_id();
989 let root = doc.node(root_id);
990 let name_node_id = root.as_map().unwrap().get_node_id(&"name".into()).unwrap();
991 let name_node = doc.node(name_node_id);
992 let prim = name_node.as_primitive().unwrap();
993 assert_eq!(prim.as_str(), Some("Alice"));
994 }
995
996 #[test]
997 fn test_eure_nested_path() {
998 let doc = eure!({
999 user.name = "Bob"
1000 user.age = 30
1001 });
1002
1003 let root_id = doc.get_root_id();
1005 let root = doc.node(root_id);
1006 let user_id = root.as_map().unwrap().get_node_id(&"user".into()).unwrap();
1007 let user = doc.node(user_id);
1008 let name_id = user.as_map().unwrap().get_node_id(&"name".into()).unwrap();
1009 let name = doc.node(name_id);
1010 assert_eq!(name.as_primitive().unwrap().as_str(), Some("Bob"));
1011
1012 let age_id = user.as_map().unwrap().get_node_id(&"age".into()).unwrap();
1013 let age = doc.node(age_id);
1014 assert!(matches!(
1015 age.as_primitive(),
1016 Some(crate::value::PrimitiveValue::Integer(_))
1017 ));
1018 }
1019
1020 #[test]
1021 fn test_eure_block() {
1022 let doc = eure!({
1023 user {
1024 name = "Charlie"
1025 active = true
1026 }
1027 });
1028
1029 let root_id = doc.get_root_id();
1030 let root = doc.node(root_id);
1031 let user_id = root.as_map().unwrap().get_node_id(&"user".into()).unwrap();
1032 let user = doc.node(user_id);
1033 let name_id = user.as_map().unwrap().get_node_id(&"name".into()).unwrap();
1034 let name = doc.node(name_id);
1035 assert_eq!(name.as_primitive().unwrap().as_str(), Some("Charlie"));
1036 }
1037
1038 #[test]
1039 fn test_eure_extension() {
1040 let doc = eure!({
1041 field.%variant = @code("text")
1042 });
1043
1044 let root_id = doc.get_root_id();
1045 let root = doc.node(root_id);
1046 let field_id = root.as_map().unwrap().get_node_id(&"field".into()).unwrap();
1047 let field = doc.node(field_id);
1048
1049 let variant_id = field.get_extension(&"variant".parse().unwrap()).unwrap();
1051 let variant = doc.node(variant_id);
1052 let text = variant.as_primitive().unwrap().as_text().unwrap();
1053 assert_eq!(text.as_str(), "text");
1054 }
1055
1056 #[test]
1057 fn test_eure_extension_with_child() {
1058 let doc = eure!({
1060 field.%variant.name = @code("text")
1061 field.%variant.min_length = 3
1062 });
1063
1064 let root_id = doc.get_root_id();
1065 let root = doc.node(root_id);
1066 let field_id = root.as_map().unwrap().get_node_id(&"field".into()).unwrap();
1067 let field = doc.node(field_id);
1068
1069 let variant_id = field.get_extension(&"variant".parse().unwrap()).unwrap();
1071 let variant = doc.node(variant_id);
1072
1073 let name_id = variant
1075 .as_map()
1076 .unwrap()
1077 .get_node_id(&"name".into())
1078 .unwrap();
1079 let name = doc.node(name_id);
1080 let text = name.as_primitive().unwrap().as_text().unwrap();
1081 assert_eq!(text.as_str(), "text");
1082
1083 let min_length_id = variant
1084 .as_map()
1085 .unwrap()
1086 .get_node_id(&"min_length".into())
1087 .unwrap();
1088 let min_length = doc.node(min_length_id);
1089 assert!(matches!(
1090 min_length.as_primitive(),
1091 Some(crate::value::PrimitiveValue::Integer(_))
1092 ));
1093 }
1094
1095 #[test]
1096 fn test_eure_array() {
1097 let doc = eure!({ tags = ["a", "b", "c"] });
1098
1099 let root_id = doc.get_root_id();
1100 let root = doc.node(root_id);
1101 let tags_id = root.as_map().unwrap().get_node_id(&"tags".into()).unwrap();
1102 let tags = doc.node(tags_id);
1103 let array = tags.as_array().unwrap();
1104 assert_eq!(array.len(), 3);
1105 }
1106
1107 #[test]
1108 fn test_eure_tuple() {
1109 let doc = eure!({ point = (1.5, 2.5) });
1110
1111 let root_id = doc.get_root_id();
1112 let root = doc.node(root_id);
1113 let point_id = root.as_map().unwrap().get_node_id(&"point".into()).unwrap();
1114 let point = doc.node(point_id);
1115 let tuple = point.as_tuple().unwrap();
1116 assert_eq!(tuple.len(), 2);
1117 }
1118
1119 #[test]
1120 fn test_eure_multiple_assignments() {
1121 let doc = eure!({
1122 a = 1
1123 b = 2
1124 c = 3
1125 });
1126
1127 let root_id = doc.get_root_id();
1128 let root = doc.node(root_id);
1129 let map = root.as_map().unwrap();
1130 assert_eq!(map.len(), 3);
1131 }
1132
1133 #[test]
1134 fn test_eure_complex() {
1135 let doc = eure!({
1137 schema {
1138 field.%variant = @code("text")
1139 field.min_length = 3
1140 field.max_length = 20
1141 }
1142 tags = ["required"]
1143 });
1144
1145 let root_id = doc.get_root_id();
1146 let root = doc.node(root_id);
1147
1148 let schema_id = root
1150 .as_map()
1151 .unwrap()
1152 .get_node_id(&"schema".into())
1153 .unwrap();
1154 let schema = doc.node(schema_id);
1155
1156 let field_id = schema
1158 .as_map()
1159 .unwrap()
1160 .get_node_id(&"field".into())
1161 .unwrap();
1162 let field = doc.node(field_id);
1163 assert!(field.get_extension(&"variant".parse().unwrap()).is_some());
1164
1165 let tags_id = root.as_map().unwrap().get_node_id(&"tags".into()).unwrap();
1167 let tags = doc.node(tags_id);
1168 assert_eq!(tags.as_array().unwrap().len(), 1);
1169 }
1170
1171 #[test]
1172 fn test_eure_array_push() {
1173 let doc = eure!({
1175 items[] = 1
1176 items[] = 2
1177 items[] = 3
1178 });
1179
1180 let root_id = doc.get_root_id();
1181 let root = doc.node(root_id);
1182 let items_id = root.as_map().unwrap().get_node_id(&"items".into()).unwrap();
1183 let items = doc.node(items_id);
1184 let array = items.as_array().unwrap();
1185 assert_eq!(array.len(), 3);
1186 }
1187
1188 #[test]
1189 fn test_eure_array_push_with_child() {
1190 let doc = eure!({
1192 items[].name = "first"
1193 items[].name = "second"
1194 });
1195
1196 let root_id = doc.get_root_id();
1197 let root = doc.node(root_id);
1198 let items_id = root.as_map().unwrap().get_node_id(&"items".into()).unwrap();
1199 let items = doc.node(items_id);
1200 let array = items.as_array().unwrap();
1201 assert_eq!(array.len(), 2);
1202
1203 let first_id = array.get(0).unwrap();
1205 let first = doc.node(first_id);
1206 let name_id = first.as_map().unwrap().get_node_id(&"name".into()).unwrap();
1207 let name = doc.node(name_id);
1208 assert_eq!(name.as_primitive().unwrap().as_str(), Some("first"));
1209 }
1210
1211 #[test]
1212 fn test_eure_tuple_index() {
1213 let doc = eure!({
1215 point.#0 = 1.5
1216 point.#1 = 2.5
1217 });
1218
1219 let root_id = doc.get_root_id();
1220 let root = doc.node(root_id);
1221 let point_id = root.as_map().unwrap().get_node_id(&"point".into()).unwrap();
1222 let point = doc.node(point_id);
1223 let tuple = point.as_tuple().unwrap();
1224 assert_eq!(tuple.len(), 2);
1225 }
1226
1227 #[test]
1228 fn test_eure_mixed_path_extension_array() {
1229 let doc = eure!({
1231 field.%items[].name = "item1"
1232 field.%items[].name = "item2"
1233 });
1234
1235 let root_id = doc.get_root_id();
1236 let root = doc.node(root_id);
1237 let field_id = root.as_map().unwrap().get_node_id(&"field".into()).unwrap();
1238 let field = doc.node(field_id);
1239
1240 let items_id = field.get_extension(&"items".parse().unwrap()).unwrap();
1242 let items = doc.node(items_id);
1243 let array = items.as_array().unwrap();
1244 assert_eq!(array.len(), 2);
1245 }
1246
1247 #[test]
1248 fn test_eure_mixed_path_array_extension() {
1249 let doc = eure!({
1251 items[].%variant = @code("text")
1252 items[].%variant = @code("number")
1253 });
1254
1255 let root_id = doc.get_root_id();
1256 let root = doc.node(root_id);
1257 let items_id = root.as_map().unwrap().get_node_id(&"items".into()).unwrap();
1258 let items = doc.node(items_id);
1259 let array = items.as_array().unwrap();
1260 assert_eq!(array.len(), 2);
1261
1262 let first_id = array.get(0).unwrap();
1264 let first = doc.node(first_id);
1265 let variant_id = first.get_extension(&"variant".parse().unwrap()).unwrap();
1266 let variant = doc.node(variant_id);
1267 assert_eq!(
1268 variant.as_primitive().unwrap().as_text().unwrap().as_str(),
1269 "text"
1270 );
1271 }
1272
1273 #[test]
1274 fn test_eure_tuple_key() {
1275 use crate::value::{ObjectKey, Tuple};
1276
1277 let doc = eure!({
1279 map.(1, "key") = "value1"
1280 map.(2, "key") = "value2"
1281 });
1282
1283 let root_id = doc.get_root_id();
1284 let root = doc.node(root_id);
1285 let map_id = root.as_map().unwrap().get_node_id(&"map".into()).unwrap();
1286 let map_node = doc.node(map_id);
1287 let map = map_node.as_map().unwrap();
1288 assert_eq!(map.len(), 2);
1289
1290 let tuple_key = ObjectKey::Tuple(Tuple(alloc::vec![1.into(), "key".into()]));
1292 let value_id = map.get_node_id(&tuple_key).unwrap();
1293 let value = doc.node(value_id);
1294 assert_eq!(value.as_primitive().unwrap().as_str(), Some("value1"));
1295 }
1296
1297 #[test]
1298 fn test_eure_tuple_key_with_bool() {
1299 use crate::value::{ObjectKey, Tuple};
1300
1301 let doc = eure!({
1303 map.(true, 1) = "yes"
1304 map.(false, 1) = "no"
1305 });
1306
1307 let root_id = doc.get_root_id();
1308 let root = doc.node(root_id);
1309 let map_id = root.as_map().unwrap().get_node_id(&"map".into()).unwrap();
1310 let map_node = doc.node(map_id);
1311 let map = map_node.as_map().unwrap();
1312 assert_eq!(map.len(), 2);
1313
1314 let tuple_key = ObjectKey::Tuple(Tuple(alloc::vec![true.into(), 1.into()]));
1316 let value_id = map.get_node_id(&tuple_key).unwrap();
1317 let value = doc.node(value_id);
1318 assert_eq!(value.as_primitive().unwrap().as_str(), Some("yes"));
1319 }
1320
1321 #[test]
1322 fn test_eure_tuple_key_with_child() {
1323 use crate::value::{ObjectKey, Tuple};
1324
1325 let doc = eure!({
1327 map.(1, 2).name = "point_a"
1328 map.(1, 2).value = 42
1329 });
1330
1331 let root_id = doc.get_root_id();
1332 let root = doc.node(root_id);
1333 let map_id = root.as_map().unwrap().get_node_id(&"map".into()).unwrap();
1334 let map_node = doc.node(map_id);
1335 let map = map_node.as_map().unwrap();
1336
1337 let tuple_key = ObjectKey::Tuple(Tuple(alloc::vec![1.into(), 2.into()]));
1339 let entry_id = map.get_node_id(&tuple_key).unwrap();
1340 let entry = doc.node(entry_id);
1341 let entry_map = entry.as_map().unwrap();
1342
1343 let name_id = entry_map.get_node_id(&"name".into()).unwrap();
1344 let name = doc.node(name_id);
1345 assert_eq!(name.as_primitive().unwrap().as_str(), Some("point_a"));
1346 }
1347
1348 #[test]
1349 fn test_eure_string_key() {
1350 let doc = eure!({
1352 field."min-length" = 3
1353 field."max-length" = 20
1354 });
1355
1356 let root_id = doc.get_root_id();
1357 let root = doc.node(root_id);
1358 let field_id = root.as_map().unwrap().get_node_id(&"field".into()).unwrap();
1359 let field = doc.node(field_id);
1360 let field_map = field.as_map().unwrap();
1361
1362 let min_id = field_map.get_node_id(&"min-length".into()).unwrap();
1364 let min_node = doc.node(min_id);
1365 assert!(matches!(
1366 min_node.as_primitive(),
1367 Some(crate::value::PrimitiveValue::Integer(_))
1368 ));
1369 }
1370
1371 #[test]
1372 fn test_eure_object_literal() {
1373 let doc = eure!({
1375 variants.click = { "x" => 1.0, "y" => 2.0 }
1376 });
1377
1378 let root_id = doc.get_root_id();
1379 let root = doc.node(root_id);
1380 let variants_id = root
1381 .as_map()
1382 .unwrap()
1383 .get_node_id(&"variants".into())
1384 .unwrap();
1385 let variants = doc.node(variants_id);
1386 let click_id = variants
1387 .as_map()
1388 .unwrap()
1389 .get_node_id(&"click".into())
1390 .unwrap();
1391 let click = doc.node(click_id);
1392 let click_map = click.as_map().unwrap();
1393
1394 assert_eq!(click_map.len(), 2);
1395 assert!(click_map.get(&"x".into()).is_some());
1396 assert!(click_map.get(&"y".into()).is_some());
1397 }
1398
1399 #[test]
1400 fn test_eure_object_literal_with_string() {
1401 let doc = eure!({
1403 schema.variants.success = { "data" => "any" }
1404 });
1405
1406 let root_id = doc.get_root_id();
1407 let root = doc.node(root_id);
1408 let schema_id = root
1409 .as_map()
1410 .unwrap()
1411 .get_node_id(&"schema".into())
1412 .unwrap();
1413 let schema = doc.node(schema_id);
1414 let variants_id = schema
1415 .as_map()
1416 .unwrap()
1417 .get_node_id(&"variants".into())
1418 .unwrap();
1419 let variants = doc.node(variants_id);
1420 let success_id = variants
1421 .as_map()
1422 .unwrap()
1423 .get_node_id(&"success".into())
1424 .unwrap();
1425 let success = doc.node(success_id);
1426 let success_map = success.as_map().unwrap();
1427
1428 let data_id = success_map.get_node_id(&"data".into()).unwrap();
1429 let data = doc.node(data_id);
1430 assert_eq!(data.as_primitive().unwrap().as_str(), Some("any"));
1431 }
1432
1433 #[test]
1434 fn test_eure_value_binding() {
1435 let doc = eure!({
1437 = @code("hello")
1438 });
1439
1440 let root_id = doc.get_root_id();
1441 let root = doc.node(root_id);
1442 let text = root.as_primitive().unwrap().as_text().unwrap();
1443 assert_eq!(text.as_str(), "hello");
1444 }
1445
1446 #[test]
1447 fn test_eure_value_binding_with_extension() {
1448 let doc = eure!({
1450 = @code("any")
1451 %variant = "literal"
1452 });
1453
1454 let root_id = doc.get_root_id();
1455 let root = doc.node(root_id);
1456
1457 let text = root.as_primitive().unwrap().as_text().unwrap();
1459 assert_eq!(text.as_str(), "any");
1460
1461 let variant_id = root.get_extension(&"variant".parse().unwrap()).unwrap();
1463 let variant = doc.node(variant_id);
1464 assert_eq!(variant.as_primitive().unwrap().as_str(), Some("literal"));
1465 }
1466
1467 #[test]
1468 fn test_eure_empty_block() {
1469 let doc = eure!({ config {} });
1471
1472 let root_id = doc.get_root_id();
1473 let root = doc.node(root_id);
1474 let config_id = root
1475 .as_map()
1476 .unwrap()
1477 .get_node_id(&"config".into())
1478 .unwrap();
1479 let config = doc.node(config_id);
1480
1481 let map = config
1483 .as_map()
1484 .expect("Empty block should create an empty map");
1485 assert!(map.is_empty());
1486 }
1487
1488 #[test]
1493 fn test_eure_null_literal() {
1494 let doc = eure!({ optional = null });
1496
1497 let root_id = doc.get_root_id();
1498 let root = doc.node(root_id);
1499 let opt_id = root
1500 .as_map()
1501 .unwrap()
1502 .get_node_id(&"optional".into())
1503 .unwrap();
1504 let opt = doc.node(opt_id);
1505 assert!(matches!(
1506 opt.as_primitive(),
1507 Some(crate::value::PrimitiveValue::Null)
1508 ));
1509 }
1510
1511 #[test]
1512 fn test_eure_null_root() {
1513 let doc = eure!({
1515 = null
1516 });
1517
1518 let root_id = doc.get_root_id();
1519 let root = doc.node(root_id);
1520 assert!(matches!(
1521 root.as_primitive(),
1522 Some(crate::value::PrimitiveValue::Null)
1523 ));
1524 }
1525
1526 #[test]
1527 fn test_eure_hole_literal() {
1528 use crate::document::node::NodeValue;
1529
1530 let doc = eure!({
1532 placeholder = !
1533 });
1534
1535 let root_id = doc.get_root_id();
1536 let root = doc.node(root_id);
1537 let placeholder_id = root
1538 .as_map()
1539 .unwrap()
1540 .get_node_id(&"placeholder".into())
1541 .unwrap();
1542 let placeholder = doc.node(placeholder_id);
1543 assert_eq!(placeholder.content, NodeValue::Hole(None));
1544 }
1545
1546 #[test]
1547 fn test_eure_hole_root() {
1548 use crate::document::node::NodeValue;
1549
1550 let doc = eure!({
1552 = !
1553 });
1554
1555 let root_id = doc.get_root_id();
1556 let root = doc.node(root_id);
1557 assert_eq!(root.content, NodeValue::Hole(None));
1558 }
1559
1560 #[test]
1561 fn test_eure_code_inline_implicit() {
1562 let doc = eure!({
1564 snippet = @code("let x = 1")
1565 });
1566
1567 let root_id = doc.get_root_id();
1568 let root = doc.node(root_id);
1569 let snippet_id = root
1570 .as_map()
1571 .unwrap()
1572 .get_node_id(&"snippet".into())
1573 .unwrap();
1574 let snippet = doc.node(snippet_id);
1575 let text = snippet.as_primitive().unwrap().as_text().unwrap();
1576 assert_eq!(text.as_str(), "let x = 1");
1577 assert!(text.language.is_implicit());
1578 }
1579
1580 #[test]
1581 fn test_eure_code_inline_with_language() {
1582 let doc = eure!({
1584 query = @code("sql", "SELECT * FROM users")
1585 });
1586
1587 let root_id = doc.get_root_id();
1588 let root = doc.node(root_id);
1589 let query_id = root.as_map().unwrap().get_node_id(&"query".into()).unwrap();
1590 let query = doc.node(query_id);
1591 let text = query.as_primitive().unwrap().as_text().unwrap();
1592 assert_eq!(text.as_str(), "SELECT * FROM users");
1593 assert_eq!(text.language.as_str(), Some("sql"));
1594 }
1595
1596 #[test]
1597 fn test_eure_block_implicit() {
1598 let doc = eure!({
1600 script = @block("fn main() {}")
1601 });
1602
1603 let root_id = doc.get_root_id();
1604 let root = doc.node(root_id);
1605 let script_id = root
1606 .as_map()
1607 .unwrap()
1608 .get_node_id(&"script".into())
1609 .unwrap();
1610 let script = doc.node(script_id);
1611 let text = script.as_primitive().unwrap().as_text().unwrap();
1612 assert_eq!(text.as_str(), "fn main() {}\n");
1614 assert!(text.language.is_implicit());
1615 }
1616
1617 #[test]
1618 fn test_eure_block_with_language() {
1619 let doc = eure!({
1621 code = @block("rust", "fn main() {\n println!(\"Hello\");\n}")
1622 });
1623
1624 let root_id = doc.get_root_id();
1625 let root = doc.node(root_id);
1626 let code_id = root.as_map().unwrap().get_node_id(&"code".into()).unwrap();
1627 let code = doc.node(code_id);
1628 let text = code.as_primitive().unwrap().as_text().unwrap();
1629 assert_eq!(text.language.as_str(), Some("rust"));
1630 assert!(text.as_str().contains("println!"));
1631 }
1632
1633 #[test]
1634 fn test_eure_code_at_root() {
1635 let doc = eure!({
1637 = @code("hello")
1638 });
1639
1640 let root_id = doc.get_root_id();
1641 let root = doc.node(root_id);
1642 let text = root.as_primitive().unwrap().as_text().unwrap();
1643 assert_eq!(text.as_str(), "hello");
1644 }
1645
1646 #[test]
1647 fn test_eure_code_with_language_at_root() {
1648 let doc = eure!({
1650 = @code("sql", "SELECT 1")
1651 });
1652
1653 let root_id = doc.get_root_id();
1654 let root = doc.node(root_id);
1655 let text = root.as_primitive().unwrap().as_text().unwrap();
1656 assert_eq!(text.as_str(), "SELECT 1");
1657 assert_eq!(text.language.as_str(), Some("sql"));
1658 }
1659
1660 #[test]
1661 fn test_eure_block_at_root() {
1662 let doc = eure!({
1664 = @block("fn main() {}")
1665 });
1666
1667 let root_id = doc.get_root_id();
1668 let root = doc.node(root_id);
1669 let text = root.as_primitive().unwrap().as_text().unwrap();
1670 assert_eq!(text.as_str(), "fn main() {}\n");
1671 assert!(text.language.is_implicit());
1672 }
1673
1674 #[test]
1675 fn test_eure_block_with_language_at_root() {
1676 let doc = eure!({
1678 = @block("rust", "fn main() {}")
1679 });
1680
1681 let root_id = doc.get_root_id();
1682 let root = doc.node(root_id);
1683 let text = root.as_primitive().unwrap().as_text().unwrap();
1684 assert_eq!(text.as_str(), "fn main() {}\n");
1685 assert_eq!(text.language.as_str(), Some("rust"));
1686 }
1687
1688 #[test]
1693 fn test_eure_array_specific_index() {
1694 let doc = eure!({
1696 items[0] = "first"
1697 items[1] = "second"
1698 });
1699
1700 let root_id = doc.get_root_id();
1701 let root = doc.node(root_id);
1702 let items_id = root.as_map().unwrap().get_node_id(&"items".into()).unwrap();
1703 let items = doc.node(items_id);
1704 let array = items.as_array().unwrap();
1705 assert_eq!(array.len(), 2);
1706
1707 let first_id = array.get(0).unwrap();
1709 let first = doc.node(first_id);
1710 assert_eq!(first.as_primitive().unwrap().as_str(), Some("first"));
1711
1712 let second_id = array.get(1).unwrap();
1713 let second = doc.node(second_id);
1714 assert_eq!(second.as_primitive().unwrap().as_str(), Some("second"));
1715 }
1716
1717 #[test]
1718 fn test_eure_array_index_with_child() {
1719 let doc = eure!({
1721 items[0].name = "first"
1722 items[0].value = 1
1723 items[1].name = "second"
1724 });
1725
1726 let root_id = doc.get_root_id();
1727 let root = doc.node(root_id);
1728 let items_id = root.as_map().unwrap().get_node_id(&"items".into()).unwrap();
1729 let items = doc.node(items_id);
1730 let array = items.as_array().unwrap();
1731 assert_eq!(array.len(), 2);
1732
1733 let first_id = array.get(0).unwrap();
1735 let first = doc.node(first_id);
1736 let name_id = first.as_map().unwrap().get_node_id(&"name".into()).unwrap();
1737 let name = doc.node(name_id);
1738 assert_eq!(name.as_primitive().unwrap().as_str(), Some("first"));
1739 }
1740
1741 #[test]
1742 fn test_eure_nested_empty_blocks() {
1743 let doc = eure!({
1745 a {
1746 b {
1747 c {}
1748 }
1749 }
1750 });
1751
1752 let root_id = doc.get_root_id();
1753 let root = doc.node(root_id);
1754
1755 let a_id = root.as_map().unwrap().get_node_id(&"a".into()).unwrap();
1756 let a = doc.node(a_id);
1757
1758 let b_id = a.as_map().unwrap().get_node_id(&"b".into()).unwrap();
1759 let b = doc.node(b_id);
1760
1761 let c_id = b.as_map().unwrap().get_node_id(&"c".into()).unwrap();
1762 let c = doc.node(c_id);
1763
1764 let map = c.as_map().expect("c should be an empty map");
1766 assert!(map.is_empty());
1767 }
1768
1769 #[test]
1770 fn test_eure_multiple_extensions() {
1771 let doc = eure!({
1773 field.%variant = @code("text")
1774 field.%"variant-repr" = "internal"
1775 field.%schema = "custom"
1776 });
1777
1778 let root_id = doc.get_root_id();
1779 let root = doc.node(root_id);
1780 let field_id = root.as_map().unwrap().get_node_id(&"field".into()).unwrap();
1781 let field = doc.node(field_id);
1782
1783 assert!(field.get_extension(&"variant".parse().unwrap()).is_some());
1785 assert!(
1786 field
1787 .get_extension(&"variant-repr".parse().unwrap())
1788 .is_some()
1789 );
1790 assert!(field.get_extension(&"schema".parse().unwrap()).is_some());
1791 }
1792
1793 #[test]
1794 fn test_eure_extension_on_array_element() {
1795 let doc = eure!({
1798 items[0].%variant = @code("text")
1799 items[0].value = "first"
1800 items[1].%variant = @code("number")
1801 items[1].value = 42
1802 });
1803
1804 let root_id = doc.get_root_id();
1805 let root = doc.node(root_id);
1806 let items_id = root.as_map().unwrap().get_node_id(&"items".into()).unwrap();
1807 let items = doc.node(items_id);
1808 let array = items.as_array().unwrap();
1809 assert_eq!(array.len(), 2);
1810
1811 let first_id = array.get(0).unwrap();
1813 let first = doc.node(first_id);
1814 let variant_id = first.get_extension(&"variant".parse().unwrap()).unwrap();
1815 let variant = doc.node(variant_id);
1816 assert_eq!(
1817 variant.as_primitive().unwrap().as_text().unwrap().as_str(),
1818 "text"
1819 );
1820 let value_id = first
1821 .as_map()
1822 .unwrap()
1823 .get_node_id(&"value".into())
1824 .unwrap();
1825 let value = doc.node(value_id);
1826 assert_eq!(value.as_primitive().unwrap().as_str(), Some("first"));
1827
1828 let second_id = array.get(1).unwrap();
1830 let second = doc.node(second_id);
1831 let variant_id = second.get_extension(&"variant".parse().unwrap()).unwrap();
1832 let variant = doc.node(variant_id);
1833 assert_eq!(
1834 variant.as_primitive().unwrap().as_text().unwrap().as_str(),
1835 "number"
1836 );
1837 }
1838
1839 #[test]
1840 fn test_eure_deep_nesting() {
1841 let doc = eure!({ a.b.c.d.e.f = "deep" });
1843
1844 let root_id = doc.get_root_id();
1845 let root = doc.node(root_id);
1846
1847 let a_id = root.as_map().unwrap().get_node_id(&"a".into()).unwrap();
1848 let a = doc.node(a_id);
1849 let b_id = a.as_map().unwrap().get_node_id(&"b".into()).unwrap();
1850 let b = doc.node(b_id);
1851 let c_id = b.as_map().unwrap().get_node_id(&"c".into()).unwrap();
1852 let c = doc.node(c_id);
1853 let d_id = c.as_map().unwrap().get_node_id(&"d".into()).unwrap();
1854 let d = doc.node(d_id);
1855 let e_id = d.as_map().unwrap().get_node_id(&"e".into()).unwrap();
1856 let e = doc.node(e_id);
1857 let f_id = e.as_map().unwrap().get_node_id(&"f".into()).unwrap();
1858 let f = doc.node(f_id);
1859
1860 assert_eq!(f.as_primitive().unwrap().as_str(), Some("deep"));
1861 }
1862
1863 #[test]
1864 fn test_eure_empty_array_literal() {
1865 let doc = eure!({ items = [] });
1867
1868 let root_id = doc.get_root_id();
1869 let root = doc.node(root_id);
1870 let items_id = root.as_map().unwrap().get_node_id(&"items".into()).unwrap();
1871 let items = doc.node(items_id);
1872 let array = items.as_array().unwrap();
1873 assert!(array.is_empty());
1874 }
1875
1876 #[test]
1877 fn test_eure_empty_tuple_literal() {
1878 let doc = eure!({ point = () });
1880
1881 let root_id = doc.get_root_id();
1882 let root = doc.node(root_id);
1883 let point_id = root.as_map().unwrap().get_node_id(&"point".into()).unwrap();
1884 let point = doc.node(point_id);
1885 let tuple = point.as_tuple().unwrap();
1886 assert!(tuple.is_empty());
1887 }
1888
1889 #[test]
1890 fn test_eure_empty_map_literal() {
1891 let doc = eure!({ data {} });
1894
1895 let root_id = doc.get_root_id();
1896 let root = doc.node(root_id);
1897 let data_id = root.as_map().unwrap().get_node_id(&"data".into()).unwrap();
1898 let data = doc.node(data_id);
1899 let map = data.as_map().unwrap();
1900 assert!(map.is_empty());
1901 }
1902
1903 #[test]
1904 fn test_eure_mixed_null_and_values() {
1905 let doc = eure!({
1907 name = "Alice"
1908 age = null
1909 active = true
1910 score = null
1911 });
1912
1913 let root_id = doc.get_root_id();
1914 let root = doc.node(root_id);
1915 let map = root.as_map().unwrap();
1916 assert_eq!(map.len(), 4);
1917
1918 let age_id = map.get_node_id(&"age".into()).unwrap();
1919 let age = doc.node(age_id);
1920 assert!(matches!(
1921 age.as_primitive(),
1922 Some(crate::value::PrimitiveValue::Null)
1923 ));
1924 }
1925
1926 #[test]
1931 fn test_eure_section_basic() {
1932 let doc = eure!({
1934 @user
1935 name = "Alice"
1936 age = 30
1937 });
1938
1939 let root_id = doc.get_root_id();
1940 let root = doc.node(root_id);
1941 let user_id = root.as_map().unwrap().get_node_id(&"user".into()).unwrap();
1942 let user = doc.node(user_id);
1943 let name_id = user.as_map().unwrap().get_node_id(&"name".into()).unwrap();
1944 let name = doc.node(name_id);
1945 assert_eq!(name.as_primitive().unwrap().as_str(), Some("Alice"));
1946 }
1947
1948 #[test]
1949 fn test_eure_section_multiple() {
1950 let doc = eure!({
1952 @user
1953 name = "Alice"
1954
1955 @settings
1956 theme = "dark"
1957 });
1958
1959 let root_id = doc.get_root_id();
1960 let root = doc.node(root_id);
1961
1962 let user_id = root.as_map().unwrap().get_node_id(&"user".into()).unwrap();
1963 let user = doc.node(user_id);
1964 assert!(user.as_map().unwrap().get_node_id(&"name".into()).is_some());
1965
1966 let settings_id = root
1967 .as_map()
1968 .unwrap()
1969 .get_node_id(&"settings".into())
1970 .unwrap();
1971 let settings = doc.node(settings_id);
1972 assert!(
1973 settings
1974 .as_map()
1975 .unwrap()
1976 .get_node_id(&"theme".into())
1977 .is_some()
1978 );
1979 }
1980
1981 #[test]
1982 fn test_eure_section_dotted_path() {
1983 let doc = eure!({
1985 @user.profile
1986 name = "Alice"
1987 });
1988
1989 let root_id = doc.get_root_id();
1990 let root = doc.node(root_id);
1991 let user_id = root.as_map().unwrap().get_node_id(&"user".into()).unwrap();
1992 let user = doc.node(user_id);
1993 let profile_id = user
1994 .as_map()
1995 .unwrap()
1996 .get_node_id(&"profile".into())
1997 .unwrap();
1998 let profile = doc.node(profile_id);
1999 assert!(
2000 profile
2001 .as_map()
2002 .unwrap()
2003 .get_node_id(&"name".into())
2004 .is_some()
2005 );
2006 }
2007
2008 #[test]
2009 fn test_eure_section_with_block() {
2010 let doc = eure!({
2012 @user {
2013 name = "Alice"
2014 age = 30
2015 }
2016 });
2017
2018 let root_id = doc.get_root_id();
2019 let root = doc.node(root_id);
2020 let user_id = root.as_map().unwrap().get_node_id(&"user".into()).unwrap();
2021 let user = doc.node(user_id);
2022 assert!(user.as_map().unwrap().get_node_id(&"name".into()).is_some());
2023 assert!(user.as_map().unwrap().get_node_id(&"age".into()).is_some());
2024 }
2025
2026 #[test]
2027 fn test_eure_section_block_with_nested() {
2028 let doc = eure!({
2030 @config {
2031 server {
2032 host = "localhost"
2033 port = 8080
2034 }
2035 debug = true
2036 }
2037 });
2038
2039 let root_id = doc.get_root_id();
2040 let root = doc.node(root_id);
2041 let config_id = root
2042 .as_map()
2043 .unwrap()
2044 .get_node_id(&"config".into())
2045 .unwrap();
2046 let config = doc.node(config_id);
2047 assert!(
2048 config
2049 .as_map()
2050 .unwrap()
2051 .get_node_id(&"server".into())
2052 .is_some()
2053 );
2054 assert!(
2055 config
2056 .as_map()
2057 .unwrap()
2058 .get_node_id(&"debug".into())
2059 .is_some()
2060 );
2061
2062 let server_id = config
2063 .as_map()
2064 .unwrap()
2065 .get_node_id(&"server".into())
2066 .unwrap();
2067 let server = doc.node(server_id);
2068 assert!(
2069 server
2070 .as_map()
2071 .unwrap()
2072 .get_node_id(&"host".into())
2073 .is_some()
2074 );
2075 assert!(
2076 server
2077 .as_map()
2078 .unwrap()
2079 .get_node_id(&"port".into())
2080 .is_some()
2081 );
2082 }
2083
2084 #[test]
2085 fn test_eure_section_block_multiple() {
2086 let doc = eure!({
2088 @user {
2089 name = "Alice"
2090 }
2091 @settings {
2092 theme = "dark"
2093 }
2094 });
2095
2096 let root_id = doc.get_root_id();
2097 let root = doc.node(root_id);
2098 assert!(root.as_map().unwrap().get_node_id(&"user".into()).is_some());
2099 assert!(
2100 root.as_map()
2101 .unwrap()
2102 .get_node_id(&"settings".into())
2103 .is_some()
2104 );
2105 }
2106
2107 #[test]
2108 fn test_eure_section_block_dotted_path() {
2109 let doc = eure!({
2111 @server.config {
2112 host = "localhost"
2113 port = 8080
2114 }
2115 });
2116
2117 let root_id = doc.get_root_id();
2118 let root = doc.node(root_id);
2119 let server_id = root
2120 .as_map()
2121 .unwrap()
2122 .get_node_id(&"server".into())
2123 .unwrap();
2124 let server = doc.node(server_id);
2125 let config_id = server
2126 .as_map()
2127 .unwrap()
2128 .get_node_id(&"config".into())
2129 .unwrap();
2130 let config = doc.node(config_id);
2131 assert!(
2132 config
2133 .as_map()
2134 .unwrap()
2135 .get_node_id(&"host".into())
2136 .is_some()
2137 );
2138 assert!(
2139 config
2140 .as_map()
2141 .unwrap()
2142 .get_node_id(&"port".into())
2143 .is_some()
2144 );
2145 }
2146
2147 #[test]
2148 fn test_eure_section_block_empty() {
2149 let doc = eure!({
2151 @empty {}
2152 });
2153
2154 let root_id = doc.get_root_id();
2155 let root = doc.node(root_id);
2156 let empty_id = root.as_map().unwrap().get_node_id(&"empty".into()).unwrap();
2157 let empty = doc.node(empty_id);
2158 assert!(empty.as_map().unwrap().is_empty());
2160 }
2161
2162 #[test]
2163 fn test_eure_section_mixed_styles() {
2164 let doc = eure!({
2166 @user {
2167 name = "Alice"
2168 }
2169
2170 @settings
2171 theme = "dark"
2172 debug = true
2173
2174 @logging {
2175 level = "info"
2176 }
2177 });
2178
2179 let root_id = doc.get_root_id();
2180 let root = doc.node(root_id);
2181
2182 let user_id = root.as_map().unwrap().get_node_id(&"user".into()).unwrap();
2184 let user = doc.node(user_id);
2185 assert!(user.as_map().unwrap().get_node_id(&"name".into()).is_some());
2186
2187 let settings_id = root
2189 .as_map()
2190 .unwrap()
2191 .get_node_id(&"settings".into())
2192 .unwrap();
2193 let settings = doc.node(settings_id);
2194 assert!(
2195 settings
2196 .as_map()
2197 .unwrap()
2198 .get_node_id(&"theme".into())
2199 .is_some()
2200 );
2201 assert!(
2202 settings
2203 .as_map()
2204 .unwrap()
2205 .get_node_id(&"debug".into())
2206 .is_some()
2207 );
2208
2209 let logging_id = root
2211 .as_map()
2212 .unwrap()
2213 .get_node_id(&"logging".into())
2214 .unwrap();
2215 let logging = doc.node(logging_id);
2216 assert!(
2217 logging
2218 .as_map()
2219 .unwrap()
2220 .get_node_id(&"level".into())
2221 .is_some()
2222 );
2223 }
2224
2225 #[test]
2226 fn test_eure_section_in_section_block() {
2227 let doc = eure!({
2229 @ settings {
2230 theme = "dark"
2231 @ logging
2232 level = "info"
2233 }
2234 });
2235
2236 let settings = doc
2237 .parse_context(doc.get_root_id())
2238 .parse_record()
2239 .expect("Failed to parse record")
2240 .field_record("settings")
2241 .expect("Failed to parse settings");
2242 let theme = settings
2243 .parse_field::<&str>("theme")
2244 .expect("Failed to parse theme");
2245 let logging = settings
2246 .field_record("logging")
2247 .expect("Failed to parse logging")
2248 .parse_field::<&str>("level")
2249 .expect("Failed to parse level");
2250 settings
2251 .deny_unknown_fields()
2252 .expect("Failed to deny unknown fields");
2253 assert_eq!(theme, "dark");
2254 assert_eq!(logging, "info");
2255 }
2256
2257 #[test]
2258 fn test_eure_variable_text() {
2259 use crate::text::Text;
2261 let code = Text::inline_implicit("fn main() {}");
2262 let doc = eure!({ snippet = code });
2263
2264 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2265 let snippet_ctx = root.field("snippet").unwrap();
2266 let snippet_node = doc.node(snippet_ctx.node_id());
2267 let text = snippet_node.as_primitive().unwrap().as_text().unwrap();
2268 assert_eq!(text.as_str(), "fn main() {}");
2269 }
2270
2271 #[test]
2272 fn test_eure_variable_in_array() {
2273 use alloc::vec::Vec;
2275 let first = "one";
2276 let second = "two";
2277 let third = "three";
2278 let doc = eure!({ items = [first, second, third] });
2279
2280 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2281 let items = root.parse_field::<Vec<&str>>("items").unwrap();
2282 assert_eq!(items, vec!["one", "two", "three"]);
2283 }
2284
2285 #[test]
2286 fn test_eure_variable_in_tuple() {
2287 let x = 1.5;
2289 let y = 2.5;
2290 let doc = eure!({ point = (x, y) });
2291
2292 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2293 let point = root.parse_field::<(f64, f64)>("point").unwrap();
2294 assert_eq!(point, (1.5, 2.5));
2295 }
2296
2297 #[test]
2298 fn test_eure_variable_in_object_literal() {
2299 let x_val = 10.0;
2301 let y_val = 20.0;
2302 let doc = eure!({
2303 coords = {
2304 "x" => x_val
2305 "y" => y_val
2306 }
2307 });
2308
2309 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2310 let coords = root.field_record("coords").unwrap();
2311 let x = coords.parse_field::<f64>("x").unwrap();
2312 let y = coords.parse_field::<f64>("y").unwrap();
2313 assert_eq!(x, 10.0);
2314 assert_eq!(y, 20.0);
2315 }
2316
2317 #[test]
2318 #[allow(clippy::bool_assert_comparison)] fn test_eure_variable_mixed_with_literals() {
2320 let username = "bob";
2322 let is_active = true;
2323 let doc = eure!({
2324 user.name = username
2325 user.active = is_active
2326 user.role = "admin"
2327 user.level = 5
2328 });
2329
2330 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2331 let user = root.field_record("user").unwrap();
2332 assert_eq!(user.parse_field::<&str>("name").unwrap(), "bob");
2333 assert_eq!(user.parse_field::<bool>("active").unwrap(), true);
2334 assert_eq!(user.parse_field::<&str>("role").unwrap(), "admin");
2335 assert_eq!(user.parse_field::<i32>("level").unwrap(), 5);
2336 }
2337
2338 #[test]
2339 fn test_eure_variable_in_nested_array() {
2340 use alloc::vec::Vec;
2342 let tag1 = "rust";
2343 let tag2 = "macro";
2344 let doc = eure!({
2345 tags[] = tag1
2346 tags[] = tag2
2347 });
2348
2349 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2350 let tags = root.parse_field::<Vec<&str>>("tags").unwrap();
2351 assert_eq!(tags, vec!["rust", "macro"]);
2352 }
2353
2354 #[test]
2355 fn test_eure_variable_at_root() {
2356 let value = 42;
2358 let doc = eure!({
2359 = value
2360 });
2361
2362 let ctx = doc.parse_context(doc.get_root_id());
2363 let root_value = ctx.parse::<i32>().unwrap();
2364 assert_eq!(root_value, 42);
2365 }
2366
2367 #[test]
2368 fn test_eure_variable_in_section() {
2369 let theme_value = "dark";
2371 let lang_value = "en";
2372 let doc = eure!({
2373 @settings
2374 theme = theme_value
2375 language = lang_value
2376 });
2377
2378 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2379 let settings = root.field_record("settings").unwrap();
2380 assert_eq!(settings.parse_field::<&str>("theme").unwrap(), "dark");
2381 assert_eq!(settings.parse_field::<&str>("language").unwrap(), "en");
2382 }
2383
2384 #[test]
2385 fn test_eure_variable_null_and_primitive() {
2386 use crate::value::PrimitiveValue;
2388 let null_value = PrimitiveValue::Null;
2389 let doc = eure!({ optional = null_value });
2390
2391 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2392 let optional_ctx = root.field("optional").unwrap();
2393 let optional_node = doc.node(optional_ctx.node_id());
2394 assert!(matches!(
2395 optional_node.as_primitive().unwrap(),
2396 PrimitiveValue::Null
2397 ));
2398 }
2399
2400 #[test]
2405 fn test_eure_source_empty() {
2406 let source_doc = eure_source!({});
2407 assert_eq!(source_doc.document(), &EureDocument::new_empty());
2408 assert!(source_doc.root_source().bindings.is_empty());
2409 assert!(source_doc.root_source().sections.is_empty());
2410 }
2411
2412 #[test]
2413 fn test_eure_source_simple_bindings() {
2414 let source_doc = eure_source!({
2415 name = "Alice"
2416 age = 30
2417 });
2418
2419 let doc = source_doc.document();
2421 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2422 assert_eq!(root.parse_field::<&str>("name").unwrap(), "Alice");
2423 assert_eq!(root.parse_field::<i64>("age").unwrap(), 30);
2424
2425 let root_source = source_doc.root_source();
2427 assert_eq!(root_source.bindings.len(), 2);
2428 assert!(root_source.sections.is_empty());
2429 }
2430
2431 #[test]
2432 fn test_eure_source_nested() {
2433 use crate::source::BindSource;
2434
2435 let source_doc = eure_source!({
2436 user {
2437 name = "Bob"
2438 active = true
2439 }
2440 });
2441
2442 let doc = source_doc.document();
2443 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2444 let user = root.field_record("user").unwrap();
2445 assert_eq!(user.parse_field::<&str>("name").unwrap(), "Bob");
2446 assert!(user.parse_field::<bool>("active").unwrap());
2447
2448 let root_source = source_doc.root_source();
2450 assert_eq!(root_source.bindings.len(), 1);
2451 match &root_source.bindings[0].bind {
2452 BindSource::Block(source_id) => {
2453 let inner = source_doc.source(*source_id);
2454 assert_eq!(inner.bindings.len(), 2);
2455 }
2456 _ => panic!("Expected BindSource::Block"),
2457 }
2458 }
2459
2460 #[test]
2461 fn test_eure_generic_entry_point() {
2462 use crate::document::constructor::DocumentConstructor;
2464
2465 let mut c = DocumentConstructor::new();
2466 eure!(c; {
2467 x = 1
2468 y = 2
2469 });
2470 let doc = c.finish();
2471
2472 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2473 assert_eq!(root.parse_field::<i64>("x").unwrap(), 1);
2474 assert_eq!(root.parse_field::<i64>("y").unwrap(), 2);
2475 }
2476
2477 #[test]
2478 fn test_eure_source_generic_entry_point() {
2479 use crate::document::source_constructor::SourceConstructor;
2481
2482 let mut c = SourceConstructor::new();
2483 eure!(c; {
2484 message = "hello"
2485 });
2486 let source_doc = c.finish();
2487
2488 let doc = source_doc.document();
2489 let root = doc.parse_context(doc.get_root_id()).parse_record().unwrap();
2490 assert_eq!(root.parse_field::<&str>("message").unwrap(), "hello");
2491 }
2492}