Skip to main content

logparse_pretty_print/tree/
display.rs

1use super::*;
2
3impl<'a, T: Clone> Clone for PrettyTree<'a, T> {
4    fn clone(&self) -> Self {
5        match self {
6            Self::Nil => Self::Nil,
7            Self::Hardline => Self::Hardline,
8            Self::Text(s) => Self::Text(s.clone()),
9            Self::Annotated { style: color, body: doc } => Self::Annotated { style: color.clone(), body: doc.clone() },
10            Self::Append { lhs, rhs } => Self::Append { lhs: lhs.clone(), rhs: rhs.clone() },
11            Self::Group { items } => Self::Group { items: items.clone() },
12            Self::MaybeInline { block, inline } => Self::MaybeInline { block: block.clone(), inline: inline.clone() },
13            Self::Nest { space, doc } => Self::Nest { space: *space, doc: doc.clone() },
14            Self::RenderLength { length: len, body: doc } => Self::RenderLength { length: *len, body: doc.clone() },
15            Self::Union { lhs: left, rhs: right } => Self::Union { lhs: left.clone(), rhs: right.clone() },
16            Self::Column { invoke: column } => Self::Column { invoke: column.clone() },
17            Self::Nesting { invoke: nesting } => Self::Nesting { invoke: nesting.clone() },
18            Self::Fail => Self::Fail,
19        }
20    }
21}
22
23impl<'a, T> Debug for PrettyTree<'a, T>
24where
25    T: Text<'a> + Debug,
26{
27    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
28        let is_line = |doc: &PrettyTree<'a, T>| match doc {
29            PrettyTree::MaybeInline { block: flat, inline: alt } => {
30                matches!((&**flat, &**alt), (PrettyTree::Hardline, PrettyTree::Text(t)) if t.as_str() == " ")
31            }
32            _ => false,
33        };
34        let is_line_ = |doc: &PrettyTree<'a, T>| match doc {
35            PrettyTree::MaybeInline { block: flat, inline: alt } => {
36                matches!((&**flat, &**alt), (PrettyTree::Hardline, PrettyTree::Nil))
37            }
38            _ => false,
39        };
40        match self {
41            PrettyTree::Nil => f.debug_tuple("Nil").finish(),
42            PrettyTree::Append { lhs: _, rhs: _ } => {
43                let mut f = f.debug_list();
44                append_docs(self, &mut |doc| {
45                    f.entry(doc);
46                });
47                f.finish()
48            }
49            _ if is_line(self) => f.debug_tuple("Line").finish(),
50            _ if is_line_(self) => f.debug_tuple("Line?").finish(),
51            PrettyTree::MaybeInline { block, inline } => f.debug_tuple("FlatAlt").field(block).field(inline).finish(),
52            PrettyTree::Group { items } => {
53                if is_line(self) {
54                    return f.debug_tuple("SoftLine").finish();
55                }
56                if is_line_(self) {
57                    return f.debug_tuple("SoftLine?").finish();
58                }
59                f.debug_tuple("Group").field(items).finish()
60            }
61            PrettyTree::Nest { space, doc } => f.debug_tuple("Nest").field(&space).field(doc).finish(),
62            PrettyTree::Hardline => f.debug_tuple("Hardline").finish(),
63            PrettyTree::RenderLength { body: doc, .. } => doc.fmt(f),
64            PrettyTree::Text(s) => Debug::fmt(s, f),
65            PrettyTree::Annotated { style: color, body: doc } => f.debug_tuple("Annotated").field(color).field(doc).finish(),
66            PrettyTree::Union { lhs: left, rhs: right } => f.debug_tuple("Union").field(left).field(right).finish(),
67            PrettyTree::Column { .. } => f.debug_tuple("Column(..)").finish(),
68            PrettyTree::Nesting { .. } => f.debug_tuple("Nesting(..)").finish(),
69            PrettyTree::Fail => f.debug_tuple("Fail").finish(),
70        }
71    }
72}
73
74fn append_docs<'a, T>(mut doc: &PrettyTree<'a, T>, consumer: &mut impl FnMut(&PrettyTree<'a, T>)) {
75    loop {
76        match doc {
77            PrettyTree::Append { lhs, rhs } => {
78                append_docs(lhs, consumer);
79                doc = rhs;
80            }
81            _ => break consumer(doc),
82        }
83    }
84}