usecrate::tree_config::{tree_config, TreeConfig}; use std::cmp::max; use std::sync::{Arc, Mutex};
/// Tree that holds `text` for the current leaf and a list of `children` that are the branches. #[derive(Debug)] pubstruct Tree { pub text: Option<String>, pub children: Vec<Tree>,
}
/// Position of the element relative to its siblings #[derive(Copy, Clone, Debug, Eq, PartialEq)] pubenum Position {
Inside,
First,
Last,
Only,
}
impl Tree { /// Create a new tree with some optional text. pubfn new(text: Option<&str>) -> Tree {
Tree {
text: text.map(|x| x.to_string()),
children: Vec::new(),
}
}
/// Navigate to the branch at the given `path` relative to this tree. /// If a valid branch is found by following the path, it is returned. pubfn at_mut(&mutself, path: &[usize]) -> Option<&mut Tree> { match path.first() {
Some(&i) => matchself.children.get_mut(i) {
Some(x) => x.at_mut(&path[1..]),
_ => None,
},
_ => Some(self),
}
}
/// "Render" this tree as a list of `String`s. /// Each string represents a line in the tree. /// `does_continue` is a bool for each column indicating whether the tree continues. pubfn lines(
&self,
does_continue: &Vec<bool>,
index: usize,
pool_size: usize,
config: &TreeConfig,
) -> Vec<String> { let does_continue = if config.show_first_level && does_continue.is_empty() {
vec![true]
} else {
does_continue.clone()
}; let position = match index {
_ if pool_size == 1 => Position::Only,
_ if (index + 1) == pool_size => Position::Last, 0 => Position::First,
_ => Position::Inside,
}; letmut next_continue = does_continue.clone();
next_continue.push(match position {
Position::Inside | Position::First => true,
Position::Last | Position::Only => false,
});
letmut txt = String::new(); let pad: String; if does_continue.len() > 1 { for &i in &does_continue[2..] {
txt.push_str(&format!( "{}{:indent$}", if i { config.symbols.continued } else { " " }, "",
indent = max(config.indent, 1) - 1
));
}
pad = txt.clone(); let branch_size = max(config.indent, 2usize) - 2; let branch = match config.symbols.branch.len() { 0 => "-".repeat(branch_size), 1 => config.symbols.branch.repeat(branch_size),
_n => config
.symbols
.branch
.repeat(branch_size)
.chars()
.take(branch_size)
.collect::<String>(),
};
let is_multiline = self
.text
.as_ref()
.map(|x| x.contains("\n"))
.unwrap_or(false);
let first_leaf = match (is_multiline, config.symbols.multiline_first) {
(true, Some(x)) => x,
_ => config.symbols.leaf,
};
txt.push_str(&format!( "{}{}{}", match position {
Position::Only => config.symbols.join_only,
Position::First => config.symbols.join_first,
Position::Last => config.symbols.join_last,
Position::Inside => config.symbols.join_inner,
},
branch,
first_leaf,
));
let s = match &self.text {
Some(x) => match is_multiline { true => format!( "{}",
x.replace( "\n",
&format!( "\n{}{}{}{}",
&pad, match position {
Position::Only | Position::Last => " ".repeat(config.symbols.continued.chars().count()),
_ => config.symbols.continued.to_string(),
}, " ".repeat(branch_size), match &config.symbols.multiline_continued {
Some(multi) => multi.to_string(),
_ => " ".repeat(first_leaf.chars().count()),
}
),
)
), false => x.clone(),
},
_ => String::new(),
};
txt.push_str(&s);
} else { iflet Some(x) = &self.text {
txt.push_str(&x);
}
} letmut ret = vec![txt]; for (index, x) inself.children.iter().enumerate() { for line in x.lines(&next_continue, index, self.children.len(), config) {
ret.push(line);
}
}
ret
}
}
/// Holds the current state of the tree, including the path to the branch. /// Multiple trees may point to the same data. #[derive(Debug, Clone)] pub(crate) struct TreeBuilderBase {
data: Arc<Mutex<Tree>>,
path: Vec<usize>,
dive_count: usize,
config: Option<TreeConfig>,
is_enabled: bool,
}
impl TreeBuilderBase { /// Create a new state pubfn new() -> TreeBuilderBase {
TreeBuilderBase {
data: Arc::new(Mutex::new(Tree::new(None))),
path: vec![],
dive_count: 1,
config: None,
is_enabled: true,
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.