1pub mod constructor;
2pub mod interpreter_sink;
3pub mod node;
4pub mod source_constructor;
5
6use crate::document::node::{NodeArray, NodeTuple};
7use crate::prelude_internal::*;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub struct NodeId(pub usize);
11
12#[derive(Debug, Clone)]
13pub struct EureDocument {
14 pub(crate) root: NodeId,
15 nodes: Vec<Node>,
16}
17
18#[derive(Debug, PartialEq, thiserror::Error, Clone)]
19#[error("Insert error: {kind} at {path}")]
20pub struct InsertError {
21 pub kind: InsertErrorKind,
22 pub path: EurePath,
23}
24
25#[derive(Debug, PartialEq, thiserror::Error, Clone)]
26pub enum InsertErrorKind {
27 #[error("Already assigned")]
28 AlreadyAssigned { key: ObjectKey },
29 #[error("Extension already assigned: {identifier}")]
30 AlreadyAssignedExtension { identifier: Identifier },
31 #[error("Expected array")]
32 ExpectedArray,
33 #[error("Array index invalid: expected {expected_index} but got {index}")]
34 ArrayIndexInvalid { index: usize, expected_index: usize },
35 #[error("Expected map")]
36 ExpectedMap,
37 #[error("Expected tuple")]
38 ExpectedTuple,
39 #[error("Tuple index invalid: expected {expected_index} but got {index}")]
40 TupleIndexInvalid { index: u8, expected_index: usize },
41 #[error("Binding target already has a value")]
42 BindingTargetHasValue,
43 #[error("Scope error: {0}")]
44 ScopeError(#[from] constructor::ScopeError),
45 #[error("Constructor error: {0}")]
46 ConstructorError(#[from] ConstructorError),
47}
48
49#[derive(Debug, PartialEq, thiserror::Error, Clone)]
51pub enum ConstructorError {
52 #[error("set_block_value called without a preceding bind operation")]
53 MissingBindBeforeSetBlockValue,
54 #[error("end_binding_value called without a preceding bind operation")]
55 MissingBindBeforeEndBindingValue,
56 #[error("end_binding_block called without a preceding end_eure_block")]
57 MissingEndEureBlockBeforeEndBindingBlock,
58 #[error("end_section_block called without a preceding end_eure_block")]
59 MissingEndEureBlockBeforeEndSectionBlock,
60 #[error("end_eure_block called but builder stack is not in EureBlock state")]
61 InvalidBuilderStackForEndEureBlock,
62 #[error("end_section_items called but builder stack is not in SectionItems state")]
63 InvalidBuilderStackForEndSectionItems,
64 #[error("ArrayIndex must follow a key segment; standalone [] is not valid")]
65 StandaloneArrayIndex,
66}
67
68impl Default for EureDocument {
69 fn default() -> Self {
70 Self::new()
71 }
72}
73
74impl PartialEq for EureDocument {
75 fn eq(&self, other: &Self) -> bool {
76 self.nodes_equal(self.root, other, other.root)
77 }
78}
79
80impl EureDocument {
81 fn nodes_equal(&self, id1: NodeId, other: &EureDocument, id2: NodeId) -> bool {
83 let node1 = &self.nodes[id1.0];
84 let node2 = &other.nodes[id2.0];
85
86 if node1.extensions.len() != node2.extensions.len() {
88 return false;
89 }
90
91 for (key1, &child_id1) in &node1.extensions {
92 match node2.extensions.get(key1) {
93 Some(&child_id2) => {
94 if !self.nodes_equal(child_id1, other, child_id2) {
95 return false;
96 }
97 }
98 None => return false,
99 }
100 }
101
102 self.node_values_equal(&node1.content, other, &node2.content)
104 }
105
106 fn node_values_equal(
108 &self,
109 value1: &NodeValue,
110 other: &EureDocument,
111 value2: &NodeValue,
112 ) -> bool {
113 match (value1, value2) {
114 (NodeValue::Hole(l1), NodeValue::Hole(l2)) => l1 == l2,
115 (NodeValue::Primitive(p1), NodeValue::Primitive(p2)) => p1 == p2,
116 (NodeValue::Array(arr1), NodeValue::Array(arr2)) => {
117 self.node_arrays_equal(arr1, other, arr2)
118 }
119 (NodeValue::Tuple(tup1), NodeValue::Tuple(tup2)) => {
120 self.node_tuples_equal(tup1, other, tup2)
121 }
122 (NodeValue::Map(map1), NodeValue::Map(map2)) => self.node_maps_equal(map1, other, map2),
123 _ => false,
124 }
125 }
126
127 fn node_arrays_equal(&self, arr1: &NodeArray, other: &EureDocument, arr2: &NodeArray) -> bool {
128 if arr1.len() != arr2.len() {
129 return false;
130 }
131
132 for (child_id1, child_id2) in arr1.iter().zip(arr2.iter()) {
133 if !self.nodes_equal(*child_id1, other, *child_id2) {
134 return false;
135 }
136 }
137
138 true
139 }
140
141 fn node_tuples_equal(&self, tup1: &NodeTuple, other: &EureDocument, tup2: &NodeTuple) -> bool {
142 if tup1.len() != tup2.len() {
143 return false;
144 }
145
146 for (child_id1, child_id2) in tup1.iter().zip(tup2.iter()) {
147 if !self.nodes_equal(*child_id1, other, *child_id2) {
148 return false;
149 }
150 }
151
152 true
153 }
154
155 fn node_maps_equal(&self, map1: &NodeMap, other: &EureDocument, map2: &NodeMap) -> bool {
156 if map1.len() != map2.len() {
157 return false;
158 }
159
160 for (key1, &child_id1) in map1.iter() {
161 match map2.get(key1) {
162 Some(&child_id2) => {
163 if !self.nodes_equal(child_id1, other, child_id2) {
164 return false;
165 }
166 }
167 None => return false,
168 }
169 }
170
171 true
172 }
173
174 pub fn new() -> Self {
175 Self {
176 root: NodeId(0),
177 nodes: vec![Node {
178 content: NodeValue::hole(),
179 extensions: Map::new(),
180 }],
181 }
182 }
183
184 pub fn new_empty() -> Self {
185 Self {
186 root: NodeId(0),
187 nodes: vec![Node {
188 content: NodeValue::Map(Default::default()),
189 extensions: Map::new(),
190 }],
191 }
192 }
193
194 pub fn new_primitive(value: PrimitiveValue) -> Self {
195 Self {
196 root: NodeId(0),
197 nodes: vec![Node {
198 content: NodeValue::Primitive(value),
199 extensions: Map::new(),
200 }],
201 }
202 }
203
204 pub fn root(&self) -> &Node {
205 &self.nodes[self.root.0]
206 }
207
208 pub fn get_root_id(&self) -> NodeId {
209 self.root
210 }
211
212 pub fn node(&self, id: NodeId) -> &Node {
213 &self.nodes[id.0]
214 }
215
216 pub fn get_node(&self, id: NodeId) -> Option<&Node> {
217 self.nodes.get(id.0)
218 }
219
220 pub fn node_mut(&mut self, id: NodeId) -> &mut Node {
221 &mut self.nodes[id.0]
222 }
223
224 pub fn get_node_mut(&mut self, id: NodeId) -> Option<&mut Node> {
225 self.nodes.get_mut(id.0)
226 }
227
228 pub fn create_node(&mut self, new: NodeValue) -> NodeId {
229 self.nodes.push(Node {
230 content: new,
231 extensions: Map::new(),
232 });
233 NodeId(self.nodes.len() - 1)
234 }
235
236 pub fn create_node_uninitialized(&mut self) -> NodeId {
237 self.create_node(NodeValue::hole())
238 }
239
240 pub fn set_content(&mut self, node_id: NodeId, content: NodeValue) {
242 self.nodes[node_id.0].content = content;
243 }
244
245 pub fn add_child_by_segment(
246 &mut self,
247 segment: PathSegment,
248 parent_node_id: NodeId,
249 ) -> Result<NodeMut<'_>, InsertErrorKind> {
250 match segment {
251 PathSegment::Ident(identifier) => {
252 self.add_map_child(ObjectKey::String(identifier.into_string()), parent_node_id)
253 }
254 PathSegment::Value(object_key) => self.add_map_child(object_key, parent_node_id),
255 PathSegment::Extension(identifier) => self.add_extension(identifier, parent_node_id),
256 PathSegment::TupleIndex(index) => self.add_tuple_element(index, parent_node_id),
257 PathSegment::ArrayIndex(index) => self.add_array_element(index, parent_node_id),
258 }
259 }
260
261 pub fn add_map_child(
262 &mut self,
263 object_key: ObjectKey,
264 parent_node_id: NodeId,
265 ) -> Result<NodeMut<'_>, InsertErrorKind> {
266 let node_id = self.create_node_uninitialized();
267 let node = self.node_mut(parent_node_id);
268 let map = node.require_map()?;
269 map.add(object_key, node_id)?;
270 Ok(NodeMut::new(self, node_id))
271 }
272
273 pub fn add_extension(
274 &mut self,
275 identifier: Identifier,
276 parent_node_id: NodeId,
277 ) -> Result<NodeMut<'_>, InsertErrorKind> {
278 let node_id = self.create_node_uninitialized();
279 let node = self.node_mut(parent_node_id);
280 if node.extensions.contains_key(&identifier) {
281 return Err(InsertErrorKind::AlreadyAssignedExtension { identifier });
282 }
283 node.extensions.insert(identifier, node_id);
284 Ok(NodeMut::new(self, node_id))
285 }
286
287 pub fn add_tuple_element(
288 &mut self,
289 index: u8,
290 parent_node_id: NodeId,
291 ) -> Result<NodeMut<'_>, InsertErrorKind> {
292 let node_id = self.create_node_uninitialized();
293 let node = self.node_mut(parent_node_id);
294 let tuple = node.require_tuple()?;
295 tuple.add_at(index, node_id)?;
296 Ok(NodeMut::new(self, node_id))
297 }
298
299 pub fn add_array_element(
300 &mut self,
301 index: Option<usize>,
302 parent_node_id: NodeId,
303 ) -> Result<NodeMut<'_>, InsertErrorKind> {
304 let node_id = self.create_node_uninitialized();
305 let node = self.node_mut(parent_node_id);
306 let array = node.require_array()?;
307 if let Some(index) = index {
308 array.add_at(index, node_id)?;
309 } else {
310 array.push(node_id)?;
311 }
312 Ok(NodeMut::new(self, node_id))
313 }
314
315 pub fn resolve_child_by_segment(
320 &mut self,
321 segment: PathSegment,
322 parent_node_id: NodeId,
323 ) -> Result<NodeMut<'_>, InsertErrorKind> {
324 let node = self.node(parent_node_id);
326
327 let existing = match &segment {
328 PathSegment::Ident(identifier) => node
329 .as_map()
330 .and_then(|m| m.get(&ObjectKey::String(identifier.clone().into_string())))
331 .copied(),
332 PathSegment::Value(object_key) => {
333 node.as_map().and_then(|m| m.get(object_key)).copied()
334 }
335 PathSegment::Extension(identifier) => node.get_extension(identifier),
336 PathSegment::TupleIndex(index) => node.as_tuple().and_then(|t| t.get(*index as usize)),
337 PathSegment::ArrayIndex(Some(index)) => node.as_array().and_then(|a| a.get(*index)),
338 PathSegment::ArrayIndex(None) => None, };
340
341 if let Some(node_id) = existing {
343 return Ok(NodeMut::new(self, node_id));
344 }
345
346 self.add_child_by_segment(segment, parent_node_id)
348 }
349
350 pub fn node_subtree_to_document(&self, node_id: NodeId) -> EureDocument {
352 let mut result = EureDocument::new();
353 let root_id = result.get_root_id();
354 self.copy_subtree(node_id, &mut result, root_id);
355 result
356 }
357
358 pub fn copy_subtree(&self, src_id: NodeId, dst: &mut EureDocument, dst_id: NodeId) {
359 let src_node = self.node(src_id);
360 dst.node_mut(dst_id).content = src_node.content.clone();
361
362 match &src_node.content {
369 NodeValue::Array(arr) => {
370 for &child_src_id in arr.iter() {
371 if let Ok(result) = dst.add_array_element(None, dst_id) {
372 let child_dst_id = result.node_id;
373 self.copy_subtree(child_src_id, dst, child_dst_id);
374 }
375 }
376 }
377 NodeValue::Tuple(tuple) => {
378 for (idx, &child_src_id) in tuple.iter().enumerate() {
379 if let Ok(result) = dst.add_tuple_element(idx as u8, dst_id) {
380 let child_dst_id = result.node_id;
381 self.copy_subtree(child_src_id, dst, child_dst_id);
382 }
383 }
384 }
385 NodeValue::Map(map) => {
386 for (key, &child_src_id) in map.iter() {
387 if let Ok(result) = dst.add_map_child(key.clone(), dst_id) {
388 let child_dst_id = result.node_id;
389 self.copy_subtree(child_src_id, dst, child_dst_id);
390 }
391 }
392 }
393 _ => {}
394 }
395 }
396}
397
398impl EureDocument {
400 pub fn replace_with_primitive(&mut self, value: PrimitiveValue) -> Result<(), InsertErrorKind> {
401 self.nodes.clear();
402 self.nodes[self.root.0].content = NodeValue::Primitive(value);
403 Ok(())
404 }
405
406 pub fn reset_as_map(&mut self) -> Result<(), InsertErrorKind> {
407 self.nodes.clear();
408 self.nodes[self.root.0].content = NodeValue::Map(Default::default());
409 Ok(())
410 }
411}
412
413#[cfg(test)]
414mod tests {
415 use super::*;
416
417 fn identifier(s: &str) -> Identifier {
418 s.parse().unwrap()
419 }
420
421 #[test]
422 fn test_add_map_child_success() {
423 let mut doc = EureDocument::new();
424 let map_id = {
425 let doc: &mut EureDocument = &mut doc;
426 doc.create_node(NodeValue::empty_map())
427 };
428 let key = ObjectKey::String("test_key".to_string());
429
430 let child_id = doc
431 .add_map_child(key.clone(), map_id)
432 .expect("Failed to add map child")
433 .node_id;
434
435 let map = doc.node(map_id).as_map().expect("Expected map");
436 assert_eq!(map.get(&key), Some(&child_id));
437 }
438
439 #[test]
440 fn test_add_map_child_error_expected_map() {
441 let mut doc = EureDocument::new();
442 let primitive_id = {
443 let doc: &mut EureDocument = &mut doc;
444 doc.create_node(NodeValue::Primitive(PrimitiveValue::Null))
445 };
446 let key = ObjectKey::String("test".to_string());
447
448 let result = doc.add_map_child(key, primitive_id);
449 assert_eq!(result.err(), Some(InsertErrorKind::ExpectedMap));
450 }
451
452 #[test]
453 fn test_add_map_child_error_already_assigned() {
454 let mut doc = EureDocument::new();
455 let root_id = doc.get_root_id();
456 let key = ObjectKey::String("test".to_string());
457
458 let _result1 = doc
459 .add_map_child(key.clone(), root_id)
460 .expect("First add should succeed");
461
462 let result2 = doc.add_map_child(key.clone(), root_id);
463 assert_eq!(
464 result2.err(),
465 Some(InsertErrorKind::AlreadyAssigned { key })
466 );
467 }
468
469 #[test]
470 fn test_add_extension_success_multiple() {
471 let mut doc = EureDocument::new();
472 let root_id = doc.get_root_id();
473 let id1 = identifier("ext1");
474 let id2 = identifier("ext2");
475
476 let node_id1 = doc
477 .add_extension(id1.clone(), root_id)
478 .expect("Failed to add extension")
479 .node_id;
480
481 let node_id2 = doc
482 .add_extension(id2.clone(), root_id)
483 .expect("Failed to add extension")
484 .node_id;
485
486 let node = doc.node(root_id);
487 assert_eq!(node.extensions.get(&id1), Some(&node_id1));
488 assert_eq!(node.extensions.get(&id2), Some(&node_id2));
489 }
490
491 #[test]
492 fn test_add_extension_success() {
493 let mut doc = EureDocument::new();
494 let primitive_id = {
495 let doc: &mut EureDocument = &mut doc;
496 doc.create_node(NodeValue::Primitive(PrimitiveValue::Null))
497 };
498 let identifier = identifier("ext");
499
500 let node_id = doc
501 .add_extension(identifier.clone(), primitive_id)
502 .expect("Failed to add extension")
503 .node_id;
504
505 let node = doc.node(primitive_id);
506 assert_eq!(node.extensions.get(&identifier), Some(&node_id));
507 }
508
509 #[test]
510 fn test_add_extension_error_already_assigned() {
511 let mut doc = EureDocument::new();
512 let map_id = {
513 let doc: &mut EureDocument = &mut doc;
514 doc.create_node(NodeValue::empty_map())
515 };
516 let identifier = identifier("ext");
517
518 let _result1 = doc
519 .add_extension(identifier.clone(), map_id)
520 .expect("First add should succeed");
521
522 let result2 = doc.add_extension(identifier.clone(), map_id);
523 assert_eq!(
524 result2.err(),
525 Some(InsertErrorKind::AlreadyAssignedExtension { identifier })
526 );
527 }
528
529 #[test]
530 fn test_add_tuple_element_success_index_0() {
531 let mut doc = EureDocument::new();
532 let tuple_id = {
533 let doc: &mut EureDocument = &mut doc;
534 doc.create_node(NodeValue::empty_tuple())
535 };
536
537 let node_id = doc
538 .add_tuple_element(0, tuple_id)
539 .expect("Failed to add tuple element")
540 .node_id;
541
542 let tuple = doc.node(tuple_id).as_tuple().expect("Expected tuple");
543 assert_eq!(tuple.to_vec(), vec![node_id]);
544 }
545
546 #[test]
547 fn test_add_tuple_element_success_sequential() {
548 let mut doc = EureDocument::new();
549 let tuple_id = {
550 let doc: &mut EureDocument = &mut doc;
551 doc.create_node(NodeValue::empty_tuple())
552 };
553
554 let node_id1 = doc
555 .add_tuple_element(0, tuple_id)
556 .expect("Failed to add tuple element")
557 .node_id;
558
559 let node_id2 = doc
560 .add_tuple_element(1, tuple_id)
561 .expect("Failed to add tuple element")
562 .node_id;
563
564 let tuple = doc.node(tuple_id).as_tuple().expect("Expected tuple");
565 assert_eq!(tuple.to_vec(), vec![node_id1, node_id2]);
566 }
567
568 #[test]
569 fn test_add_tuple_element_error_expected_tuple() {
570 let mut doc = EureDocument::new();
571 let map_id = {
572 let doc: &mut EureDocument = &mut doc;
573 doc.create_node(NodeValue::empty_map())
574 };
575
576 let result = doc.add_tuple_element(0, map_id);
577 assert_eq!(result.err(), Some(InsertErrorKind::ExpectedTuple));
578 }
579
580 #[test]
581 fn test_add_tuple_element_error_invalid_index() {
582 let mut doc = EureDocument::new();
583 let tuple_id = {
584 let doc: &mut EureDocument = &mut doc;
585 doc.create_node(NodeValue::empty_tuple())
586 };
587
588 let result = doc.add_tuple_element(1, tuple_id);
589 assert_eq!(
590 result.err(),
591 Some(InsertErrorKind::TupleIndexInvalid {
592 index: 1,
593 expected_index: 0
594 })
595 );
596 }
597
598 #[test]
599 fn test_add_array_element_success_push() {
600 let mut doc = EureDocument::new();
601 let array_id = {
602 let doc: &mut EureDocument = &mut doc;
603 doc.create_node(NodeValue::empty_array())
604 };
605
606 let node_id = doc
607 .add_array_element(None, array_id)
608 .expect("Failed to add array element")
609 .node_id;
610
611 let array = doc.node(array_id).as_array().expect("Expected array");
612 assert_eq!(array.to_vec(), vec![node_id]);
613 }
614
615 #[test]
616 fn test_add_array_element_success_at_index() {
617 let mut doc = EureDocument::new();
618 let array_id = {
619 let doc: &mut EureDocument = &mut doc;
620 doc.create_node(NodeValue::empty_array())
621 };
622
623 let node_id1 = doc
624 .add_array_element(Some(0), array_id)
625 .expect("Failed to add array element")
626 .node_id;
627
628 let node_id2 = doc
629 .add_array_element(Some(1), array_id)
630 .expect("Failed to add array element")
631 .node_id;
632
633 let array = doc.node(array_id).as_array().expect("Expected array");
634 assert_eq!(array.to_vec(), vec![node_id1, node_id2]);
635 }
636
637 #[test]
638 fn test_add_array_element_error_expected_array() {
639 let mut doc = EureDocument::new();
640 let map_id = {
641 let doc: &mut EureDocument = &mut doc;
642 doc.create_node(NodeValue::empty_map())
643 };
644
645 let result = doc.add_array_element(None, map_id);
646 assert_eq!(result.err(), Some(InsertErrorKind::ExpectedArray));
647 }
648
649 #[test]
650 fn test_add_array_element_error_invalid_index() {
651 let mut doc = EureDocument::new();
652 let array_id = {
653 let doc: &mut EureDocument = &mut doc;
654 doc.create_node(NodeValue::empty_array())
655 };
656
657 let result = doc.add_array_element(Some(1), array_id);
658 assert_eq!(
659 result.err(),
660 Some(InsertErrorKind::ArrayIndexInvalid {
661 index: 1,
662 expected_index: 0
663 })
664 );
665 }
666
667 #[test]
668 fn test_add_child_by_segment_ident() {
669 let mut doc = EureDocument::new();
670 let root_id = doc.get_root_id();
671 let identifier = identifier("test");
672 let segment = PathSegment::Ident(identifier.clone());
673
674 let result = doc.add_child_by_segment(segment, root_id);
675 assert!(result.is_ok());
676
677 let map = doc.node(root_id).as_map().expect("Expected map");
678 let key = ObjectKey::String(identifier.into_string());
679 assert!(map.get(&key).is_some());
680 }
681
682 #[test]
683 fn test_add_child_by_segment_value() {
684 let mut doc = EureDocument::new();
685 let root_id = doc.get_root_id();
686 let key = ObjectKey::String("test".to_string());
687 let segment = PathSegment::Value(key.clone());
688
689 let result = doc.add_child_by_segment(segment, root_id);
690 assert!(result.is_ok());
691
692 let map = doc.node(root_id).as_map().expect("Expected map");
693 assert!(map.get(&key).is_some());
694 }
695
696 #[test]
697 fn test_add_child_by_segment_extension() {
698 let mut doc = EureDocument::new();
699 let root_id = doc.get_root_id();
700 let identifier = identifier("ext");
701 let segment = PathSegment::Extension(identifier.clone());
702
703 let result = doc.add_child_by_segment(segment, root_id);
704 assert!(result.is_ok());
705
706 let node = doc.node(root_id);
707 assert!(node.extensions.contains_key(&identifier));
708 }
709
710 #[test]
711 fn test_add_child_by_segment_tuple_index() {
712 let mut doc = EureDocument::new();
713 let tuple_id = {
714 let doc: &mut EureDocument = &mut doc;
715 doc.create_node(NodeValue::empty_tuple())
716 };
717 let segment = PathSegment::TupleIndex(0);
718
719 let result = doc.add_child_by_segment(segment, tuple_id);
720 assert!(result.is_ok());
721
722 let tuple = doc.node(tuple_id).as_tuple().expect("Expected tuple");
723 assert_eq!(tuple.len(), 1);
724 }
725
726 #[test]
727 fn test_add_child_by_segment_array_index_none() {
728 let mut doc = EureDocument::new();
729 let array_id = {
730 let doc: &mut EureDocument = &mut doc;
731 doc.create_node(NodeValue::empty_array())
732 };
733 let segment = PathSegment::ArrayIndex(None);
734
735 let result = doc.add_child_by_segment(segment, array_id);
736 assert!(result.is_ok());
737
738 let array = doc.node(array_id).as_array().expect("Expected array");
739 assert_eq!(array.len(), 1);
740 }
741
742 #[test]
743 fn test_add_child_by_segment_array_index_some() {
744 let mut doc = EureDocument::new();
745 let array_id = {
746 let doc: &mut EureDocument = &mut doc;
747 doc.create_node(NodeValue::empty_array())
748 };
749 let segment = PathSegment::ArrayIndex(Some(0));
750
751 let result = doc.add_child_by_segment(segment, array_id);
752 assert!(result.is_ok());
753
754 let array = doc.node(array_id).as_array().expect("Expected array");
755 assert_eq!(array.len(), 1);
756 }
757
758 #[test]
759 fn test_resolve_ident_idempotent() {
760 let mut doc = EureDocument::new();
761 let root_id = doc.get_root_id();
762 let identifier = identifier("field");
763
764 let node_id1 = doc
766 .resolve_child_by_segment(PathSegment::Ident(identifier.clone()), root_id)
767 .expect("First call failed")
768 .node_id;
769
770 let node_id2 = doc
772 .resolve_child_by_segment(PathSegment::Ident(identifier), root_id)
773 .expect("Second call failed")
774 .node_id;
775
776 assert_eq!(node_id1, node_id2);
777 }
778
779 #[test]
780 fn test_resolve_value_idempotent() {
781 let mut doc = EureDocument::new();
782 let root_id = doc.get_root_id();
783 let object_key = ObjectKey::String("key".to_string());
784
785 let node_id1 = doc
787 .resolve_child_by_segment(PathSegment::Value(object_key.clone()), root_id)
788 .expect("First call failed")
789 .node_id;
790
791 let node_id2 = doc
793 .resolve_child_by_segment(PathSegment::Value(object_key), root_id)
794 .expect("Second call failed")
795 .node_id;
796
797 assert_eq!(node_id1, node_id2);
798 }
799
800 #[test]
801 fn test_resolve_extension_idempotent() {
802 let mut doc = EureDocument::new();
803 let root_id = doc.get_root_id();
804 let identifier = identifier("ext");
805
806 let node_id1 = doc
808 .resolve_child_by_segment(PathSegment::Extension(identifier.clone()), root_id)
809 .expect("First call failed")
810 .node_id;
811
812 let node_id2 = doc
814 .resolve_child_by_segment(PathSegment::Extension(identifier), root_id)
815 .expect("Second call failed")
816 .node_id;
817
818 assert_eq!(node_id1, node_id2);
819 }
820
821 #[test]
822 fn test_resolve_tuple_index_idempotent() {
823 let mut doc = EureDocument::new();
824 let parent_id = doc.create_node_uninitialized();
825
826 let node_id1 = doc
828 .resolve_child_by_segment(PathSegment::TupleIndex(0), parent_id)
829 .expect("First call failed")
830 .node_id;
831
832 let node_id2 = doc
834 .resolve_child_by_segment(PathSegment::TupleIndex(0), parent_id)
835 .expect("Second call failed")
836 .node_id;
837
838 assert_eq!(node_id1, node_id2);
839 }
840
841 #[test]
842 fn test_resolve_array_index_some_idempotent() {
843 let mut doc = EureDocument::new();
844 let parent_id = doc.create_node_uninitialized();
845
846 let node_id1 = doc
848 .resolve_child_by_segment(PathSegment::ArrayIndex(Some(0)), parent_id)
849 .expect("First call failed")
850 .node_id;
851
852 let node_id2 = doc
854 .resolve_child_by_segment(PathSegment::ArrayIndex(Some(0)), parent_id)
855 .expect("Second call failed")
856 .node_id;
857
858 assert_eq!(node_id1, node_id2);
859 }
860
861 #[test]
862 fn test_resolve_array_index_none_always_creates_new() {
863 let mut doc = EureDocument::new();
864 let parent_id = doc.create_node_uninitialized();
865
866 let node_id1 = doc
868 .resolve_child_by_segment(PathSegment::ArrayIndex(None), parent_id)
869 .expect("First call failed")
870 .node_id;
871
872 let node_id2 = doc
874 .resolve_child_by_segment(PathSegment::ArrayIndex(None), parent_id)
875 .expect("Second call failed")
876 .node_id;
877
878 assert_ne!(node_id1, node_id2);
880
881 let array = doc.node(parent_id).as_array().expect("Expected array");
883 assert_eq!(array.len(), 2);
884 assert_eq!(array.get(0).unwrap(), node_id1);
885 assert_eq!(array.get(1).unwrap(), node_id2);
886 }
887
888 #[test]
889 fn test_get_node_with_valid_id() {
890 let mut doc = EureDocument::new();
891 let node_id = doc.create_node(NodeValue::Primitive(PrimitiveValue::Null));
892
893 let result = doc.get_node(node_id);
894 assert!(result.is_some());
895
896 let node = result.unwrap();
897 assert_eq!(node.content, NodeValue::Primitive(PrimitiveValue::Null));
898 }
899
900 #[test]
901 fn test_get_node_with_invalid_id() {
902 let doc = EureDocument::new();
903 let invalid_id = NodeId(9999);
905
906 let result = doc.get_node(invalid_id);
907 assert!(result.is_none());
908 }
909
910 #[test]
911 fn test_get_node_mut_with_valid_id() {
912 let mut doc = EureDocument::new();
913 let node_id = doc.create_node(NodeValue::Primitive(PrimitiveValue::Null));
914
915 let result = doc.get_node_mut(node_id);
916 assert!(result.is_some());
917
918 let node = result.unwrap();
920 node.content = NodeValue::Primitive(PrimitiveValue::Bool(true));
921
922 assert_eq!(
924 doc.node(node_id).content,
925 NodeValue::Primitive(PrimitiveValue::Bool(true))
926 );
927 }
928
929 #[test]
930 fn test_get_node_mut_with_invalid_id() {
931 let mut doc = EureDocument::new();
932 let invalid_id = NodeId(9999);
934
935 let result = doc.get_node_mut(invalid_id);
936 assert!(result.is_none());
937 }
938
939 #[test]
940 fn test_partialeq_empty_documents() {
941 let doc1 = EureDocument::new();
942 let doc2 = EureDocument::new();
943 assert_eq!(doc1, doc2);
944 }
945
946 #[test]
947 fn test_partialeq_primitive_documents() {
948 let doc1 = EureDocument::new_primitive(PrimitiveValue::Bool(true));
949 let doc2 = EureDocument::new_primitive(PrimitiveValue::Bool(true));
950 let doc3 = EureDocument::new_primitive(PrimitiveValue::Bool(false));
951
952 assert_eq!(doc1, doc2);
953 assert_ne!(doc1, doc3);
954 }
955
956 #[test]
957 fn test_partialeq_with_map_children() {
958 let mut doc1 = EureDocument::new();
959 let mut doc2 = EureDocument::new();
960
961 let root1 = doc1.get_root_id();
962 let root2 = doc2.get_root_id();
963
964 let key = ObjectKey::String("test".to_string());
965
966 doc1.add_map_child(key.clone(), root1)
967 .expect("Failed to add child");
968 doc2.add_map_child(key.clone(), root2)
969 .expect("Failed to add child");
970
971 assert_eq!(doc1, doc2);
972 }
973
974 #[test]
975 fn test_partialeq_with_different_map_children() {
976 let mut doc1 = EureDocument::new();
977 let mut doc2 = EureDocument::new();
978
979 let root1 = doc1.get_root_id();
980 let root2 = doc2.get_root_id();
981
982 doc1.add_map_child(ObjectKey::String("key1".to_string()), root1)
983 .expect("Failed to add child");
984 doc2.add_map_child(ObjectKey::String("key2".to_string()), root2)
985 .expect("Failed to add child");
986
987 assert_ne!(doc1, doc2);
988 }
989
990 #[test]
991 fn test_partialeq_with_extensions() {
992 let mut doc1 = EureDocument::new();
993 let mut doc2 = EureDocument::new();
994
995 let root1 = doc1.get_root_id();
996 let root2 = doc2.get_root_id();
997
998 let ext_id = identifier("ext");
999
1000 doc1.add_extension(ext_id.clone(), root1)
1001 .expect("Failed to add extension");
1002 doc2.add_extension(ext_id.clone(), root2)
1003 .expect("Failed to add extension");
1004
1005 assert_eq!(doc1, doc2);
1006 }
1007
1008 #[test]
1009 fn test_partialeq_with_different_extensions() {
1010 let mut doc1 = EureDocument::new();
1011 let mut doc2 = EureDocument::new();
1012
1013 let root1 = doc1.get_root_id();
1014 let root2 = doc2.get_root_id();
1015
1016 doc1.add_extension(identifier("ext1"), root1)
1017 .expect("Failed to add extension");
1018 doc2.add_extension(identifier("ext2"), root2)
1019 .expect("Failed to add extension");
1020
1021 assert_ne!(doc1, doc2);
1022 }
1023
1024 #[test]
1025 fn test_partialeq_with_arrays() {
1026 let mut doc1 = EureDocument::new();
1027 let mut doc2 = EureDocument::new();
1028
1029 let array_id1 = doc1.create_node(NodeValue::empty_array());
1031 doc1.add_array_element(None, array_id1)
1032 .expect("Failed to add array element");
1033 doc1.root = array_id1;
1034
1035 let array_id2 = doc2.create_node(NodeValue::empty_array());
1037 doc2.add_array_element(None, array_id2)
1038 .expect("Failed to add array element");
1039 doc2.root = array_id2;
1040
1041 assert_eq!(doc1, doc2);
1042 }
1043
1044 #[test]
1045 fn test_partialeq_with_tuples() {
1046 let mut doc1 = EureDocument::new();
1047 let mut doc2 = EureDocument::new();
1048
1049 let tuple_id1 = doc1.create_node(NodeValue::empty_tuple());
1051 doc1.add_tuple_element(0, tuple_id1)
1052 .expect("Failed to add tuple element");
1053 doc1.root = tuple_id1;
1054
1055 let tuple_id2 = doc2.create_node(NodeValue::empty_tuple());
1057 doc2.add_tuple_element(0, tuple_id2)
1058 .expect("Failed to add tuple element");
1059 doc2.root = tuple_id2;
1060
1061 assert_eq!(doc1, doc2);
1062 }
1063
1064 #[test]
1065 fn test_partialeq_nested_structure() {
1066 let mut doc1 = EureDocument::new();
1067 let mut doc2 = EureDocument::new();
1068
1069 let root1 = doc1.get_root_id();
1071 let child1 = doc1
1072 .add_map_child(ObjectKey::String("child".to_string()), root1)
1073 .expect("Failed to add child")
1074 .node_id;
1075 doc1.node_mut(child1).content = NodeValue::Primitive(PrimitiveValue::Bool(true));
1076
1077 let root2 = doc2.get_root_id();
1079 let child2 = doc2
1080 .add_map_child(ObjectKey::String("child".to_string()), root2)
1081 .expect("Failed to add child")
1082 .node_id;
1083 doc2.node_mut(child2).content = NodeValue::Primitive(PrimitiveValue::Bool(true));
1084
1085 assert_eq!(doc1, doc2);
1086 }
1087
1088 #[test]
1089 fn test_partialeq_ignores_node_id_values() {
1090 let mut doc1 = EureDocument::new();
1091 let mut doc2 = EureDocument::new();
1092
1093 let root1 = doc1.get_root_id();
1095 let _intermediate = doc1.create_node(NodeValue::Primitive(PrimitiveValue::Null));
1096 let child1 = doc1
1097 .add_map_child(ObjectKey::String("key".to_string()), root1)
1098 .expect("Failed")
1099 .node_id;
1100
1101 let root2 = doc2.get_root_id();
1103 let child2 = doc2
1104 .add_map_child(ObjectKey::String("key".to_string()), root2)
1105 .expect("Failed")
1106 .node_id;
1107
1108 assert_eq!(doc1, doc2);
1111
1112 assert_ne!(child1.0, child2.0);
1114 }
1115}