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