ziyy_core/resolver/document/
display.rs

1use std::fmt::Display;
2
3/// Indentation token
4#[derive(Debug)]
5struct Token {
6    /// Is followed by a brother
7    siblings: bool,
8    /// Is intermediate while printing children
9    children: bool,
10}
11
12impl Display for Token {
13    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
14        let Token { siblings, children } = self;
15
16        write!(
17            f,
18            "{}",
19            match (siblings, children) {
20                (true, true) => "│   ",
21                (true, false) => "├── ",
22                (false, true) => "    ",
23                (false, false) => "└── ",
24            }
25        )
26    }
27}
28
29impl Token {
30    /// Create a new indentation token
31    fn new(siblings: bool) -> Self {
32        Token {
33            siblings,
34            children: false,
35        }
36    }
37
38    /// Set children flag before starting displaying children
39    fn set_children(&mut self) {
40        self.children = true;
41    }
42}
43
44/// Manages the state during the display operation
45#[derive(Debug)]
46pub struct Indentation {
47    tokens: Vec<Token>,
48    ignore_root: bool,
49}
50
51impl Display for Indentation {
52    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
53        let first: usize = if self.ignore_root { 1 } else { 0 };
54
55        for token in &self.tokens[first..] {
56            write!(f, "{token}")?;
57        }
58
59        Ok(())
60    }
61}
62
63impl Indentation {
64    /// Creates a new indentation handler
65    pub fn new(ignore_root: bool) -> Self {
66        Indentation {
67            tokens: Vec::new(),
68            ignore_root,
69        }
70    }
71
72    /// Adds a new layer of indentation
73    pub fn indent(&mut self, siblings: bool) -> &mut Self {
74        // Setup children mode for previous tokens
75        let len = self.tokens.len();
76        if len > 0 {
77            self.tokens[len - 1].set_children();
78        }
79
80        self.tokens.push(Token::new(siblings));
81        self
82    }
83
84    /// Removes the last layer of indentation
85    pub fn deindent(&mut self) -> &mut Self {
86        self.tokens.pop();
87        self
88    }
89}