1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 /// A struct that makes it easier to print out a pretty tree of data, which
6 /// can be visually scanned more easily.
7 pub struct PrintTree {
8     /// The current level of recursion.
9     level: u32,
10 
11     /// An item which is queued up, so that we can determine if we need
12     /// a mid-tree prefix or a branch ending prefix.
13     queued_item: Option<String>,
14 }
15 
16 /// A trait that makes it easy to describe a pretty tree of data,
17 /// regardless of the printing destination, to either print it
18 /// directly to stdout, or serialize it as in the debugger
19 pub trait PrintTreePrinter {
new_level(&mut self, title: String)20     fn new_level(&mut self, title: String);
end_level(&mut self)21     fn end_level(&mut self);
add_item(&mut self, text: String)22     fn add_item(&mut self, text: String);
23 }
24 
25 impl PrintTree {
new(title: &str) -> PrintTree26     pub fn new(title: &str) -> PrintTree {
27         println!("\u{250c} {}", title);
28         PrintTree {
29             level: 1,
30             queued_item: None,
31         }
32     }
33 
print_level_prefix(&self)34     fn print_level_prefix(&self) {
35         for _ in 0 .. self.level {
36             print!("\u{2502}  ");
37         }
38     }
39 
flush_queued_item(&mut self, prefix: &str)40     fn flush_queued_item(&mut self, prefix: &str) {
41         if let Some(queued_item) = self.queued_item.take() {
42             self.print_level_prefix();
43             println!("{} {}", prefix, queued_item);
44         }
45     }
46 }
47 
48 // The default `println!` based printer
49 impl PrintTreePrinter for PrintTree {
50     /// Descend one level in the tree with the given title.
new_level(&mut self, title: String)51     fn new_level(&mut self, title: String) {
52         self.flush_queued_item("\u{251C}\u{2500}");
53 
54         self.print_level_prefix();
55         println!("\u{251C}\u{2500} {}", title);
56 
57         self.level = self.level + 1;
58     }
59 
60     /// Ascend one level in the tree.
end_level(&mut self)61     fn end_level(&mut self) {
62         self.flush_queued_item("\u{2514}\u{2500}");
63         self.level = self.level - 1;
64     }
65 
66     /// Add an item to the current level in the tree.
add_item(&mut self, text: String)67     fn add_item(&mut self, text: String) {
68         self.flush_queued_item("\u{251C}\u{2500}");
69         self.queued_item = Some(text);
70     }
71 }
72 
73 impl Drop for PrintTree {
drop(&mut self)74     fn drop(&mut self) {
75         self.flush_queued_item("\u{9492}\u{9472}");
76     }
77 }
78