use std::fmt::Display;
#[derive(Debug)]
struct Token {
siblings: bool,
children: bool,
}
impl Display for Token {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let Token { siblings, children } = self;
write!(
f,
"{}",
match (siblings, children) {
(true, true) => "│ ",
(true, false) => "├── ",
(false, true) => " ",
(false, false) => "└── ",
}
)
}
}
impl Token {
fn new(siblings: bool) -> Self {
Token {
siblings,
children: false,
}
}
fn set_children(&mut self) {
self.children = true;
}
}
#[derive(Debug)]
pub struct Indentation {
tokens: Vec<Token>,
ignore_root: bool,
}
impl Display for Indentation {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let first: usize = if self.ignore_root { 1 } else { 0 };
for token in &self.tokens[first..] {
write!(f, "{token}")?;
}
Ok(())
}
}
impl Indentation {
pub fn new(ignore_root: bool) -> Self {
Indentation {
tokens: Vec::new(),
ignore_root,
}
}
pub fn indent(&mut self, siblings: bool) -> &mut Self {
let len = self.tokens.len();
if len > 0 {
self.tokens[len - 1].set_children();
}
self.tokens.push(Token::new(siblings));
self
}
pub fn deindent(&mut self) -> &mut Self {
self.tokens.pop();
self
}
}