1use super::id_registry::IdRegistry;
7use super::node::FoNode;
8use std::fmt;
9
10#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
12pub struct NodeId(usize);
13
14impl NodeId {
15 #[inline]
17 pub fn index(self) -> usize {
18 self.0
19 }
20
21 #[inline]
23 pub const fn from_index(index: usize) -> Self {
24 Self(index)
25 }
26}
27
28impl fmt::Display for NodeId {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 write!(f, "Node({})", self.0)
31 }
32}
33
34pub struct FoArena<'a> {
39 nodes: Vec<FoNode<'a>>,
40 id_registry: IdRegistry,
41 pub document_lang: Option<String>,
43 pub xmp_packets: Vec<String>,
47}
48
49impl<'a> FoArena<'a> {
50 pub fn new() -> Self {
52 Self {
53 nodes: Vec::new(),
54 id_registry: IdRegistry::new(),
55 document_lang: None,
56 xmp_packets: Vec::new(),
57 }
58 }
59
60 pub fn with_capacity(capacity: usize) -> Self {
62 Self {
63 nodes: Vec::with_capacity(capacity),
64 id_registry: IdRegistry::new(),
65 document_lang: None,
66 xmp_packets: Vec::new(),
67 }
68 }
69
70 pub fn id_registry(&self) -> &IdRegistry {
72 &self.id_registry
73 }
74
75 pub fn id_registry_mut(&mut self) -> &mut IdRegistry {
77 &mut self.id_registry
78 }
79
80 pub fn add_node(&mut self, node: FoNode<'a>) -> NodeId {
82 let id = NodeId(self.nodes.len());
83 self.nodes.push(node);
84 id
85 }
86
87 pub fn get(&self, id: NodeId) -> Option<&FoNode<'a>> {
89 self.nodes.get(id.0)
90 }
91
92 pub fn get_mut(&mut self, id: NodeId) -> Option<&mut FoNode<'a>> {
94 self.nodes.get_mut(id.0)
95 }
96
97 #[inline]
99 pub fn len(&self) -> usize {
100 self.nodes.len()
101 }
102
103 #[inline]
105 pub fn is_empty(&self) -> bool {
106 self.nodes.is_empty()
107 }
108
109 pub fn iter(&self) -> impl Iterator<Item = (NodeId, &FoNode<'a>)> {
111 self.nodes
112 .iter()
113 .enumerate()
114 .map(|(i, node)| (NodeId(i), node))
115 }
116
117 pub fn root(&self) -> Option<(NodeId, &FoNode<'a>)> {
119 if self.nodes.is_empty() {
120 None
121 } else {
122 Some((NodeId(0), &self.nodes[0]))
123 }
124 }
125
126 pub fn set_parent(&mut self, child: NodeId, parent: NodeId) -> Result<(), String> {
128 if child.0 >= self.nodes.len() {
129 return Err(format!("Child node {} does not exist", child.0));
130 }
131 if parent.0 >= self.nodes.len() {
132 return Err(format!("Parent node {} does not exist", parent.0));
133 }
134
135 self.nodes[child.0].parent = Some(parent);
137
138 Ok(())
139 }
140
141 pub fn append_child(&mut self, parent: NodeId, child: NodeId) -> Result<(), String> {
143 if child.0 >= self.nodes.len() {
144 return Err(format!("Child node {} does not exist", child.0));
145 }
146 if parent.0 >= self.nodes.len() {
147 return Err(format!("Parent node {} does not exist", parent.0));
148 }
149
150 self.nodes[child.0].parent = Some(parent);
152
153 let parent_node = &mut self.nodes[parent.0];
155 if let Some(first_child) = parent_node.first_child {
156 let mut last_sibling = first_child;
158 while let Some(next) = self.nodes[last_sibling.0].next_sibling {
159 last_sibling = next;
160 }
161 self.nodes[last_sibling.0].next_sibling = Some(child);
162 } else {
163 parent_node.first_child = Some(child);
165 }
166
167 Ok(())
168 }
169
170 pub fn children(&self, parent: NodeId) -> Vec<NodeId> {
172 let mut children = Vec::new();
173 if let Some(node) = self.get(parent) {
174 let mut current = node.first_child;
175 while let Some(child_id) = current {
176 children.push(child_id);
177 current = self.get(child_id).and_then(|n| n.next_sibling);
178 }
179 }
180 children
181 }
182
183 pub fn depth(&self, mut node: NodeId) -> usize {
185 let mut depth = 0;
186 while let Some(parent) = self.get(node).and_then(|n| n.parent) {
187 depth += 1;
188 node = parent;
189 }
190 depth
191 }
192}
193
194impl<'a> Default for FoArena<'a> {
195 fn default() -> Self {
196 Self::new()
197 }
198}
199
200#[cfg(test)]
201mod tests {
202 use super::*;
203 use crate::tree::node::FoNodeData;
204
205 #[test]
206 fn test_arena_creation() {
207 let arena: FoArena = FoArena::new();
208 assert_eq!(arena.len(), 0);
209 assert!(arena.is_empty());
210 }
211
212 #[test]
213 fn test_add_node() {
214 let mut arena = FoArena::new();
215 let node = FoNode::new(FoNodeData::Root);
216 let id = arena.add_node(node);
217
218 assert_eq!(arena.len(), 1);
219 assert_eq!(id.index(), 0);
220 assert!(arena.get(id).is_some());
221 }
222
223 #[test]
224 fn test_parent_child() {
225 let mut arena = FoArena::new();
226
227 let root = arena.add_node(FoNode::new(FoNodeData::Root));
229 let child = arena.add_node(FoNode::new(FoNodeData::Block {
230 properties: crate::properties::PropertyList::new(),
231 }));
232
233 arena
235 .append_child(root, child)
236 .expect("test: should succeed");
237
238 assert_eq!(
240 arena.get(child).expect("test: should succeed").parent,
241 Some(root)
242 );
243 assert_eq!(
244 arena.get(root).expect("test: should succeed").first_child,
245 Some(child)
246 );
247 }
248
249 #[test]
250 fn test_multiple_children() {
251 let mut arena = FoArena::new();
252
253 let root = arena.add_node(FoNode::new(FoNodeData::Root));
254 let child1 = arena.add_node(FoNode::new(FoNodeData::Block {
255 properties: crate::properties::PropertyList::new(),
256 }));
257 let child2 = arena.add_node(FoNode::new(FoNodeData::Block {
258 properties: crate::properties::PropertyList::new(),
259 }));
260 let child3 = arena.add_node(FoNode::new(FoNodeData::Block {
261 properties: crate::properties::PropertyList::new(),
262 }));
263
264 arena
265 .append_child(root, child1)
266 .expect("test: should succeed");
267 arena
268 .append_child(root, child2)
269 .expect("test: should succeed");
270 arena
271 .append_child(root, child3)
272 .expect("test: should succeed");
273
274 let children = arena.children(root);
275 assert_eq!(children.len(), 3);
276 assert_eq!(children[0], child1);
277 assert_eq!(children[1], child2);
278 assert_eq!(children[2], child3);
279 }
280
281 #[test]
282 fn test_depth() {
283 let mut arena = FoArena::new();
284
285 let root = arena.add_node(FoNode::new(FoNodeData::Root));
286 let child = arena.add_node(FoNode::new(FoNodeData::Block {
287 properties: crate::properties::PropertyList::new(),
288 }));
289 let grandchild = arena.add_node(FoNode::new(FoNodeData::Inline {
290 properties: crate::properties::PropertyList::new(),
291 }));
292
293 arena
294 .append_child(root, child)
295 .expect("test: should succeed");
296 arena
297 .append_child(child, grandchild)
298 .expect("test: should succeed");
299
300 assert_eq!(arena.depth(root), 0);
301 assert_eq!(arena.depth(child), 1);
302 assert_eq!(arena.depth(grandchild), 2);
303 }
304
305 #[test]
306 fn test_iteration() {
307 let mut arena = FoArena::new();
308
309 arena.add_node(FoNode::new(FoNodeData::Root));
310 arena.add_node(FoNode::new(FoNodeData::Block {
311 properties: crate::properties::PropertyList::new(),
312 }));
313 arena.add_node(FoNode::new(FoNodeData::Inline {
314 properties: crate::properties::PropertyList::new(),
315 }));
316
317 let count = arena.iter().count();
318 assert_eq!(count, 3);
319 }
320
321 #[test]
322 fn test_node_id_display() {
323 let id = NodeId::from_index(42);
324 assert_eq!(format!("{}", id), "Node(42)");
325 }
326
327 #[test]
328 fn test_node_id_equality() {
329 let id1 = NodeId::from_index(5);
330 let id2 = NodeId::from_index(5);
331 let id3 = NodeId::from_index(6);
332 assert_eq!(id1, id2);
333 assert_ne!(id1, id3);
334 }
335
336 #[test]
337 fn test_node_id_copy() {
338 let id1 = NodeId::from_index(3);
339 let id2 = id1;
340 assert_eq!(id1.index(), id2.index());
341 }
342
343 #[test]
344 fn test_with_capacity() {
345 let arena: FoArena = FoArena::with_capacity(64);
346 assert!(arena.is_empty());
347 assert_eq!(arena.len(), 0);
348 }
349
350 #[test]
351 fn test_default() {
352 let arena: FoArena = FoArena::default();
353 assert!(arena.is_empty());
354 }
355
356 #[test]
357 fn test_root_on_empty_arena() {
358 let arena: FoArena = FoArena::new();
359 assert!(arena.root().is_none());
360 }
361
362 #[test]
363 fn test_root_returns_first_node() {
364 let mut arena = FoArena::new();
365 let root_id = arena.add_node(FoNode::new(FoNodeData::Root));
366 arena.add_node(FoNode::new(FoNodeData::LayoutMasterSet));
367
368 let (id, node) = arena.root().expect("test: should succeed");
369 assert_eq!(id, root_id);
370 assert!(matches!(node.data, FoNodeData::Root));
371 }
372
373 #[test]
374 fn test_get_invalid_id() {
375 let arena: FoArena = FoArena::new();
376 let invalid = NodeId::from_index(999);
377 assert!(arena.get(invalid).is_none());
378 }
379
380 #[test]
381 fn test_get_mut_invalid_id() {
382 let mut arena: FoArena = FoArena::new();
383 let invalid = NodeId::from_index(999);
384 assert!(arena.get_mut(invalid).is_none());
385 }
386
387 #[test]
388 fn test_set_parent_invalid_child() {
389 let mut arena = FoArena::new();
390 let root = arena.add_node(FoNode::new(FoNodeData::Root));
391 let invalid = NodeId::from_index(999);
392 assert!(arena.set_parent(invalid, root).is_err());
393 }
394
395 #[test]
396 fn test_set_parent_invalid_parent() {
397 let mut arena = FoArena::new();
398 let child = arena.add_node(FoNode::new(FoNodeData::Root));
399 let invalid = NodeId::from_index(999);
400 assert!(arena.set_parent(child, invalid).is_err());
401 }
402
403 #[test]
404 fn test_append_child_invalid_child() {
405 let mut arena = FoArena::new();
406 let root = arena.add_node(FoNode::new(FoNodeData::Root));
407 let invalid = NodeId::from_index(999);
408 assert!(arena.append_child(root, invalid).is_err());
409 }
410
411 #[test]
412 fn test_append_child_invalid_parent() {
413 let mut arena = FoArena::new();
414 let child = arena.add_node(FoNode::new(FoNodeData::Root));
415 let invalid = NodeId::from_index(999);
416 assert!(arena.append_child(invalid, child).is_err());
417 }
418
419 #[test]
420 fn test_children_of_leaf() {
421 let mut arena = FoArena::new();
422 let root = arena.add_node(FoNode::new(FoNodeData::Root));
423 let children = arena.children(root);
424 assert!(children.is_empty());
425 }
426
427 #[test]
428 fn test_document_lang() {
429 let mut arena: FoArena = FoArena::new();
430 assert!(arena.document_lang.is_none());
431 arena.document_lang = Some("en".to_string());
432 assert_eq!(arena.document_lang.as_deref(), Some("en"));
433 }
434
435 #[test]
436 fn test_id_registry() {
437 let arena: FoArena = FoArena::new();
438 let _reg = arena.id_registry();
440 }
441
442 #[test]
443 fn test_id_registry_mut() {
444 let mut arena: FoArena = FoArena::new();
445 let _reg = arena.id_registry_mut();
446 }
447
448 #[test]
449 fn test_iter_yields_correct_ids() {
450 let mut arena = FoArena::new();
451 let id0 = arena.add_node(FoNode::new(FoNodeData::Root));
452 let id1 = arena.add_node(FoNode::new(FoNodeData::LayoutMasterSet));
453
454 let items: Vec<_> = arena.iter().collect();
455 assert_eq!(items.len(), 2);
456 assert_eq!(items[0].0, id0);
457 assert_eq!(items[1].0, id1);
458 }
459
460 #[test]
461 fn test_depth_three_levels() {
462 let mut arena = FoArena::new();
463 let root = arena.add_node(FoNode::new(FoNodeData::Root));
464 let child = arena.add_node(FoNode::new(FoNodeData::Block {
465 properties: crate::properties::PropertyList::new(),
466 }));
467 let grandchild = arena.add_node(FoNode::new(FoNodeData::Inline {
468 properties: crate::properties::PropertyList::new(),
469 }));
470 let great_grandchild = arena.add_node(FoNode::new(FoNodeData::Text("hi".to_string())));
471
472 arena
473 .append_child(root, child)
474 .expect("test: should succeed");
475 arena
476 .append_child(child, grandchild)
477 .expect("test: should succeed");
478 arena
479 .append_child(grandchild, great_grandchild)
480 .expect("test: should succeed");
481
482 assert_eq!(arena.depth(root), 0);
483 assert_eq!(arena.depth(child), 1);
484 assert_eq!(arena.depth(grandchild), 2);
485 assert_eq!(arena.depth(great_grandchild), 3);
486 }
487
488 #[test]
489 fn test_sibling_ordering() {
490 let mut arena = FoArena::new();
491 let parent = arena.add_node(FoNode::new(FoNodeData::Root));
492
493 let mut ids = vec![];
494 for _ in 0..5 {
495 let child = arena.add_node(FoNode::new(FoNodeData::Block {
496 properties: crate::properties::PropertyList::new(),
497 }));
498 arena
499 .append_child(parent, child)
500 .expect("test: should succeed");
501 ids.push(child);
502 }
503
504 let children = arena.children(parent);
505 assert_eq!(children, ids);
506 }
507}