1use std::borrow::Cow;
2
3#[cfg(feature = "http")]
4use http::{HeaderMap, HeaderName, HeaderValue, StatusCode};
5use topcoat_core::context::Cx;
6
7use crate::{PartsWriter, PromotedStr, StaticStr, Unescaped, buffer::ViewHandle};
8
9pub trait NodeViewParts {
25 fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>);
27}
28
29impl NodeViewParts for () {
31 #[inline]
32 fn into_view_parts(self, _cx: &Cx, _parts: &mut PartsWriter<'_>) {}
33}
34
35impl NodeViewParts for ViewHandle {
36 #[inline]
37 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
38 parts.push_view_handle(self);
39 }
40}
41
42macro_rules! impl_primitive {
43 ($ty:ty, $method:ident) => {
44 impl NodeViewParts for $ty {
45 #[inline]
46 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
47 parts.$method(self);
48 }
49 }
50 };
51 ($ty:ty, $method:ident, ref) => {
52 impl_primitive!($ty, $method);
53
54 impl NodeViewParts for &$ty {
55 #[inline]
56 fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
57 (*self).into_view_parts(cx, parts)
58 }
59 }
60 };
61}
62
63impl_primitive!(bool, push_bool, ref);
64impl_primitive!(char, push_char, ref);
65impl_primitive!(i8, push_i8, ref);
66impl_primitive!(i16, push_i16, ref);
67impl_primitive!(i32, push_i32, ref);
68impl_primitive!(i64, push_i64, ref);
69impl_primitive!(i128, push_i128, ref);
70impl_primitive!(isize, push_isize, ref);
71impl_primitive!(u8, push_u8, ref);
72impl_primitive!(u16, push_u16, ref);
73impl_primitive!(u32, push_u32, ref);
74impl_primitive!(u64, push_u64, ref);
75impl_primitive!(u128, push_u128, ref);
76impl_primitive!(usize, push_usize, ref);
77impl_primitive!(f32, push_f32, ref);
78impl_primitive!(f64, push_f64, ref);
79impl_primitive!(String, push_string);
80
81impl NodeViewParts for Cow<'static, str> {
82 #[inline]
83 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
84 match self {
85 Cow::Borrowed(value) => parts.push_static_str(value),
86 Cow::Owned(value) => parts.push_string(value),
87 };
88 }
89}
90
91impl NodeViewParts for &str {
92 #[inline]
93 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
94 parts.push_str(self);
95 }
96}
97
98impl NodeViewParts for PromotedStr {
99 #[inline]
100 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
101 parts.push_promoted_str(self.0);
102 }
103}
104
105impl NodeViewParts for StaticStr {
106 #[inline]
107 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
108 parts.push_static_str(self.0);
109 }
110}
111
112impl NodeViewParts for Unescaped<String> {
113 #[inline]
114 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
115 parts.push_string_unescaped(self.0);
116 }
117}
118
119impl NodeViewParts for Unescaped<PromotedStr> {
120 #[inline]
121 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
122 parts.push_promoted_str_unescaped(self.0.0);
123 }
124}
125
126impl NodeViewParts for Unescaped<StaticStr> {
127 #[inline]
128 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
129 parts.push_static_str_unescaped(self.0.0);
130 }
131}
132
133impl NodeViewParts for Unescaped<&'static str> {
134 #[inline]
135 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
136 parts.push_static_str_unescaped(self.0);
137 }
138}
139
140impl NodeViewParts for &String {
141 #[inline]
142 fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
143 self.as_str().into_view_parts(cx, parts);
144 }
145}
146
147#[cfg(feature = "http")]
155impl NodeViewParts for StatusCode {
156 #[inline]
157 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
158 parts.push_status_code(self);
159 }
160}
161
162#[cfg(feature = "http")]
169impl NodeViewParts for HeaderMap {
170 #[inline]
171 fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
172 parts.push_headers(self);
173 }
174}
175
176#[cfg(feature = "http")]
180impl NodeViewParts for (HeaderName, HeaderValue) {
181 fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
182 let (name, value) = self;
183 let mut headers = HeaderMap::with_capacity(1);
184 headers.insert(name, value);
185 headers.into_view_parts(cx, parts);
186 }
187}
188
189impl<'b, T: ?Sized> NodeViewParts for &&'b T
190where
191 &'b T: NodeViewParts,
192{
193 #[inline]
194 fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
195 (*self).into_view_parts(cx, parts);
196 }
197}
198
199impl<T> NodeViewParts for Option<T>
200where
201 T: NodeViewParts,
202{
203 #[inline]
204 fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
205 if let Some(value) = self {
206 value.into_view_parts(cx, parts);
207 }
208 }
209}
210
211impl<T> NodeViewParts for Vec<T>
212where
213 T: NodeViewParts,
214{
215 #[inline]
216 fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
217 for value in self {
218 value.into_view_parts(cx, parts);
219 }
220 }
221}
222
223macro_rules! impl_tuple {
224 ($($ty:ident),+) => {
225 impl<$($ty),+> NodeViewParts for ($($ty,)+)
226 where
227 $($ty: NodeViewParts,)+
228 {
229 #[inline]
230 #[allow(non_snake_case)]
231 fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
232 let ($($ty,)+) = self;
233 $($ty.into_view_parts(cx, parts);)+
234 }
235 }
236 };
237}
238
239impl_tuple!(T1);
240impl_tuple!(T1, T2);
241impl_tuple!(T1, T2, T3);
242impl_tuple!(T1, T2, T3, T4);
243impl_tuple!(T1, T2, T3, T4, T5);
244impl_tuple!(T1, T2, T3, T4, T5, T6);
245impl_tuple!(T1, T2, T3, T4, T5, T6, T7);
246impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
247impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
248impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
249impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
250impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);