write_html/
html_trait.rs

1use std::fmt::Write;
2
3use crate::{HtmlEnv, Empty, Sum};
4
5
6/// Represents a content that can be written to a `Write` as HTML.
7pub trait Html {
8    /// Tells whether `self` is a unit value, meaning that it is not written.
9    fn is_unit(&self) -> bool {
10        false
11    }
12    /// Writes the HTML representation of `self` to `w`.
13    ///
14    /// # Arguments
15    /// * `env` - The environment to write to.
16    ///
17    /// # Example
18    /// ```
19    /// use write_html::{Html, HtmlEnv, AsHtml};
20    /// use std::fmt::Write;
21    /// 
22    /// let mut s = String::new();
23    /// "<h1>H1</h1>".as_html().write_html(&mut s).unwrap();
24    /// assert_eq!(s, "<h1>H1</h1>");
25    /// ```
26    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
46/*impl Html for () {
47    fn is_unit(&self) -> bool {
48        true
49    }
50    fn write_html(self, _env: &mut impl HtmlEnv) -> std::fmt::Result {
51        Ok(())
52    }
53}*/
54
55impl<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
67//impl<I: IntoIterator> Html for I
68//where
69//    I::Item: Html,
70//{
71//    fn write_html(self, env: &mut impl HtmlEnv) -> std::fmt::Result {
72//        for h in self {
73//            h.write_html(env)?;
74//        }
75//        Ok(())
76//    }
77//}
78
79/// Html string
80///
81/// TODO better doc
82pub 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
93/// Html text string
94///
95/// TODO better doc
96pub 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
107/// Something that can be converted into HTML.
108///
109/// TODO better doc
110pub trait AsHtml {
111    /// The HTML type.
112    type Html: Html;
113    /// The HTML text type.
114    type HtmlText: Html;
115    /// Converts `self` into HTML.
116    fn as_html(self) -> Self::Html;
117    /// Converts `self` into HTML text.
118    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
143/// Something that can be converted into an HTML string.
144pub trait ToHtmlString {
145    /// Converts `self` into an HTML string.
146    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}