1use crate::{prelude_internal::*, value::ValueKind};
2
3#[derive(Debug, Clone)]
4pub struct Node {
8 pub content: NodeValue,
9 pub extensions: Map<Identifier, NodeId>,
10}
11
12pub struct NodeMut<'d> {
13 document: &'d mut EureDocument,
14 pub node_id: NodeId,
15}
16
17impl<'d> core::fmt::Debug for NodeMut<'d> {
18 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19 match self.document.get_node(self.node_id) {
20 Some(node) => f
21 .debug_tuple("NodeMut")
22 .field(&self.node_id)
23 .field(node)
24 .finish(),
25 None => f
26 .debug_tuple("NodeMut")
27 .field(&self.node_id)
28 .field(&"<invalid>")
29 .finish(),
30 }
31 }
32}
33
34impl<'d> NodeMut<'d> {
35 pub fn new(document: &'d mut EureDocument, node_id: NodeId) -> Self {
36 Self { document, node_id }
37 }
38
39 pub fn add_map_child(self, object_key: ObjectKey) -> Result<NodeMut<'d>, InsertErrorKind> {
40 self.document.add_map_child(object_key, self.node_id)
41 }
42
43 pub fn add_extension(self, identifier: Identifier) -> Result<NodeMut<'d>, InsertErrorKind> {
44 self.document.add_extension(identifier, self.node_id)
45 }
46
47 pub fn add_tuple_element(self, index: u8) -> Result<NodeMut<'d>, InsertErrorKind> {
48 self.document.add_tuple_element(index, self.node_id)
49 }
50
51 pub fn add_array_element(self, index: Option<usize>) -> Result<NodeMut<'d>, InsertErrorKind> {
52 self.document.add_array_element(index, self.node_id)
53 }
54
55 pub fn add_child_by_segment(
56 self,
57 segment: PathSegment,
58 ) -> Result<NodeMut<'d>, InsertErrorKind> {
59 self.document.add_child_by_segment(segment, self.node_id)
60 }
61
62 pub fn get_extension(self, ident: &Identifier) -> Option<NodeMut<'d>> {
63 let node_id = self.document.node(self.node_id).extensions.get(ident)?;
64 Some(NodeMut::new(self.document, *node_id))
65 }
66
67 pub fn as_map(self) -> Option<&'d NodeMap> {
70 self.document.node(self.node_id).as_map()
71 }
72
73 pub fn as_array(self) -> Option<&'d NodeArray> {
74 self.document.node(self.node_id).as_array()
75 }
76
77 pub fn as_tuple(self) -> Option<&'d NodeTuple> {
78 self.document.node(self.node_id).as_tuple()
79 }
80
81 pub fn require_map(self) -> Result<&'d mut NodeMap, InsertErrorKind> {
82 self.document.node_mut(self.node_id).require_map()
83 }
84
85 pub fn require_tuple(self) -> Result<&'d mut NodeTuple, InsertErrorKind> {
86 self.document.node_mut(self.node_id).require_tuple()
87 }
88
89 pub fn require_array(self) -> Result<&'d mut NodeArray, InsertErrorKind> {
90 self.document.node_mut(self.node_id).require_array()
91 }
92}
93
94impl Node {
95 pub fn as_map(&self) -> Option<&NodeMap> {
96 match &self.content {
97 NodeValue::Map(map) => Some(map),
98 _ => None,
99 }
100 }
101
102 pub fn as_array(&self) -> Option<&NodeArray> {
103 match &self.content {
104 NodeValue::Array(array) => Some(array),
105 _ => None,
106 }
107 }
108
109 pub fn as_tuple(&self) -> Option<&NodeTuple> {
110 match &self.content {
111 NodeValue::Tuple(tuple) => Some(tuple),
112 _ => None,
113 }
114 }
115
116 pub fn as_primitive(&self) -> Option<&PrimitiveValue> {
117 match &self.content {
118 NodeValue::Primitive(primitive) => Some(primitive),
119 _ => None,
120 }
121 }
122
123 pub fn get_extension(&self, ident: &Identifier) -> Option<NodeId> {
124 self.extensions.get(ident).copied()
125 }
126
127 pub(crate) fn require_map(&mut self) -> Result<&mut NodeMap, InsertErrorKind> {
128 if self.content.is_hole() {
129 self.content = NodeValue::Map(Default::default());
130 let NodeValue::Map(map) = &mut self.content else {
131 unreachable!();
132 };
133 Ok(map)
134 } else if let NodeValue::Map(map) = &mut self.content {
135 Ok(map)
136 } else {
137 Err(InsertErrorKind::ExpectedMap)
138 }
139 }
140
141 pub(crate) fn require_tuple(&mut self) -> Result<&mut NodeTuple, InsertErrorKind> {
142 if self.content.is_hole() {
143 self.content = NodeValue::Tuple(Default::default());
144 let NodeValue::Tuple(tuple) = &mut self.content else {
145 unreachable!();
146 };
147 Ok(tuple)
148 } else if let NodeValue::Tuple(tuple) = &mut self.content {
149 Ok(tuple)
150 } else {
151 Err(InsertErrorKind::ExpectedTuple)
152 }
153 }
154
155 pub(crate) fn require_array(&mut self) -> Result<&mut NodeArray, InsertErrorKind> {
156 if self.content.is_hole() {
157 self.content = NodeValue::Array(Default::default());
158 let NodeValue::Array(array) = &mut self.content else {
159 unreachable!();
160 };
161 Ok(array)
162 } else if let NodeValue::Array(array) = &mut self.content {
163 Ok(array)
164 } else {
165 Err(InsertErrorKind::ExpectedArray)
166 }
167 }
168}
169
170#[derive(Debug, PartialEq, Clone)]
171pub enum NodeValue {
172 Hole(Option<Identifier>),
175 Primitive(PrimitiveValue),
176 Array(NodeArray),
177 Map(NodeMap),
178 Tuple(NodeTuple),
179}
180
181impl NodeValue {
182 pub fn hole() -> Self {
184 Self::Hole(None)
185 }
186
187 pub fn labeled_hole(label: Identifier) -> Self {
189 Self::Hole(Some(label))
190 }
191
192 pub fn is_hole(&self) -> bool {
194 matches!(self, Self::Hole(_))
195 }
196
197 pub fn empty_map() -> Self {
198 Self::Map(NodeMap::new())
199 }
200
201 pub fn empty_array() -> Self {
202 Self::Array(NodeArray::new())
203 }
204
205 pub fn empty_tuple() -> Self {
206 Self::Tuple(NodeTuple::new())
207 }
208
209 pub fn value_kind(&self) -> Option<ValueKind> {
210 match self {
211 Self::Hole(_) => None,
212 Self::Primitive(primitive) => Some(primitive.kind()),
213 Self::Array(_) => Some(ValueKind::Array),
214 Self::Map(_) => Some(ValueKind::Map),
215 Self::Tuple(_) => Some(ValueKind::Tuple),
216 }
217 }
218}
219
220impl From<PrimitiveValue> for NodeValue {
225 fn from(p: PrimitiveValue) -> Self {
226 NodeValue::Primitive(p)
227 }
228}
229
230#[derive(Debug, Default, Clone, PartialEq, Eq, Plural)]
232pub struct NodeArray(pub Vec<NodeId>);
233
234#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Plural)]
236pub struct NodeTuple(pub Vec<NodeId>);
237
238pub type NodeMap = Map<ObjectKey, NodeId>;
239
240impl NodeTuple {
241 pub fn get(&self, index: usize) -> Option<NodeId> {
242 self.0.get(index).copied()
243 }
244
245 pub fn push(&mut self, node_id: NodeId) -> Result<(), InsertErrorKind> {
246 self.0.push(node_id);
247 Ok(())
248 }
249
250 pub fn add_at(&mut self, index: u8, node_id: NodeId) -> Result<(), InsertErrorKind> {
251 if index as usize != self.0.len() {
252 return Err(InsertErrorKind::TupleIndexInvalid {
253 index,
254 expected_index: self.0.len(),
255 });
256 }
257 self.0.insert(index as usize, node_id);
258 Ok(())
259 }
260}
261
262impl NodeArray {
263 pub fn get(&self, index: usize) -> Option<NodeId> {
264 self.0.get(index).copied()
265 }
266
267 pub fn push(&mut self, node_id: NodeId) -> Result<(), InsertErrorKind> {
268 self.0.push(node_id);
269 Ok(())
270 }
271
272 pub fn add_at(&mut self, index: usize, node_id: NodeId) -> Result<(), InsertErrorKind> {
273 if index != self.0.len() {
274 return Err(InsertErrorKind::ArrayIndexInvalid {
275 index,
276 expected_index: self.0.len(),
277 });
278 }
279 self.0.insert(index, node_id);
280 Ok(())
281 }
282}
283
284#[cfg(test)]
285mod tests {
286 use super::*;
287
288 fn identifier(s: &str) -> Identifier {
289 s.parse().unwrap()
290 }
291
292 #[test]
293 fn test_require_map_on_uninitialized() {
294 let mut node = Node {
295 content: NodeValue::hole(),
296 extensions: Map::new(),
297 };
298
299 let map = node.require_map().expect("Should convert to map");
300 assert_eq!(map.0.len(), 0);
301
302 assert!(node.as_map().is_some());
304 }
305
306 #[test]
307 fn test_require_map_on_existing_map() {
308 let mut node = Node {
309 content: NodeValue::Map(Default::default()),
310 extensions: Map::new(),
311 };
312
313 let map = node.require_map().expect("Should return existing map");
314 assert_eq!(map.0.len(), 0);
315 }
316
317 #[test]
318 fn test_require_map_on_wrong_type() {
319 let mut node = Node {
320 content: NodeValue::Primitive(PrimitiveValue::Null),
321 extensions: Map::new(),
322 };
323
324 let result = node.require_map();
325 assert_eq!(result, Err(InsertErrorKind::ExpectedMap));
326 }
327
328 #[test]
329 fn test_require_tuple_on_uninitialized() {
330 let mut node = Node {
331 content: NodeValue::hole(),
332 extensions: Map::new(),
333 };
334
335 let tuple = node.require_tuple().expect("Should convert to tuple");
336 assert_eq!(tuple.0.len(), 0);
337
338 assert!(node.as_tuple().is_some());
340 }
341
342 #[test]
343 fn test_require_tuple_on_existing_tuple() {
344 let mut node = Node {
345 content: NodeValue::Tuple(Default::default()),
346 extensions: Map::new(),
347 };
348
349 let tuple = node.require_tuple().expect("Should return existing tuple");
350 assert_eq!(tuple.0.len(), 0);
351 }
352
353 #[test]
354 fn test_require_tuple_on_wrong_type() {
355 let mut node = Node {
356 content: NodeValue::Primitive(PrimitiveValue::Null),
357 extensions: Map::new(),
358 };
359
360 let result = node.require_tuple();
361 assert_eq!(result, Err(InsertErrorKind::ExpectedTuple));
362 }
363
364 #[test]
365 fn test_require_array_on_uninitialized() {
366 let mut node = Node {
367 content: NodeValue::hole(),
368 extensions: Map::new(),
369 };
370
371 let array = node.require_array().expect("Should convert to array");
372 assert_eq!(array.0.len(), 0);
373
374 assert!(node.as_array().is_some());
376 }
377
378 #[test]
379 fn test_require_array_on_existing_array() {
380 let mut node = Node {
381 content: NodeValue::Array(Default::default()),
382 extensions: Map::new(),
383 };
384
385 let array = node.require_array().expect("Should return existing array");
386 assert_eq!(array.0.len(), 0);
387 }
388
389 #[test]
390 fn test_require_array_on_wrong_type() {
391 let mut node = Node {
392 content: NodeValue::Primitive(PrimitiveValue::Null),
393 extensions: Map::new(),
394 };
395
396 let result = node.require_array();
397 assert_eq!(result, Err(InsertErrorKind::ExpectedArray));
398 }
399
400 #[test]
401 fn test_node_get_extension_exists() {
402 let mut doc = EureDocument::new();
403 let root_id = doc.get_root_id();
404 let ext_identifier = identifier("test_ext");
405
406 let ext_node_id = doc
408 .add_extension(ext_identifier.clone(), root_id)
409 .expect("Failed to add extension")
410 .node_id;
411
412 let root_node = doc.node(root_id);
414 let result = root_node.get_extension(&ext_identifier);
415
416 assert!(result.is_some());
417 assert_eq!(result.unwrap(), ext_node_id);
418 }
419
420 #[test]
421 fn test_node_get_extension_missing() {
422 let doc = EureDocument::new();
423 let root_id = doc.get_root_id();
424 let ext_identifier = identifier("nonexistent");
425
426 let root_node = doc.node(root_id);
428 let result = root_node.get_extension(&ext_identifier);
429
430 assert!(result.is_none());
431 }
432
433 #[test]
434 fn test_node_mut_get_extension_exists() {
435 let mut doc = EureDocument::new();
436 let root_id = doc.get_root_id();
437 let ext_identifier = identifier("test_ext");
438
439 let ext_node_id = doc
441 .add_extension(ext_identifier.clone(), root_id)
442 .expect("Failed to add extension")
443 .node_id;
444
445 let node_mut = NodeMut::new(&mut doc, root_id);
447 let result = node_mut.get_extension(&ext_identifier);
448
449 assert!(result.is_some());
450 let ext_node_mut = result.unwrap();
451 assert_eq!(ext_node_mut.node_id, ext_node_id);
452 }
453
454 #[test]
455 fn test_node_mut_get_extension_missing() {
456 let mut doc = EureDocument::new();
457 let root_id = doc.get_root_id();
458 let ext_identifier = identifier("nonexistent");
459
460 let node_mut = NodeMut::new(&mut doc, root_id);
462 let result = node_mut.get_extension(&ext_identifier);
463
464 assert!(result.is_none());
465 }
466
467 #[test]
468 fn test_node_mut_debug_valid_node() {
469 let mut doc = EureDocument::new();
470 let root_id = doc.get_root_id();
471
472 let node_mut = NodeMut::new(&mut doc, root_id);
474 let debug_output = alloc::format!("{:?}", node_mut);
475
476 assert!(debug_output.contains("NodeMut"));
478 assert!(debug_output.contains("NodeId"));
479 assert!(debug_output.contains("Node"));
480 assert!(debug_output.contains("Hole"));
481 }
482
483 #[test]
484 fn test_node_mut_debug_invalid_node() {
485 let mut doc = EureDocument::new();
486 let invalid_id = NodeId(999999); let node_mut = NodeMut::new(&mut doc, invalid_id);
490 let debug_output = alloc::format!("{:?}", node_mut);
491
492 assert!(debug_output.contains("NodeMut"));
494 assert!(debug_output.contains("<invalid>"));
495 }
496}