1use crate::element::Element;
6use crate::render::RenderChunk;
7
8impl<E: Element + ?Sized> Element for &'_ E {
9 fn width(&self) -> usize {
10 (*self).width()
11 }
12
13 fn render(&self) -> impl DoubleEndedIterator<Item = RenderChunk<'_>> {
14 (*self).render()
15 }
16}
17
18impl<E: Element> Element for [E] {
19 fn width(&self) -> usize {
20 self.iter().map(|e| e.width()).sum()
21 }
22
23 fn render(&self) -> impl DoubleEndedIterator<Item = RenderChunk<'_>> {
24 self.iter().flat_map(|e| e.render())
25 }
26}
27
28impl<E: Element, const N: usize> Element for [E; N] {
29 fn width(&self) -> usize {
30 self.iter().map(|e| e.width()).sum()
31 }
32
33 fn render(&self) -> impl DoubleEndedIterator<Item = RenderChunk<'_>> {
34 self.iter().flat_map(|e| e.render())
35 }
36}
37
38impl<E: Element> Element for Option<E> {
39 fn width(&self) -> usize {
40 match self {
41 Some(inner) => inner.width(),
42 None => 0,
43 }
44 }
45
46 fn render(&self) -> impl DoubleEndedIterator<Item = RenderChunk<'_>> {
47 self.iter().flat_map(|e| e.render())
48 }
49}
50
51impl Element for () {
52 fn width(&self) -> usize {
53 0
54 }
55
56 fn render(&self) -> impl DoubleEndedIterator<Item = RenderChunk<'_>> {
57 std::iter::empty()
58 }
59}
60
61macro_rules! impl_element_for_tuple {
62 ( A $( $t:ident )* , 0 $( $n:tt )* ) => {
63 impl<A $(, $t)*> Element for (A, $($t),*)
64 where
65 A: Element,
66 $($t: Element,)*
67 {
68 fn width(&self) -> usize {
69 self.0.width()
70 $(+ self.$n.width())*
71 }
72
73 fn render(&self) -> impl DoubleEndedIterator<Item = RenderChunk<'_>> {
74 self.0.render()
75 $(.chain(self.$n.render()))*
76 }
77 }
78 };
79}
80
81impl_element_for_tuple!(A, 0);
82impl_element_for_tuple!(A B, 0 1);
83impl_element_for_tuple!(A B C, 0 1 2);
84impl_element_for_tuple!(A B C D, 0 1 2 3);
85impl_element_for_tuple!(A B C D E, 0 1 2 3 4);
86impl_element_for_tuple!(A B C D E F, 0 1 2 3 4 5);
87impl_element_for_tuple!(A B C D E F G, 0 1 2 3 4 5 6);
88impl_element_for_tuple!(A B C D E F G H, 0 1 2 3 4 5 6 7);
89impl_element_for_tuple!(A B C D E F G H I, 0 1 2 3 4 5 6 7 8);
90impl_element_for_tuple!(A B C D E F G H I J, 0 1 2 3 4 5 6 7 8 9);
91
92#[cfg(test)]
93mod tests {
94 use crate::element::Gap;
95
96 use super::*;
97
98 fn is_element<E: Element + ?Sized>() {}
99
100 #[test]
101 fn element_impls() {
102 is_element::<[Gap]>();
103 is_element::<&[Gap]>();
104 is_element::<[Gap; 42]>();
105 is_element::<[&[Gap]; 4]>();
106 is_element::<((), (), (), (), (), (), (), Gap, (), ())>();
107 }
108}