virtual_node/
iterable_nodes.rs

1use crate::{View, VirtualNode};
2
3/// Used by the html! macro for all braced child nodes so that we can use any type
4/// that implements Into<IterableNodes>
5///
6/// html! { <div> { nodes } </div> }
7///
8/// nodes can be a String .. VirtualNode .. Vec<VirtualNode> ... etc
9pub struct IterableNodes(Vec<VirtualNode>);
10
11impl IterableNodes {
12    /// Retrieve the first node mutably
13    pub fn first_mut(&mut self) -> Option<&mut VirtualNode> {
14        self.0.first_mut()
15    }
16
17    /// Retrieve the last node mutably
18    pub fn last_mut(&mut self) -> Option<&mut VirtualNode> {
19        self.0.last_mut()
20    }
21}
22
23impl IntoIterator for IterableNodes {
24    type Item = VirtualNode;
25    // TODO: Is this possible with an array [VirtualNode] instead of a vec?
26    type IntoIter = ::std::vec::IntoIter<VirtualNode>;
27
28    fn into_iter(self) -> Self::IntoIter {
29        self.0.into_iter()
30    }
31}
32
33impl From<VirtualNode> for IterableNodes {
34    fn from(other: VirtualNode) -> Self {
35        IterableNodes(vec![other])
36    }
37}
38
39impl From<&str> for IterableNodes {
40    fn from(other: &str) -> Self {
41        IterableNodes(vec![VirtualNode::text(other)])
42    }
43}
44
45impl From<String> for IterableNodes {
46    fn from(other: String) -> Self {
47        IterableNodes(vec![VirtualNode::text(other.as_str())])
48    }
49}
50
51impl From<&String> for IterableNodes {
52    fn from(other: &String) -> Self {
53        IterableNodes(vec![VirtualNode::text(other.as_str())])
54    }
55}
56
57impl From<Vec<VirtualNode>> for IterableNodes {
58    fn from(other: Vec<VirtualNode>) -> Self {
59        IterableNodes(other)
60    }
61}
62
63impl<V: View> From<V> for IterableNodes {
64    fn from(from: V) -> Self {
65        IterableNodes(vec![from.render()])
66    }
67}
68
69impl<T: Into<IterableNodes>> From<Option<T>> for IterableNodes {
70    fn from(opt: Option<T>) -> Self {
71        if let Some(val) = opt {
72            val.into()
73        } else {
74            IterableNodes(vec![])
75        }
76    }
77}
78
79impl<V: View> From<Vec<V>> for IterableNodes {
80    fn from(other: Vec<V>) -> Self {
81        IterableNodes(other.into_iter().map(|it| it.render()).collect())
82    }
83}
84
85impl<V: View> From<&Vec<V>> for IterableNodes {
86    fn from(other: &Vec<V>) -> Self {
87        IterableNodes(other.iter().map(|it| it.render()).collect())
88    }
89}
90
91impl<V: View> From<&[V]> for IterableNodes {
92    fn from(other: &[V]) -> Self {
93        IterableNodes(other.iter().map(|it| it.render()).collect())
94    }
95}
96
97// Implements
98//   From<T> and From<&T> -> IterableNodes
99//   by using T's Display implementation.
100macro_rules! from_display_impls {
101    ($ty:ty) => {
102        impl From<$ty> for IterableNodes {
103            fn from(val: $ty) -> Self {
104                IterableNodes::from(val.to_string())
105            }
106        }
107
108        impl From<&$ty> for IterableNodes {
109            fn from(val: &$ty) -> Self {
110                IterableNodes::from(val.to_string())
111            }
112        }
113    };
114
115    ($ty:ty, $($tys:ty),*) => {
116        from_display_impls!( $ty );
117        from_display_impls! ( $($tys),* );
118    }
119}
120from_display_impls!(u8, u16, u32, usize, u64, u128, i8, i16, i32, isize, i64, i128, f32, f64);