Skip to main content

dioxus_core/view/
element.rs

1//! The typed element view: [`ElementBuilder`] and its tag marker
2//! [`ElementTag`].
3
4use std::marker::PhantomData;
5
6use crate::DynamicValues;
7use dioxus_core_template::TemplateRawTree;
8
9use super::{IntoViewChild, View, ViewTemplate};
10
11/// A static element tag marker.
12pub trait ElementTag {
13    /// The renderer tag name.
14    const NAME: &'static str;
15
16    /// The optional renderer namespace.
17    const NAMESPACE: Option<&'static str> = None;
18}
19
20/// A typed element view.
21pub struct ElementBuilder<Tag, Attributes, Children> {
22    attrs: Attributes,
23    children: Children,
24    _tag: PhantomData<Tag>,
25}
26
27/// Create an empty typed element for a tag marker.
28#[inline]
29pub const fn element_builder<Tag>() -> ElementBuilder<Tag, (), ()> {
30    ElementBuilder {
31        attrs: (),
32        children: (),
33        _tag: PhantomData,
34    }
35}
36
37impl<Tag, Attributes, Children> ElementBuilder<Tag, Attributes, Children> {
38    /// Append one attribute view.
39    #[inline]
40    pub fn attribute<AttributeView>(
41        self,
42        attr: AttributeView,
43    ) -> ElementBuilder<Tag, (Attributes, AttributeView), Children> {
44        ElementBuilder {
45            attrs: (self.attrs, attr),
46            children: self.children,
47            _tag: PhantomData,
48        }
49    }
50
51    /// Append one child.
52    #[inline]
53    pub fn child<Child, Marker>(
54        self,
55        child: Child,
56    ) -> ElementBuilder<Tag, Attributes, (Children, <Child as IntoViewChild<Marker>>::Output)>
57    where
58        Child: IntoViewChild<Marker>,
59    {
60        ElementBuilder {
61            attrs: self.attrs,
62            children: (self.children, child.into_child()),
63            _tag: PhantomData,
64        }
65    }
66}
67
68impl<Tag: ElementTag, Attributes: ViewTemplate, Children: ViewTemplate> ViewTemplate
69    for ElementBuilder<Tag, Attributes, Children>
70{
71    const TEMPLATE_TREE: &'static TemplateRawTree = &TemplateRawTree::Element {
72        tag: Tag::NAME,
73        namespace: Tag::NAMESPACE,
74        attrs: Attributes::TEMPLATE_TREE,
75        children: Children::TEMPLATE_TREE,
76    };
77}
78
79impl<Tag: ElementTag, Attributes: View, Children: View> View
80    for ElementBuilder<Tag, Attributes, Children>
81{
82    #[inline]
83    fn push(self, dynamic: &mut DynamicValues) {
84        self.attrs.push(dynamic);
85        self.children.push(dynamic);
86    }
87}