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)]
231#[plural(len, is_empty, iter, into_iter, new)]
232pub struct NodeArray(Vec<NodeId>);
233
234#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Plural)]
235#[plural(len, is_empty, iter, into_iter, new)]
236pub struct NodeTuple(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 pub fn to_vec(&self) -> Vec<NodeId> {
262 self.0.clone()
263 }
264
265 pub fn from_vec(vec: Vec<NodeId>) -> Self {
266 Self(vec)
267 }
268}
269
270impl NodeArray {
271 pub fn get(&self, index: usize) -> Option<NodeId> {
272 self.0.get(index).copied()
273 }
274
275 pub fn push(&mut self, node_id: NodeId) -> Result<(), InsertErrorKind> {
276 self.0.push(node_id);
277 Ok(())
278 }
279
280 pub fn add_at(&mut self, index: usize, node_id: NodeId) -> Result<(), InsertErrorKind> {
281 if index != self.0.len() {
282 return Err(InsertErrorKind::ArrayIndexInvalid {
283 index,
284 expected_index: self.0.len(),
285 });
286 }
287 self.0.insert(index, node_id);
288 Ok(())
289 }
290
291 pub fn to_vec(&self) -> Vec<NodeId> {
292 self.0.clone()
293 }
294
295 pub fn from_vec(vec: Vec<NodeId>) -> Self {
296 Self(vec)
297 }
298}
299
300#[cfg(test)]
301mod tests {
302 use super::*;
303
304 fn identifier(s: &str) -> Identifier {
305 s.parse().unwrap()
306 }
307
308 #[test]
309 fn test_require_map_on_uninitialized() {
310 let mut node = Node {
311 content: NodeValue::hole(),
312 extensions: Map::new(),
313 };
314
315 let map = node.require_map().expect("Should convert to map");
316 assert_eq!(map.len(), 0);
317
318 assert!(node.as_map().is_some());
320 }
321
322 #[test]
323 fn test_require_map_on_existing_map() {
324 let mut node = Node {
325 content: NodeValue::Map(Default::default()),
326 extensions: Map::new(),
327 };
328
329 let map = node.require_map().expect("Should return existing map");
330 assert_eq!(map.len(), 0);
331 }
332
333 #[test]
334 fn test_require_map_on_wrong_type() {
335 let mut node = Node {
336 content: NodeValue::Primitive(PrimitiveValue::Null),
337 extensions: Map::new(),
338 };
339
340 let result = node.require_map();
341 assert_eq!(result, Err(InsertErrorKind::ExpectedMap));
342 }
343
344 #[test]
345 fn test_require_tuple_on_uninitialized() {
346 let mut node = Node {
347 content: NodeValue::hole(),
348 extensions: Map::new(),
349 };
350
351 let tuple = node.require_tuple().expect("Should convert to tuple");
352 assert_eq!(tuple.len(), 0);
353
354 assert!(node.as_tuple().is_some());
356 }
357
358 #[test]
359 fn test_require_tuple_on_existing_tuple() {
360 let mut node = Node {
361 content: NodeValue::Tuple(Default::default()),
362 extensions: Map::new(),
363 };
364
365 let tuple = node.require_tuple().expect("Should return existing tuple");
366 assert_eq!(tuple.len(), 0);
367 }
368
369 #[test]
370 fn test_require_tuple_on_wrong_type() {
371 let mut node = Node {
372 content: NodeValue::Primitive(PrimitiveValue::Null),
373 extensions: Map::new(),
374 };
375
376 let result = node.require_tuple();
377 assert_eq!(result, Err(InsertErrorKind::ExpectedTuple));
378 }
379
380 #[test]
381 fn test_require_array_on_uninitialized() {
382 let mut node = Node {
383 content: NodeValue::hole(),
384 extensions: Map::new(),
385 };
386
387 let array = node.require_array().expect("Should convert to array");
388 assert_eq!(array.len(), 0);
389
390 assert!(node.as_array().is_some());
392 }
393
394 #[test]
395 fn test_require_array_on_existing_array() {
396 let mut node = Node {
397 content: NodeValue::Array(Default::default()),
398 extensions: Map::new(),
399 };
400
401 let array = node.require_array().expect("Should return existing array");
402 assert_eq!(array.len(), 0);
403 }
404
405 #[test]
406 fn test_require_array_on_wrong_type() {
407 let mut node = Node {
408 content: NodeValue::Primitive(PrimitiveValue::Null),
409 extensions: Map::new(),
410 };
411
412 let result = node.require_array();
413 assert_eq!(result, Err(InsertErrorKind::ExpectedArray));
414 }
415
416 #[test]
417 fn test_node_get_extension_exists() {
418 let mut doc = EureDocument::new();
419 let root_id = doc.get_root_id();
420 let ext_identifier = identifier("test_ext");
421
422 let ext_node_id = doc
424 .add_extension(ext_identifier.clone(), root_id)
425 .expect("Failed to add extension")
426 .node_id;
427
428 let root_node = doc.node(root_id);
430 let result = root_node.get_extension(&ext_identifier);
431
432 assert!(result.is_some());
433 assert_eq!(result.unwrap(), ext_node_id);
434 }
435
436 #[test]
437 fn test_node_get_extension_missing() {
438 let doc = EureDocument::new();
439 let root_id = doc.get_root_id();
440 let ext_identifier = identifier("nonexistent");
441
442 let root_node = doc.node(root_id);
444 let result = root_node.get_extension(&ext_identifier);
445
446 assert!(result.is_none());
447 }
448
449 #[test]
450 fn test_node_mut_get_extension_exists() {
451 let mut doc = EureDocument::new();
452 let root_id = doc.get_root_id();
453 let ext_identifier = identifier("test_ext");
454
455 let ext_node_id = doc
457 .add_extension(ext_identifier.clone(), root_id)
458 .expect("Failed to add extension")
459 .node_id;
460
461 let node_mut = NodeMut::new(&mut doc, root_id);
463 let result = node_mut.get_extension(&ext_identifier);
464
465 assert!(result.is_some());
466 let ext_node_mut = result.unwrap();
467 assert_eq!(ext_node_mut.node_id, ext_node_id);
468 }
469
470 #[test]
471 fn test_node_mut_get_extension_missing() {
472 let mut doc = EureDocument::new();
473 let root_id = doc.get_root_id();
474 let ext_identifier = identifier("nonexistent");
475
476 let node_mut = NodeMut::new(&mut doc, root_id);
478 let result = node_mut.get_extension(&ext_identifier);
479
480 assert!(result.is_none());
481 }
482
483 #[test]
484 fn test_node_mut_debug_valid_node() {
485 let mut doc = EureDocument::new();
486 let root_id = doc.get_root_id();
487
488 let node_mut = NodeMut::new(&mut doc, root_id);
490 let debug_output = alloc::format!("{:?}", node_mut);
491
492 assert!(debug_output.contains("NodeMut"));
494 assert!(debug_output.contains("NodeId"));
495 assert!(debug_output.contains("Node"));
496 assert!(debug_output.contains("Hole"));
497 }
498
499 #[test]
500 fn test_node_mut_debug_invalid_node() {
501 let mut doc = EureDocument::new();
502 let invalid_id = NodeId(999999); let node_mut = NodeMut::new(&mut doc, invalid_id);
506 let debug_output = alloc::format!("{:?}", node_mut);
507
508 assert!(debug_output.contains("NodeMut"));
510 assert!(debug_output.contains("<invalid>"));
511 }
512}