Skip to main content

topcoat_view/
node.rs

1use topcoat_core::context::Cx;
2
3use crate::{PartsWriter, Unescaped, View};
4
5/// Converts a value used in node position into view parts.
6///
7/// When this trait is implemented on a type, it can be used in the node position of an element
8/// in the [`view!`](https://docs.rs/topcoat/latest/topcoat/view/macro.view.html) macro:
9///
10/// ```rust
11/// # use topcoat::view::{component, view};
12/// # #[component]
13/// # async fn example() -> topcoat::Result {
14/// # let my_value = "value";
15/// view! {
16///     <div>(my_value)</div>
17/// }
18/// # }
19/// ```
20pub trait NodeViewParts {
21    /// Appends this value to the view being built.
22    fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>);
23}
24
25impl NodeViewParts for View {
26    #[inline]
27    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
28        parts.push_part(self.into_part());
29    }
30}
31
32macro_rules! impl_primitive {
33    ($ty:ty, $method:ident) => {
34        impl NodeViewParts for $ty {
35            #[inline]
36            fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
37                parts.$method(self);
38            }
39        }
40    };
41    ($ty:ty, $method:ident, ref) => {
42        impl_primitive!($ty, $method);
43
44        impl NodeViewParts for &$ty {
45            #[inline]
46            fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
47                (*self).into_view_parts(cx, parts)
48            }
49        }
50    };
51}
52
53impl_primitive!(bool, push_bool, ref);
54impl_primitive!(char, push_char, ref);
55impl_primitive!(i8, push_i8, ref);
56impl_primitive!(i16, push_i16, ref);
57impl_primitive!(i32, push_i32, ref);
58impl_primitive!(i64, push_i64, ref);
59impl_primitive!(i128, push_i128, ref);
60impl_primitive!(isize, push_isize, ref);
61impl_primitive!(u8, push_u8, ref);
62impl_primitive!(u16, push_u16, ref);
63impl_primitive!(u32, push_u32, ref);
64impl_primitive!(u64, push_u64, ref);
65impl_primitive!(u128, push_u128, ref);
66impl_primitive!(usize, push_usize, ref);
67impl_primitive!(f32, push_f32, ref);
68impl_primitive!(f64, push_f64, ref);
69impl_primitive!(String, push_str);
70
71impl NodeViewParts for &str {
72    #[inline]
73    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
74        parts.push_str(self.to_owned());
75    }
76}
77
78impl NodeViewParts for Unescaped<String> {
79    #[inline]
80    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
81        parts.push_str_unescaped(self.0);
82    }
83}
84
85impl NodeViewParts for Unescaped<&'static str> {
86    #[inline]
87    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
88        parts.push_str_unescaped(self.0);
89    }
90}
91
92impl NodeViewParts for &String {
93    #[inline]
94    fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
95        self.as_str().into_view_parts(cx, parts);
96    }
97}
98
99impl<'b, T: ?Sized> NodeViewParts for &&'b T
100where
101    &'b T: NodeViewParts,
102{
103    #[inline]
104    fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
105        (*self).into_view_parts(cx, parts);
106    }
107}
108
109impl<T> NodeViewParts for Option<T>
110where
111    T: NodeViewParts,
112{
113    #[inline]
114    fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
115        if let Some(value) = self {
116            value.into_view_parts(cx, parts);
117        }
118    }
119}
120
121impl<T> NodeViewParts for Vec<T>
122where
123    T: NodeViewParts,
124{
125    #[inline]
126    fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
127        for value in self {
128            value.into_view_parts(cx, parts);
129        }
130    }
131}
132
133macro_rules! impl_tuple {
134    ($($ty:ident),+) => {
135        impl<$($ty),+> NodeViewParts for ($($ty,)+)
136        where
137            $($ty: NodeViewParts,)+
138        {
139            #[inline]
140            #[allow(non_snake_case)]
141            fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
142                let ($($ty,)+) = self;
143                $($ty.into_view_parts(cx, parts);)+
144            }
145        }
146    };
147}
148
149impl_tuple!(T1);
150impl_tuple!(T1, T2);
151impl_tuple!(T1, T2, T3);
152impl_tuple!(T1, T2, T3, T4);
153impl_tuple!(T1, T2, T3, T4, T5);
154impl_tuple!(T1, T2, T3, T4, T5, T6);
155impl_tuple!(T1, T2, T3, T4, T5, T6, T7);
156impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
157impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
158impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
159impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
160impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);