Skip to content

Commit b9b4553

Browse files
authored
Merge branch 'master' into traversals
2 parents 8f54fba + 031c61c commit b9b4553

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

examples/formatted.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
extern crate slab_tree;
2+
3+
use slab_tree::*;
4+
5+
fn main() {
6+
let mut tree = TreeBuilder::new().with_root(0).build();
7+
let mut root = tree.root_mut().unwrap();
8+
{
9+
let mut one = root.append(1);
10+
let mut two = one.append(2);
11+
two.append(3);
12+
two.append(4);
13+
}
14+
{
15+
let mut five = root.append(5);
16+
five.append(6).append(7);
17+
five.append(8);
18+
}
19+
root.append(9);
20+
21+
let mut s = String::new();
22+
// 0
23+
// ├── 1
24+
// │ └── 2
25+
// │ ├── 3
26+
// │ └── 4
27+
// ├── 5
28+
// │ ├── 6
29+
// │ │ └── 7
30+
// │ └── 8
31+
// └── 9
32+
tree.write_formatted(&mut s).unwrap();
33+
print!("{}", s);
34+
}

src/tree.rs

+83
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,89 @@ impl<T> Default for Tree<T> {
376376
}
377377
}
378378

379+
impl<T: std::fmt::Debug> Tree<T> {
380+
/// Write formatted tree representation and nodes with debug formatting.
381+
///
382+
/// Example:
383+
///
384+
/// ```
385+
/// use slab_tree::tree::TreeBuilder;
386+
///
387+
/// let mut tree = TreeBuilder::new().with_root(0).build();
388+
/// let mut root = tree.root_mut().unwrap();
389+
/// root.append(1)
390+
/// .append(2);
391+
/// root.append(3);
392+
/// let mut s = String::new();
393+
/// tree.write_formatted(&mut s).unwrap();
394+
/// assert_eq!(&s, "\
395+
/// 0
396+
/// ├── 1
397+
/// │ └── 2
398+
/// └── 3
399+
/// ");
400+
/// ```
401+
///
402+
/// Writes nothing if the tree is empty.
403+
///
404+
/// ```
405+
/// use slab_tree::tree::TreeBuilder;
406+
///
407+
/// let tree = TreeBuilder::<i32>::new().build();
408+
/// let mut s = String::new();
409+
/// tree.write_formatted(&mut s).unwrap();
410+
/// assert_eq!(&s, "");
411+
/// ```
412+
pub fn write_formatted<W: std::fmt::Write>(&self, w: &mut W) -> std::fmt::Result {
413+
if let Some(root) = self.root() {
414+
let node_id = root.node_id();
415+
let childn = 0;
416+
let level = 0;
417+
let last = vec![];
418+
let mut stack = vec![(node_id, childn, level, last)];
419+
while let Some((node_id, childn, level, last)) = stack.pop() {
420+
debug_assert_eq!(
421+
last.len(),
422+
level,
423+
"each previous level should indicate whether it has reached the last node"
424+
);
425+
let node = self
426+
.get(node_id)
427+
.expect("getting node of existing node ref id");
428+
if childn == 0 {
429+
for i in 1..level {
430+
if last[i - 1] {
431+
write!(w, " ")?;
432+
} else {
433+
write!(w, "│ ")?;
434+
}
435+
}
436+
if level > 0 {
437+
if last[level - 1] {
438+
write!(w, "└── ")?;
439+
} else {
440+
write!(w, "├── ")?;
441+
}
442+
}
443+
writeln!(w, "{:?}", node.data())?;
444+
}
445+
let mut children = node.children().skip(childn);
446+
if let Some(child) = children.next() {
447+
let mut next_last = last.clone();
448+
if children.next().is_some() {
449+
stack.push((node_id, childn + 1, level, last));
450+
next_last.push(false);
451+
} else {
452+
next_last.push(true);
453+
}
454+
stack.push((child.node_id(), 0, level + 1, next_last));
455+
}
456+
}
457+
}
458+
Ok(())
459+
}
460+
}
461+
379462
#[cfg_attr(tarpaulin, skip)]
380463
#[cfg(test)]
381464
mod tree_tests {

0 commit comments

Comments
 (0)