1use crate::Html;
2use crate::interface::Hooks;
3use crate::utils::{Element, ElementResult, document};
4use std::collections::BTreeMap;
5pub use std::fmt::{Result, Write};
6pub use std::sync::Arc;
7
8pub type Renderables = Vec<Arc<dyn Render>>;
10
11pub trait Render {
16 fn html(&self) -> String {
22 let mut buf = vec![];
23 self.render(&mut buf).unwrap();
24 buf.join("")
25 }
26 fn render_tree(self) -> ElementResult<Html>
30 where
31 Self: Sized,
32 {
33 let mut parent = document().create_element("div").unwrap();
34 let mut renderable = vec![];
36 let map = self.render_tree_into(&mut parent, &mut renderable)?;
38 let mut list = vec![];
39 let children = parent.children();
40 let len = children.length();
41 for index in 0..len {
42 if let Some(child) = children.get_with_index(index) {
43 list.push(child);
44 }
45 }
46
47 Html::new(list, map, renderable)
48 }
49 fn render_tree_into(
53 self,
54 parent: &mut Element,
55 renderables: &mut Renderables,
56 ) -> ElementResult<BTreeMap<String, Element>>
57 where
58 Self: Sized,
59 {
60 let mut map = BTreeMap::new();
61 self.render_node(parent, &mut map, renderables)?;
62 Ok(map)
63 }
64
65 fn render_node(
69 self,
70 _parent: &mut Element,
71 _map: &mut Hooks,
72 _renderables: &mut Renderables,
73 ) -> ElementResult<()>
74 where
75 Self: Sized,
76 {
77 Ok(())
78 }
79
80 fn render(&self, _w: &mut Vec<String>) -> ElementResult<()>;
82
83 fn remove_event_listeners(&self) -> ElementResult<()> {
86 Ok(())
87 }
88}
89
90impl Render for () {
93 fn render(&self, _w: &mut Vec<String>) -> ElementResult<()> {
94 Ok(())
95 }
96}
97
98impl Render for &str {
99 fn render(&self, w: &mut Vec<String>) -> ElementResult<()> {
100 w.push(self.to_string());
101 Ok(())
102 }
103 fn render_node(
104 self,
105 parent: &mut Element,
106 _map: &mut Hooks,
107 _renderables: &mut Renderables,
108 ) -> ElementResult<()> {
109 let el = document().create_text_node(self);
110 parent.append_child(&el)?;
111 Ok(())
112 }
113}
114
115impl<T: Render + Clone> Render for Vec<T> {
116 fn render(&self, list: &mut Vec<std::string::String>) -> ElementResult<()> {
117 for item in self {
118 item.render(list)?;
119 }
120 Ok(())
121 }
122
123 fn render_node(
124 self,
125 parent: &mut Element,
126 map: &mut Hooks,
127 renderables: &mut Renderables,
128 ) -> ElementResult<()> {
129 for item in self {
130 item.render_node(parent, map, renderables)?;
131 }
132 Ok(())
133 }
134}
135impl<T: Render + Clone> Render for Option<T> {
159 fn render_node(
160 self,
161 parent: &mut Element,
162 map: &mut Hooks,
163 renderables: &mut Renderables,
164 ) -> ElementResult<()> {
165 if let Some(h) = self {
166 h.render_node(parent, map, renderables)?;
167 }
168 Ok(())
169 }
170
171 fn render(&self, w: &mut Vec<String>) -> ElementResult<()> {
172 if let Some(h) = self {
173 h.render(w)?;
174 }
175 Ok(())
176 }
177}
178
179macro_rules! impl_tuple {
180 ($($ident:ident)+) => {
181 impl<$($ident: Render,)+> Render for ($($ident,)+) {
182 #[inline]
183 #[allow(non_snake_case)]
184 fn render(&self, w: &mut Vec<String>)->ElementResult<()>{
185 let ($($ident,)+) = self;
186 $($ident.render(w)?;)+
187 Ok(())
188 }
189 #[allow(non_snake_case)]
190 fn render_node(
191 self,
192 parent:&mut Element,
193 map:&mut Hooks,
194 renderables:&mut Renderables
195 )->ElementResult<()>{
196 let ($($ident,)+) = self;
197 $($ident.render_node(parent, map, renderables)?;)+
198 Ok(())
199 }
200 }
201 }
202}
203
204macro_rules! impl_types {
205 ($($ident:ident)+) => {
206 $(
207 impl Render for $ident {
208 fn render(&self, w: &mut Vec<String>)->ElementResult<()>{
209 w.push(format!("{}", self));
210 Ok(())
211 }
212 fn render_node(
213 self,
214 parent:&mut Element,
215 _map:&mut Hooks,
216 _renderables:&mut Renderables
217 )->ElementResult<()>{
218 let el = document().create_text_node(&format!("{}", self));
219 parent.append_child(&el)?;
220 Ok(())
221 }
222 }
223 )+
224 }
225}
226
227impl_types! {f32 f64 u128 u64 u32 u16 u8 i8 i16 i32 i64 i128 bool String usize}
228
229impl_tuple! {A B}
230impl_tuple! {A B C}
231impl_tuple! {A B C D}
232impl_tuple! {A B C D E}
233impl_tuple! {A B C D F G}
234impl_tuple! {A B C D F G H}
235impl_tuple! {A B C D F G H I}
236impl_tuple! {A B C D F G H I J}
237impl_tuple! {A B C D F G H I J K}