Skip to main content

topcoat_view/html/
element.rs

1use topcoat_core::context::Cx;
2
3use crate::{PartsWriter, PromotedStr, StaticStr, Unescaped};
4
5/// Converts a value used as an element name into view parts.
6///
7/// Implement this trait to use a type as a dynamic element name in
8/// [`view!`](https://docs.rs/topcoat/latest/topcoat/view/macro.view.html):
9///
10/// ```rust
11/// # use topcoat::view::{View, component, view};
12/// # #[component]
13/// # async fn example() -> topcoat::Result<impl View> {
14/// # let tag_name = "div";
15/// Ok(view! {
16///     <(tag_name)></(tag_name)>
17/// })
18/// # }
19/// ```
20pub trait ElementNameViewParts {
21    /// Appends this element name to the view being built.
22    fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>);
23}
24
25impl ElementNameViewParts for String {
26    #[inline]
27    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
28        parts.push_string(self);
29    }
30}
31
32impl ElementNameViewParts for &str {
33    #[inline]
34    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
35        parts.push_str(self);
36    }
37}
38
39impl ElementNameViewParts for PromotedStr {
40    #[inline]
41    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
42        parts.push_promoted_str(self.0);
43    }
44}
45
46impl ElementNameViewParts for StaticStr {
47    #[inline]
48    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
49        parts.push_static_str(self.0);
50    }
51}
52
53impl ElementNameViewParts for Unescaped<String> {
54    #[inline]
55    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
56        parts.push_string_unescaped(self.0);
57    }
58}
59
60impl ElementNameViewParts for Unescaped<&'static str> {
61    #[inline]
62    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
63        parts.push_static_str_unescaped(self.0);
64    }
65}
66
67impl ElementNameViewParts for Unescaped<PromotedStr> {
68    #[inline]
69    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
70        parts.push_promoted_str_unescaped(self.0.0);
71    }
72}
73
74impl ElementNameViewParts for Unescaped<StaticStr> {
75    #[inline]
76    fn into_view_parts(self, _cx: &Cx, parts: &mut PartsWriter<'_>) {
77        parts.push_static_str_unescaped(self.0.0);
78    }
79}
80
81impl ElementNameViewParts for &String {
82    #[inline]
83    fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
84        self.as_str().into_view_parts(cx, parts);
85    }
86}
87
88impl<'b, T: ?Sized> ElementNameViewParts for &&'b T
89where
90    &'b T: ElementNameViewParts,
91{
92    #[inline]
93    fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
94        (*self).into_view_parts(cx, parts);
95    }
96}
97
98macro_rules! impl_tuple {
99    ($($ty:ident),+) => {
100        impl<$($ty),+> ElementNameViewParts for ($($ty,)+)
101        where
102            $($ty: ElementNameViewParts,)+
103        {
104            #[inline]
105            #[allow(non_snake_case)]
106            fn into_view_parts(self, cx: &Cx, parts: &mut PartsWriter<'_>) {
107                let ($($ty,)+) = self;
108                $($ty.into_view_parts(cx, parts);)+
109            }
110        }
111    };
112}
113
114impl_tuple!(T1);
115impl_tuple!(T1, T2);
116impl_tuple!(T1, T2, T3);
117impl_tuple!(T1, T2, T3, T4);
118impl_tuple!(T1, T2, T3, T4, T5);
119impl_tuple!(T1, T2, T3, T4, T5, T6);
120impl_tuple!(T1, T2, T3, T4, T5, T6, T7);
121impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
122impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
123impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
124impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
125impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);