1
use std::fmt;
2

            
3
/// A struct that can be used to pretty print the parse tree obtained from the [pest] crate.
4
pub struct DisplayPair<'i, R: pest::RuleType>(pub pest::iterators::Pair<'i, R>);
5

            
6
impl<R: pest::RuleType> fmt::Display for DisplayPair<'_, R> {
7
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8
        self.display(f, 0)
9
    }
10
}
11

            
12
impl<R: pest::RuleType> DisplayPair<'_, R> {
13
    fn display(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
14
        let span = self.0.clone().as_span();
15
        let rule = self.0.as_rule();
16
        let inner = self.0.clone().into_inner();
17
        let indent = "  ".repeat(depth);
18
        let children_possible = if let Some(len) = inner.size_hint().1 {
19
            len > 0
20
        } else {
21
            true
22
        };
23

            
24
        write!(
25
            f,
26
            "{}{:?}({}, {}, \"{}\"",
27
            indent,
28
            rule,
29
            span.start_pos().pos(),
30
            span.end_pos().pos(),
31
            span.as_str()
32
        )?;
33
        if children_possible {
34
            writeln!(f, ", [")?;
35
            for pair in self.0.clone().into_inner() {
36
                DisplayPair(pair).display(f, depth + 1)?;
37
            }
38
            write!(f, "{indent}]),")?;
39
        } else {
40
            write!(f, ")")?;
41
        }
42

            
43
        if depth > 0 {
44
            writeln!(f)?;
45
        }
46

            
47
        Ok(())
48
    }
49
}