1use crate::interface::Hooks;
2use crate::utils::{document, Element, ElementResult};
3use crate::Html;
4use std::collections::BTreeMap;
5pub use std::fmt::{Result, Write};
6pub use std::sync::Arc;
7
8pub type Renderables = Vec<Arc<dyn Render>>;
9
10pub trait Render {
13 fn html(&self) -> String {
18 let mut buf = vec![];
19 self.render(&mut buf).unwrap();
20 buf.join("")
21 }
22 fn render_tree(self) -> ElementResult<Html>
24 where
25 Self: Sized,
26 {
27 let mut parent = document().create_element("div").unwrap();
28 let mut renderable = vec![];
30 let map = self.render_tree_into(&mut parent, &mut renderable)?;
32 let mut list = vec![];
33 let children = parent.children();
34 let len = children.length();
35 for index in 0..len {
36 if let Some(child) = children.get_with_index(index) {
37 list.push(child);
38 }
39 }
40
41 Html::new(list, map, renderable)
42 }
43 fn render_tree_into(
44 self,
45 parent: &mut Element,
46 renderables: &mut Renderables,
47 ) -> ElementResult<BTreeMap<String, Element>>
48 where
49 Self: Sized,
50 {
51 let mut map = BTreeMap::new();
52 self.render_node(parent, &mut map, renderables)?;
53 Ok(map)
54 }
55
56 fn render_node(
57 self,
58 _parent: &mut Element,
59 _map: &mut Hooks,
60 _renderables: &mut Renderables,
61 ) -> ElementResult<()>
62 where
63 Self: Sized,
64 {
65 Ok(())
66 }
67
68 fn render(&self, _w: &mut Vec<String>) -> ElementResult<()>;
69
70 fn remove_event_listeners(&self) -> ElementResult<()> {
71 Ok(())
72 }
73}
74
75impl Render for () {
78 fn render(&self, _w: &mut Vec<String>) -> ElementResult<()> {
79 Ok(())
80 }
81}
82
83impl Render for &str {
84 fn render(&self, w: &mut Vec<String>) -> ElementResult<()> {
85 w.push(self.to_string());
86 Ok(())
87 }
88 fn render_node(
89 self,
90 parent: &mut Element,
91 _map: &mut Hooks,
92 _renderables: &mut Renderables,
93 ) -> ElementResult<()> {
94 let el = document().create_text_node(self);
95 parent.append_child(&el)?;
96 Ok(())
97 }
98}
99
100impl<T: Render + Clone> Render for Vec<T> {
101 fn render(&self, list: &mut Vec<std::string::String>) -> ElementResult<()> {
102 for item in self {
103 item.render(list)?;
104 }
105 Ok(())
106 }
107
108 fn render_node(
109 self,
110 parent: &mut Element,
111 map: &mut Hooks,
112 renderables: &mut Renderables,
113 ) -> ElementResult<()> {
114 for item in self {
115 item.render_node(parent, map, renderables)?;
116 }
117 Ok(())
118 }
119}
120impl<T: Render + Clone> Render for Option<T> {
144 fn render_node(
145 self,
146 parent: &mut Element,
147 map: &mut Hooks,
148 renderables: &mut Renderables,
149 ) -> ElementResult<()> {
150 if let Some(h) = self {
151 h.render_node(parent, map, renderables)?;
152 }
153 Ok(())
154 }
155
156 fn render(&self, w: &mut Vec<String>) -> ElementResult<()> {
157 if let Some(h) = self {
158 h.render(w)?;
159 }
160 Ok(())
161 }
162}
163
164macro_rules! impl_tuple {
165 ($($ident:ident)+) => {
166 impl<$($ident: Render,)+> Render for ($($ident,)+) {
167 #[inline]
168 #[allow(non_snake_case)]
169 fn render(&self, w: &mut Vec<String>)->ElementResult<()>{
170 let ($($ident,)+) = self;
171 $($ident.render(w)?;)+
172 Ok(())
173 }
174 #[allow(non_snake_case)]
175 fn render_node(
176 self,
177 parent:&mut Element,
178 map:&mut Hooks,
179 renderables:&mut Renderables
180 )->ElementResult<()>{
181 let ($($ident,)+) = self;
182 $($ident.render_node(parent, map, renderables)?;)+
183 Ok(())
184 }
185 }
186 }
187}
188
189macro_rules! impl_types {
190 ($($ident:ident)+) => {
191 $(
192 impl Render for $ident {
193 fn render(&self, w: &mut Vec<String>)->ElementResult<()>{
194 w.push(format!("{}", self));
195 Ok(())
196 }
197 fn render_node(
198 self,
199 parent:&mut Element,
200 _map:&mut Hooks,
201 _renderables:&mut Renderables
202 )->ElementResult<()>{
203 let el = document().create_text_node(&format!("{}", self));
204 parent.append_child(&el)?;
205 Ok(())
206 }
207 }
208 )+
209 }
210}
211
212impl_types! {f32 f64 u128 u64 u32 u16 u8 i8 i16 i32 i64 i128 bool String usize}
213
214impl_tuple! {A B}
215impl_tuple! {A B C}
216impl_tuple! {A B C D}
217impl_tuple! {A B C D E}
218impl_tuple! {A B C D F G}
219impl_tuple! {A B C D F G H}
220impl_tuple! {A B C D F G H I}
221impl_tuple! {A B C D F G H I J}
222impl_tuple! {A B C D F G H I J K}