tide_jsx/
render.rs

1use std::fmt::{Result, Write};
2
3/// Render a component
4///
5/// This is the underlying mechanism of the `#[component]` macro
6pub trait Render: Sized {
7    /// Render the component to a writer.
8    /// Make sure you escape html correctly using the `render::html_escaping` module
9    fn render_into<W: Write>(self, writer: &mut W) -> Result;
10
11    /// Render the component to string
12    fn render(self) -> String {
13        let mut buf = String::new();
14        self.render_into(&mut buf).unwrap();
15        buf
16    }
17}
18
19/// Does nothing
20impl Render for () {
21    fn render_into<W: Write>(self, _writer: &mut W) -> Result {
22        Ok(())
23    }
24}
25
26/// Renders `A`, then `B`
27impl<A: Render, B: Render> Render for (A, B) {
28    fn render_into<W: Write>(self, writer: &mut W) -> Result {
29        self.0.render_into(writer)?;
30        self.1.render_into(writer)
31    }
32}
33
34/// Renders `A`, then `B`, then `C`
35impl<A: Render, B: Render, C: Render> Render for (A, B, C) {
36    fn render_into<W: Write>(self, writer: &mut W) -> Result {
37        self.0.render_into(writer)?;
38        self.1.render_into(writer)?;
39        self.2.render_into(writer)
40    }
41}
42
43/// Renders `T` or nothing
44impl<T: Render> Render for Option<T> {
45    fn render_into<W: Write>(self, writer: &mut W) -> Result {
46        match self {
47            None => Ok(()),
48            Some(x) => x.render_into(writer),
49        }
50    }
51}
52
53impl<T: Render> Render for Vec<T> {
54    fn render_into<W: Write>(self, writer: &mut W) -> Result {
55        for elem in self {
56            elem.render_into(writer)?;
57        }
58        Ok(())
59    }
60}
61
62/// Renders `O` or `E`
63impl<O: Render, E: Render> Render for std::result::Result<O, E> {
64    fn render_into<W: Write>(self, writer: &mut W) -> Result {
65        match self {
66            Ok(o) => o.render_into(writer),
67            Err(e) => e.render_into(writer),
68        }
69    }
70}