1use std::fmt::Write;
2
3use crate::{HtmlEnv, Empty, Sum};
4
5
6pub trait Html {
8 fn is_unit(&self) -> bool {
10 false
11 }
12 fn write_html(self, env: &mut impl HtmlEnv) -> std::fmt::Result;
27}
28
29impl Html for Empty {
30 fn is_unit(&self) -> bool {
31 true
32 }
33 fn write_html(self, _env: &mut impl HtmlEnv) -> std::fmt::Result {
34 Ok(())
35 }
36}
37
38impl<A: Html, B: Html> Html for Sum<A, B> {
39 fn write_html(self, env: &mut impl HtmlEnv) -> std::fmt::Result {
40 self.0.write_html(env)?;
41 self.1.write_html(env)?;
42 Ok(())
43 }
44}
45
46impl<I: Iterator> Html for I
56where
57 I::Item: Html,
58{
59 fn write_html(self, env: &mut impl HtmlEnv) -> std::fmt::Result {
60 for h in self {
61 h.write_html(env)?;
62 }
63 Ok(())
64 }
65}
66
67pub struct HtmlStr<S>(pub S);
83
84impl<S> Html for HtmlStr<S>
85where
86 S: AsRef<str>,
87{
88 fn write_html(self, env: &mut impl HtmlEnv) -> std::fmt::Result {
89 env.write_str(self.0.as_ref())
90 }
91}
92
93pub struct HtmlTextStr<S>(pub S);
97
98impl<S> Html for HtmlTextStr<S>
99where
100 S: AsRef<str>,
101{
102 fn write_html(self, env: &mut impl HtmlEnv) -> std::fmt::Result {
103 env.write_html_text().write_str(self.0.as_ref())
104 }
105}
106
107pub trait AsHtml {
111 type Html: Html;
113 type HtmlText: Html;
115 fn as_html(self) -> Self::Html;
117 fn as_html_text(self) -> Self::HtmlText;
119}
120
121impl<'a> AsHtml for &'a str {
122 type Html = HtmlStr<&'a str>;
123 type HtmlText = HtmlTextStr<&'a str>;
124 fn as_html(self) -> Self::Html {
125 HtmlStr(self)
126 }
127 fn as_html_text(self) -> Self::HtmlText {
128 HtmlTextStr(self)
129 }
130}
131
132impl AsHtml for String {
133 type Html = HtmlStr<String>;
134 type HtmlText = HtmlTextStr<String>;
135 fn as_html(self) -> Self::Html {
136 HtmlStr(self)
137 }
138 fn as_html_text(self) -> Self::HtmlText {
139 HtmlTextStr(self)
140 }
141}
142
143pub trait ToHtmlString {
145 fn to_html_string(self) -> Result<String, std::fmt::Error>;
147}
148
149impl<H: Html> ToHtmlString for H {
150 fn to_html_string(self) -> Result<String, std::fmt::Error> {
151 let mut s = String::new();
152 self.write_html(&mut s)?;
153 Ok(s)
154 }
155}