use once_cell::sync::Lazy; use std::sync::{Arc, Mutex}; #[derive(Debug, Clone)] pub struct TreeSymbols { /// A vertical base of the tree (│) pub continued: &'static str, /// Symbol for joining the first branch in a group (├) pub join_first: &'static str, /// Symbol for joining the last branch in a group (└) pub join_last: &'static str, /// Symbol for joining a branch that is not first or last in its group (├) pub join_inner: &'static str, /// Symbol for joining a branch if it is the only one in its group (├) pub join_only: &'static str, /// A repeated branch token (─) pub branch: &'static str, /// End of a leaf (╼) pub leaf: &'static str, pub multiline_first: Option<&'static str>, pub multiline_continued: Option<&'static str>, } #[derive(Debug, Clone)] pub struct TreeConfig { pub symbols: TreeSymbols, /// Aside from the first branch, `indent` is equal to the number of spaces a child branch is /// shifted from its parent. pub indent: usize, pub show_first_level: bool, } impl TreeSymbols { pub fn new() -> Self { Self { continued: "│", join_first: "├", join_inner: "├", join_last: "└", join_only: "└", branch: "─", leaf: "╼ ", multiline_first: None, multiline_continued: None, } } pub fn with_pipes() -> Self { Self { continued: "║", join_first: "╠", join_inner: "╠", join_last: "╚", join_only: "╚", branch: "═", leaf: "╼ ", multiline_first: None, multiline_continued: None, } } pub fn with_thick() -> Self { Self { continued: "┃", join_first: "┣", join_inner: "┣", join_last: "┗", join_only: "┗", branch: "━", leaf: "╼ ", multiline_first: None, multiline_continued: None, } } pub fn with_rounded() -> Self { Self { continued: "│", join_first: "├", join_inner: "├", join_last: "╰", join_only: "╰", branch: "─", leaf: "╼ ", multiline_first: None, multiline_continued: None, } } pub fn with_dashed() -> Self { Self { continued: "┊", join_first: "┊", join_inner: "┊", join_last: "'", join_only: "'", branch: "╌", leaf: "- ", multiline_first: None, multiline_continued: None, } } pub fn continued(mut self, sym: &'static str) -> Self { self.continued = sym; self } pub fn join_first(mut self, sym: &'static str) -> Self { self.join_first = sym; self } pub fn join_inner(mut self, sym: &'static str) -> Self { self.join_inner = sym; self } pub fn join_last(mut self, sym: &'static str) -> Self { self.join_last = sym; self } pub fn join_only(mut self, sym: &'static str) -> Self { self.join_only = sym; self } pub fn branch(mut self, sym: &'static str) -> Self { self.branch = sym; self } pub fn leaf(mut self, sym: &'static str) -> Self { self.leaf = sym; self } pub fn multiline_first(mut self, sym: &'static str) -> Self { self.multiline_first = Some(sym); self } pub fn multiline_continued(mut self, sym: &'static str) -> Self { self.multiline_continued = Some(sym); self } } impl TreeConfig { pub fn new() -> Self { Self { symbols: TreeSymbols::new(), indent: 2, show_first_level: false, } } pub fn with_symbols(symbols: TreeSymbols) -> Self { Self { symbols, indent: 2, show_first_level: false, } } pub fn indent(mut self, x: usize) -> Self { self.indent = x; self } pub fn show_first_level(mut self) -> Self { self.show_first_level = true; self } pub fn hide_first_level(mut self) -> Self { self.show_first_level = false; self } pub fn symbols(mut self, x: TreeSymbols) -> Self { self.symbols = x; self } } impl Default for TreeSymbols { fn default() -> Self { tree_config_symbols() } } impl Default for TreeConfig { fn default() -> Self { tree_config() } } static DEFAULT_CONFIG: Lazy>> = Lazy::new(|| -> Arc> { Arc::new(Mutex::new(TreeConfig::new())) }); /// Set the default tree config pub fn set_tree_config(x: TreeConfig) { *DEFAULT_CONFIG.lock().unwrap() = x; } /// The default tree config pub fn tree_config() -> TreeConfig { DEFAULT_CONFIG.lock().unwrap().clone() } /// Set the default tree symbols config pub fn set_tree_config_symbols(x: TreeSymbols) { DEFAULT_CONFIG.lock().unwrap().symbols = x; } /// The default tree symbols config pub fn tree_config_symbols() -> TreeSymbols { DEFAULT_CONFIG.lock().unwrap().symbols.clone() } /// The default tree symbols config pub fn update_tree_config(mut update: F) { let mut x = DEFAULT_CONFIG.lock().unwrap(); update(&mut x); } /// The default tree symbols config pub fn update_tree_config_symbols(mut update: F) { let mut x = DEFAULT_CONFIG.lock().unwrap(); update(&mut x.symbols); }