yew_vnode_struct/
vnode_struct.rs

1use std::collections::HashMap;
2use web_sys::{Element, Node};
3use yew::html::NodeRef;
4use yew::virtual_dom::{Classes, VComp, VList, VNode, VTag, VText};
5
6type Attributes = HashMap<String, String>;
7
8#[derive(Debug, PartialEq)]
9struct VTagStruct {
10    reference: Option<Element>,
11    attributes: Attributes,
12    classes: Classes,
13    value: Option<String>,
14    kind: Option<String>,
15    checked: bool,
16    node_ref: NodeRef,
17}
18
19impl From<VTag> for VTagStruct {
20    fn from(vtag: VTag) -> Self {
21        VTagStruct {
22            reference: vtag.reference,
23            attributes: vtag.attributes,
24            classes: vtag.classes,
25            value: vtag.value,
26            kind: vtag.kind,
27            checked: vtag.checked,
28            node_ref: vtag.node_ref,
29        }
30    }
31}
32
33/// All the properties of VNodeStruct
34#[derive(Debug, PartialEq)]
35pub struct VNodeStruct {
36    vtag: Option<VTagStruct>,
37    vlist: Option<VList>,
38    vtext: Option<VText>,
39    vcomp: Option<VComp>,
40    vref: Option<Node>,
41    children: Option<Vec<VNodeStruct>>,
42}
43
44impl VNodeStruct {
45    /// Get all the complete structure from VNode
46    pub fn new(vnode: VNode) -> Self {
47        match vnode {
48            VNode::VTag(ref vtag) => VNodeStruct {
49                vtag: Some(VTagStruct::from(*vtag.clone())),
50                vlist: None,
51                vtext: None,
52                vcomp: None,
53                vref: None,
54                children: if !vtag.children.is_empty() {
55                    Some(vec![VNodeStruct::new(VNode::VList(vtag.children.clone()))])
56                } else {
57                    None
58                },
59            },
60            VNode::VText(ref vtext) => VNodeStruct {
61                vtag: None,
62                vlist: None,
63                vtext: Some(VText {
64                    text: vtext.text.clone(),
65                    reference: vtext.reference.clone(),
66                }),
67                vcomp: None,
68                vref: None,
69                children: None,
70            },
71            VNode::VList(ref vlist) => VNodeStruct {
72                vtag: None,
73                vlist: Some(vlist.clone()),
74                vtext: None,
75                vcomp: None,
76                vref: None,
77                children: if !vlist.children.is_empty() {
78                    Some(
79                        vlist
80                            .children
81                            .clone()
82                            .into_iter()
83                            .map(VNodeStruct::new)
84                            .collect(),
85                    )
86                } else {
87                    None
88                },
89            },
90            VNode::VComp(ref vcomp) => VNodeStruct {
91                vtag: None,
92                vlist: None,
93                vtext: None,
94                vcomp: Some(vcomp.clone()),
95                vref: None,
96                children: None,
97            },
98            VNode::VRef(ref vref) => VNodeStruct {
99                vtag: None,
100                vlist: None,
101                vtext: None,
102                vcomp: None,
103                vref: Some(vref.clone()),
104                children: None,
105            },
106        }
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::VNodeStruct;
113    use yew::html;
114
115    #[test]
116    fn should_match_the_vnode_structures() {
117        let vnode = html! {
118            <div id="example">{"example"}</div>
119        };
120
121        let vnode_structure = VNodeStruct::new(vnode);
122
123        let vnode_expected = html! {
124            <div id="example">{"example"}</div>
125        };
126
127        let vnode_structure_expected = VNodeStruct::new(vnode_expected);
128
129        assert_eq!(vnode_structure, vnode_structure_expected);
130    }
131
132    #[test]
133    fn should_no_match_the_vnode_structures() {
134        let vnode = html! {
135            <div id="example">{"example"}</div>
136        };
137
138        let vnode_structure = VNodeStruct::new(vnode);
139
140        let vnode_expected = html! {
141            <div id="second-example">{"second example"}</div>
142        };
143
144        let vnode_structure_expected = VNodeStruct::new(vnode_expected);
145
146        assert_ne!(vnode_structure, vnode_structure_expected);
147    }
148}