tide_jsx/
simple_element.rs

1use crate::html_escaping::escape_html;
2use crate::Render;
3use std::borrow::Cow;
4use std::collections::HashMap;
5use std::fmt::{Result, Write};
6
7type Attributes<'a> = Option<HashMap<&'a str, Cow<'a, str>>>;
8
9/// Simple HTML element tag
10#[derive(Debug)]
11pub struct SimpleElement<'a, T: Render> {
12    /// the HTML tag name, like `html`, `head`, `body`, `link`...
13    pub tag_name: &'a str,
14    pub attributes: Attributes<'a>,
15    pub contents: Option<T>,
16}
17
18fn write_attributes<'a, W: Write>(maybe_attributes: Attributes<'a>, writer: &mut W) -> Result {
19    match maybe_attributes {
20        None => Ok(()),
21        Some(mut attributes) => {
22            for (key, value) in attributes.drain() {
23                write!(writer, " {}=\"", key)?;
24                escape_html(&value, writer)?;
25                write!(writer, "\"")?;
26            }
27            Ok(())
28        }
29    }
30}
31
32impl<T: Render> Render for SimpleElement<'_, T> {
33    fn render_into<W: Write>(self, writer: &mut W) -> Result {
34        match self.contents {
35            None => {
36                write!(writer, "<{}", self.tag_name)?;
37                write_attributes(self.attributes, writer)?;
38                write!(writer, "/>")
39            }
40            Some(renderable) => {
41                write!(writer, "<{}", self.tag_name)?;
42                write_attributes(self.attributes, writer)?;
43                write!(writer, ">")?;
44                renderable.render_into(writer)?;
45                write!(writer, "</{}>", self.tag_name)
46            }
47        }
48    }
49}