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 impl PrintTree { new(title: String) -> PrintTree17 pub fn new(title: String) -> PrintTree { 18 println!("\u{250c} {}", title); 19 PrintTree { 20 level: 1, 21 queued_item: None, 22 } 23 } 24 25 /// Descend one level in the tree with the given title string. new_level(&mut self, queued_title: String)26 pub fn new_level(&mut self, queued_title: String) { 27 self.flush_queued_item("\u{251C}\u{2500}"); 28 29 self.print_level_prefix(); 30 31 let items: Vec<&str> = queued_title.split("\n").collect(); 32 println!("\u{251C}\u{2500} {}", items[0]); 33 for i in 1..items.len() { 34 self.print_level_child_indentation(); 35 print!("{}", items[i]); 36 if i < items.len() { 37 print!("\n"); 38 } 39 } 40 41 self.level = self.level + 1; 42 } 43 44 /// Ascend one level in the tree. end_level(&mut self)45 pub fn end_level(&mut self) { 46 self.flush_queued_item("\u{2514}\u{2500}"); 47 self.level -= 1; 48 } 49 50 /// Add an item to the current level in the tree. add_item(&mut self, text: String)51 pub fn add_item(&mut self, text: String) { 52 self.flush_queued_item("\u{251C}\u{2500}"); 53 self.queued_item = Some(text); 54 } 55 print_level_prefix(&self)56 fn print_level_prefix(&self) { 57 for _ in 0..self.level { 58 print!("\u{2502} "); 59 } 60 } 61 print_level_child_indentation(&self)62 fn print_level_child_indentation(&self) { 63 for _ in 0..(self.level + 1) { 64 print!("\u{2502} "); 65 } 66 print!("{}", " ".repeat(7)); 67 } 68 flush_queued_item(&mut self, prefix: &str)69 fn flush_queued_item(&mut self, prefix: &str) { 70 if let Some(queued_item) = self.queued_item.take() { 71 self.print_level_prefix(); 72 let items: Vec<&str> = queued_item.split("\n").collect(); 73 println!("{} {}", prefix, items[0]); 74 for i in 1..items.len() { 75 self.print_level_child_indentation(); 76 print!("{}", items[i]); 77 if i < items.len() { 78 print!("\n"); 79 } 80 } 81 } 82 } 83 } 84 85 impl Drop for PrintTree { drop(&mut self)86 fn drop(&mut self) { 87 self.flush_queued_item("\u{9492}\u{9472}"); 88 } 89 } 90