1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
pub use view::*;

pub struct VNode {
    pub vnode_type: &'static str,
    pub children: Vec<VNode>,
    pub classes: Vec<String>,
    pub text: Option<String>,
}

impl VNode {
    pub fn add_class(&mut self, c: &str) {
        self.classes.push(c.to_string())
    }

    pub fn add_view_child(&mut self, child: VNode) {
        self.children.push(child);
    }

    pub fn render_to_string(&self) -> String {
        if let Some(t) = &self.text {
            t.clone()
        } else {
            format!(
                "<{} class=\"{}\">{}</{}>",
                self.vnode_type,
                self.classes.join(","),
                self.children
                    .iter()
                    .map(|c| c.render_to_string())
                    .collect::<Vec<String>>()
                    .join(""),
                self.vnode_type
            )
        }
    }
}

pub type Div = VNode;

impl Default for Div {
    fn default() -> Self {
        VNode {
            vnode_type: "div",
            children: vec![],
            classes: vec![],
            text: None,
        }
    }
}

pub type Text = VNode;

impl Text {
    pub fn new(t: &str) -> Self {
        VNode {
            vnode_type: "text",
            children: vec![],
            classes: vec![],
            text: Some(t.to_string()),
        }
    }
}