1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use std::fmt::{self, Display, Formatter};
use super::*;
const INDENT: usize = 4;
struct IndentedXml<'a>(&'a Xml, usize);
struct IndentedTag<'a>(&'a Tag, usize);
struct IndentedContent<'a>(&'a Content, usize);
impl Display for IndentedXml<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let Self(x, ind) = self;
let ind2 = ind + INDENT;
x.0.iter().try_for_each(|x| write!(f, "{}", IndentedContent(x, ind2)))
}
}
impl Display for IndentedTag<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let Self(tag, ind) = self;
let ind2 = ind + INDENT;
let n = &tag.name;
write!(f, "{:ind$}<{n}", "")?;
tag.args.iter().try_for_each(|a| write!(f, " {a}"))?;
match tag.inner.as_ref().map_or(&[] as &[Content], |x| &x.0[..]) {
&[] => write!(f, " />"),
&[ref x] => {
let sep = match x {
Content::Tag(_) => true,
Content::Nested(_) => true,
Content::Word(_) => false,
};
if sep {
writeln!(f ,">")?;
writeln!(f, "{}", IndentedContent(x, ind2))?;
write!(f, "{:ind$}</{n}>", "")
} else {
write!(f, ">{x}</{n}>")
}
},
data => {
writeln!(f, ">")?;
data.iter().try_for_each(|x| writeln!(f, "{}", IndentedContent(x, ind2)))?;
write!(f, "{:ind$}</{n}>", "")
}
}
}
}
impl Display for IndentedContent<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let Self(x, ind) = self;
match x {
Content::Tag(t) => write!(f, "{}", IndentedTag(t, *ind)),
Content::Word(w) => write!(f, "{:ind$}{}", "", w),
Content::Nested(x) => write!(f, "{}", IndentedXml(x, *ind - INDENT)),
}
}
}
impl Display for Xml {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.0.iter().try_for_each(|x| write!(f, "{x}"))
}
}
impl Display for Tag {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", IndentedTag(self, 0))
}
}
impl Display for Arg {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}=\"{}\"", self.name, self.value)
}
}
impl Display for Content {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::Tag(t) => write!(f, "{t}"),
Self::Word(w) => write!(f, "{w}"),
Self::Nested(x) => write!(f, "{}", IndentedXml(x, 0)),
}
}
}