pretty_print/tree/
display.rs

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