eure_document/
document.rs

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