1mod node;
34mod walker;
35
36pub use node::{ParentRef, RecordId};
37pub use walker::{BreadthFirstWalker, TreeWalker};
38
39use std::collections::HashMap;
40
41pub trait TreeRecord {
46 fn owner_index(&self) -> i32;
49
50 fn set_owner_index(&mut self, index: i32);
52}
53
54#[derive(Debug, Clone)]
59pub struct RecordTree<R> {
60 records: Vec<R>,
62 parents: HashMap<RecordId, RecordId>,
64 children: HashMap<RecordId, Vec<RecordId>>,
66 roots: Vec<RecordId>,
68}
69
70impl<R: TreeRecord> RecordTree<R> {
71 pub fn from_records(records: Vec<R>) -> Self {
75 let mut tree = RecordTree {
76 records,
77 parents: HashMap::new(),
78 children: HashMap::new(),
79 roots: Vec::new(),
80 };
81 tree.rebuild_relationships();
82 tree
83 }
84
85 fn rebuild_relationships(&mut self) {
87 self.parents.clear();
88 self.children.clear();
89 self.roots.clear();
90
91 let len = self.records.len();
92
93 for (idx, record) in self.records.iter().enumerate() {
94 let child_id = RecordId::new(idx as u32);
95 let owner_index = record.owner_index();
96
97 if owner_index < 0 || (owner_index as usize) >= len {
99 self.roots.push(child_id);
100 } else {
101 let parent_id = RecordId::new(owner_index as u32);
102 self.parents.insert(child_id, parent_id);
103 self.children.entry(parent_id).or_default().push(child_id);
104 }
105 }
106 }
107
108 pub fn len(&self) -> usize {
110 self.records.len()
111 }
112
113 pub fn is_empty(&self) -> bool {
115 self.records.is_empty()
116 }
117
118 pub fn get(&self, id: RecordId) -> Option<&R> {
120 self.records.get(id.index() as usize)
121 }
122
123 pub fn get_mut(&mut self, id: RecordId) -> Option<&mut R> {
125 self.records.get_mut(id.index() as usize)
126 }
127
128 pub fn get_by_index(&self, index: usize) -> Option<&R> {
130 self.records.get(index)
131 }
132
133 pub fn iter(&self) -> impl Iterator<Item = (RecordId, &R)> {
135 self.records
136 .iter()
137 .enumerate()
138 .map(|(i, r)| (RecordId::new(i as u32), r))
139 }
140
141 pub fn iter_mut(&mut self) -> impl Iterator<Item = (RecordId, &mut R)> {
143 self.records
144 .iter_mut()
145 .enumerate()
146 .map(|(i, r)| (RecordId::new(i as u32), r))
147 }
148
149 pub fn roots(&self) -> impl Iterator<Item = (RecordId, &R)> {
151 self.roots
152 .iter()
153 .filter_map(move |&id| self.records.get(id.index() as usize).map(|r| (id, r)))
154 }
155
156 pub fn root_count(&self) -> usize {
158 self.roots.len()
159 }
160
161 pub fn is_root(&self, id: RecordId) -> bool {
163 self.roots.contains(&id)
164 }
165
166 pub fn parent(&self, id: RecordId) -> Option<(RecordId, &R)> {
168 self.parents.get(&id).and_then(|&parent_id| {
169 self.records
170 .get(parent_id.index() as usize)
171 .map(|r| (parent_id, r))
172 })
173 }
174
175 pub fn parent_id(&self, id: RecordId) -> Option<RecordId> {
177 self.parents.get(&id).copied()
178 }
179
180 pub fn children(&self, id: RecordId) -> impl Iterator<Item = (RecordId, &R)> {
182 self.children
183 .get(&id)
184 .map(|ids| ids.as_slice())
185 .unwrap_or(&[])
186 .iter()
187 .filter_map(move |&child_id| {
188 self.records
189 .get(child_id.index() as usize)
190 .map(|r| (child_id, r))
191 })
192 }
193
194 pub fn child_count(&self, id: RecordId) -> usize {
196 self.children.get(&id).map(|c| c.len()).unwrap_or(0)
197 }
198
199 pub fn has_children(&self, id: RecordId) -> bool {
201 self.children
202 .get(&id)
203 .map(|c| !c.is_empty())
204 .unwrap_or(false)
205 }
206
207 pub fn ancestors(&self, id: RecordId) -> impl Iterator<Item = (RecordId, &R)> {
209 AncestorIterator {
210 tree: self,
211 current: self.parent_id(id),
212 }
213 }
214
215 pub fn descendants(&self, id: RecordId) -> impl Iterator<Item = (RecordId, &R)> {
217 DescendantIterator {
218 tree: self,
219 stack: self.children.get(&id).cloned().unwrap_or_default(),
220 }
221 }
222
223 pub fn depth(&self, id: RecordId) -> usize {
225 let mut depth = 0;
226 let mut current = id;
227 while let Some(parent_id) = self.parent_id(current) {
228 depth += 1;
229 current = parent_id;
230 }
231 depth
232 }
233
234 pub fn walk_depth_first(&self) -> TreeWalker<'_, R> {
236 TreeWalker::new(self)
237 }
238
239 pub fn walk_from(&self, id: RecordId) -> TreeWalker<'_, R> {
241 TreeWalker::from_node(self, id)
242 }
243
244 pub fn find<F>(&self, predicate: F) -> impl Iterator<Item = (RecordId, &R)>
246 where
247 F: Fn(&R) -> bool,
248 {
249 self.records
250 .iter()
251 .enumerate()
252 .filter(move |(_, r)| predicate(r))
253 .map(|(i, r)| (RecordId::new(i as u32), r))
254 }
255
256 pub fn find_first<F>(&self, predicate: F) -> Option<(RecordId, &R)>
258 where
259 F: Fn(&R) -> bool,
260 {
261 self.records
262 .iter()
263 .enumerate()
264 .find(|(_, r)| predicate(r))
265 .map(|(i, r)| (RecordId::new(i as u32), r))
266 }
267
268 pub fn path_to_root(&self, id: RecordId) -> Vec<RecordId> {
270 let mut path = vec![id];
271 let mut current = id;
272 while let Some(parent_id) = self.parent_id(current) {
273 path.push(parent_id);
274 current = parent_id;
275 }
276 path
277 }
278
279 pub fn into_records(self) -> Vec<R> {
281 self.records
282 }
283
284 pub fn as_slice(&self) -> &[R] {
286 &self.records
287 }
288
289 pub fn add(&mut self, record: R) -> RecordId {
293 let id = RecordId::new(self.records.len() as u32);
294 let owner_index = record.owner_index();
295
296 self.records.push(record);
297
298 if owner_index < 0 || (owner_index as usize) >= self.records.len() - 1 {
300 self.roots.push(id);
301 } else {
302 let parent_id = RecordId::new(owner_index as u32);
303 self.parents.insert(id, parent_id);
304 self.children.entry(parent_id).or_default().push(id);
305 }
306
307 id
308 }
309
310 pub fn remove(&mut self, id: RecordId) -> Option<R> {
315 let index = id.index() as usize;
316 if index >= self.records.len() {
317 return None;
318 }
319
320 let record = self.records.remove(index);
321
322 self.rebuild_relationships();
324
325 Some(record)
326 }
327
328 pub fn reparent(&mut self, id: RecordId, new_parent: Option<RecordId>) {
330 if let Some(old_parent_id) = self.parents.remove(&id) {
332 if let Some(siblings) = self.children.get_mut(&old_parent_id) {
333 siblings.retain(|&child_id| child_id != id);
334 }
335 }
336
337 self.roots.retain(|&root_id| root_id != id);
339
340 if let Some(parent_id) = new_parent {
342 self.parents.insert(id, parent_id);
343 self.children.entry(parent_id).or_default().push(id);
344
345 if let Some(record) = self.records.get_mut(id.index() as usize) {
347 record.set_owner_index(parent_id.index() as i32);
348 }
349 } else {
350 self.roots.push(id);
352 if let Some(record) = self.records.get_mut(id.index() as usize) {
353 record.set_owner_index(-1);
354 }
355 }
356 }
357}
358
359impl<R> Default for RecordTree<R> {
360 fn default() -> Self {
361 RecordTree {
362 records: Vec::new(),
363 parents: HashMap::new(),
364 children: HashMap::new(),
365 roots: Vec::new(),
366 }
367 }
368}
369
370struct AncestorIterator<'a, R: TreeRecord> {
372 tree: &'a RecordTree<R>,
373 current: Option<RecordId>,
374}
375
376impl<'a, R: TreeRecord> Iterator for AncestorIterator<'a, R> {
377 type Item = (RecordId, &'a R);
378
379 fn next(&mut self) -> Option<Self::Item> {
380 let id = self.current?;
381 self.current = self.tree.parent_id(id);
382 self.tree.get(id).map(|r| (id, r))
383 }
384}
385
386struct DescendantIterator<'a, R: TreeRecord> {
388 tree: &'a RecordTree<R>,
389 stack: Vec<RecordId>,
390}
391
392impl<'a, R: TreeRecord> Iterator for DescendantIterator<'a, R> {
393 type Item = (RecordId, &'a R);
394
395 fn next(&mut self) -> Option<Self::Item> {
396 let id = self.stack.pop()?;
397
398 if let Some(children) = self.tree.children.get(&id) {
400 self.stack.extend(children.iter().rev());
401 }
402
403 self.tree.get(id).map(|r| (id, r))
404 }
405}
406
407#[cfg(test)]
408mod tests {
409 use super::*;
410
411 #[derive(Debug, Clone, Default)]
412 struct TestRecord {
413 owner_index: i32,
414 value: String,
415 }
416
417 impl TreeRecord for TestRecord {
418 fn owner_index(&self) -> i32 {
419 self.owner_index
420 }
421
422 fn set_owner_index(&mut self, index: i32) {
423 self.owner_index = index;
424 }
425 }
426
427 #[test]
428 fn test_build_tree() {
429 let records = vec![
430 TestRecord {
431 owner_index: -1,
432 value: "root".to_string(),
433 },
434 TestRecord {
435 owner_index: 0,
436 value: "child1".to_string(),
437 },
438 TestRecord {
439 owner_index: 0,
440 value: "child2".to_string(),
441 },
442 TestRecord {
443 owner_index: 1,
444 value: "grandchild".to_string(),
445 },
446 ];
447
448 let tree = RecordTree::from_records(records);
449
450 assert_eq!(tree.len(), 4);
451 assert_eq!(tree.root_count(), 1);
452 }
453
454 #[test]
455 fn test_navigation() {
456 let records = vec![
457 TestRecord {
458 owner_index: -1,
459 value: "root".to_string(),
460 },
461 TestRecord {
462 owner_index: 0,
463 value: "child1".to_string(),
464 },
465 TestRecord {
466 owner_index: 0,
467 value: "child2".to_string(),
468 },
469 TestRecord {
470 owner_index: 1,
471 value: "grandchild".to_string(),
472 },
473 ];
474
475 let tree = RecordTree::from_records(records);
476
477 let roots: Vec<_> = tree.roots().collect();
479 assert_eq!(roots.len(), 1);
480 assert_eq!(roots[0].1.value, "root");
481
482 let root_id = RecordId::new(0);
484 let children: Vec<_> = tree.children(root_id).collect();
485 assert_eq!(children.len(), 2);
486
487 let child_id = RecordId::new(1);
489 let parent = tree.parent(child_id);
490 assert!(parent.is_some());
491 assert_eq!(parent.unwrap().1.value, "root");
492
493 assert_eq!(tree.depth(RecordId::new(0)), 0);
495 assert_eq!(tree.depth(RecordId::new(1)), 1);
496 assert_eq!(tree.depth(RecordId::new(3)), 2);
497 }
498
499 #[test]
500 fn test_walk_depth_first() {
501 let records = vec![
502 TestRecord {
503 owner_index: -1,
504 value: "root".to_string(),
505 },
506 TestRecord {
507 owner_index: 0,
508 value: "child1".to_string(),
509 },
510 TestRecord {
511 owner_index: 0,
512 value: "child2".to_string(),
513 },
514 TestRecord {
515 owner_index: 1,
516 value: "grandchild".to_string(),
517 },
518 ];
519
520 let tree = RecordTree::from_records(records);
521
522 let walked: Vec<_> = tree.walk_depth_first().collect();
523 assert_eq!(walked.len(), 4);
524
525 assert_eq!(walked[0].1.value, "root");
527 assert_eq!(walked[0].2, 0);
528 }
529
530 #[test]
531 fn test_ancestors() {
532 let records = vec![
533 TestRecord {
534 owner_index: -1,
535 value: "root".to_string(),
536 },
537 TestRecord {
538 owner_index: 0,
539 value: "child".to_string(),
540 },
541 TestRecord {
542 owner_index: 1,
543 value: "grandchild".to_string(),
544 },
545 ];
546
547 let tree = RecordTree::from_records(records);
548
549 let ancestors: Vec<_> = tree.ancestors(RecordId::new(2)).collect();
550 assert_eq!(ancestors.len(), 2);
551 assert_eq!(ancestors[0].1.value, "child");
552 assert_eq!(ancestors[1].1.value, "root");
553 }
554}