microcad_lang/
tree_display.rs1pub trait TreeDisplay {
8 fn tree_print(&self, f: &mut std::fmt::Formatter, depth: TreeState) -> std::fmt::Result;
11
12 fn print_tree(&self, f: &mut std::fmt::Formatter, shorten: bool) -> std::fmt::Result {
14 self.tree_print(f, TreeState { depth: 0, shorten })
15 }
16
17 fn write_tree(&self, f: &mut impl std::io::Write) -> std::io::Result<()> {
19 write!(f, "{}", WriteFmt(|f| self.print_tree(f, false)))
20 }
21}
22
23struct WriteFmt<F>(pub F)
25where
26 F: Fn(&mut std::fmt::Formatter<'_>) -> std::fmt::Result;
27
28impl<F> std::fmt::Display for WriteFmt<F>
29where
30 F: Fn(&mut std::fmt::Formatter<'_>) -> std::fmt::Result,
31{
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 self.0(f)
34 }
35}
36
37const INDENT: usize = 2;
39
40#[derive(derive_more::Deref, Clone, Copy)]
42pub struct TreeState {
43 #[deref]
44 depth: usize,
45 pub shorten: bool,
47}
48
49impl TreeState {
50 pub fn new(shorten: bool) -> Self {
53 Self { depth: 0, shorten }
54 }
55
56 pub fn indent(&mut self) {
58 self.depth += INDENT
59 }
60
61 pub fn indented(&self) -> Self {
63 Self {
64 depth: self.depth + INDENT,
65 shorten: self.shorten,
66 }
67 }
68}
69
70impl From<usize> for TreeState {
71 fn from(depth: usize) -> Self {
72 TreeState {
73 depth,
74 shorten: true,
75 }
76 }
77}
78
79pub struct FormatTree<'a, T: TreeDisplay>(pub &'a T);
81
82impl<T: TreeDisplay> std::fmt::Display for FormatTree<'_, T> {
83 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84 self.0.tree_print(f, 2.into())
85 }
86}