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