1use std::fmt::Formatter;
2
3pub trait Xml: Sized {
5 fn xml(&self) -> String {
7 self.display().to_string()
8 }
9
10 fn serialize_xml(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result;
12
13 fn display<'a>(&'a self) -> Display<'a, Self> {
15 Display(self)
16 }
17}
18
19impl<T: Xml> Xml for &T {
20 fn serialize_xml(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
21 T::serialize_xml(self, fmt)
22 }
23}
24
25impl<T: Xml> Xml for &mut T {
26 fn serialize_xml(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
27 T::serialize_xml(self, fmt)
28 }
29}
30
31impl<T: Xml> Xml for Box<T> {
32 fn serialize_xml(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
33 T::serialize_xml(self, fmt)
34 }
35}
36
37pub struct Display<'a, T>(&'a T);
38
39impl<'a, T: Xml> std::fmt::Display for Display<'a, T> {
40 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
41 T::serialize_xml(self.0, f)
42 }
43}
44
45pub struct Empty;
47
48impl Xml for Empty {
49 fn serialize_xml(&self, _fmt: &mut Formatter<'_>) -> std::fmt::Result {
50 Ok(())
51 }
52}
53
54pub struct Conditional<T>(pub Option<T>);
56
57impl<T: Xml> Xml for Conditional<T> {
58 fn serialize_xml(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
59 match self.0.as_ref() {
60 Some(some) => some.serialize_xml(fmt),
61 None => Ok(()),
62 }
63 }
64}
65
66pub struct List<T>(pub Vec<T>);
68
69impl<T> Xml for List<T>
70where
71 T: Xml,
72{
73 fn serialize_xml(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
74 for item in self.0.iter() {
75 item.serialize_xml(fmt)?;
76 }
77 Ok(())
78 }
79}