Skip to main content

dioxus_core/view/
child.rs

1//! Normalizing values into typed child views: the [`IntoViewChild`] trait and
2//! the dynamic node slot it lowers dynamic nodes through.
3
4use std::marker::PhantomData;
5
6use crate::{DynamicValues, IntoDynNode};
7use dioxus_core_template::TemplateRawTree;
8
9use super::{View, ViewTemplate};
10
11/// Marker for child values that should become dynamic node slots.
12pub struct DynamicViewChildMarker<Marker>(PhantomData<Marker>);
13
14/// A dynamic node slot.
15pub struct DynamicNodeBuilder<N, Marker = ()> {
16    node: N,
17    _marker: PhantomData<Marker>,
18}
19
20/// Create a dynamic node slot from any [`IntoDynNode`] value.
21#[inline]
22pub fn dynamic_node_builder<N, Marker>(node: N) -> DynamicNodeBuilder<N, Marker>
23where
24    N: IntoDynNode<Marker>,
25{
26    DynamicNodeBuilder {
27        node,
28        _marker: PhantomData,
29    }
30}
31
32impl<N, Marker> ViewTemplate for DynamicNodeBuilder<N, Marker> {
33    const TEMPLATE_TREE: &'static TemplateRawTree = &TemplateRawTree::DynamicNode;
34}
35
36impl<N, Marker> View for DynamicNodeBuilder<N, Marker>
37where
38    N: IntoDynNode<Marker>,
39{
40    fn push(self, dynamic: &mut DynamicValues) {
41        dynamic.push_node(self.node.into_dyn_node());
42    }
43}
44
45/// Marker for child values that are already typed views.
46#[doc(hidden)]
47pub struct ViewChildMarker;
48
49/// Convert a value passed to [`ElementBuilder::child`](super::ElementBuilder::child) into a typed
50/// child view.
51pub trait IntoViewChild<Marker = ViewChildMarker> {
52    /// The typed view contributed by this child.
53    type Output: View;
54
55    /// Convert into the child view.
56    fn into_child(self) -> Self::Output;
57}
58
59impl<V: View> IntoViewChild<ViewChildMarker> for V {
60    type Output = V;
61
62    #[inline]
63    fn into_child(self) -> Self::Output {
64        self
65    }
66}
67
68impl<N, Marker> IntoViewChild<DynamicViewChildMarker<Marker>> for N
69where
70    N: IntoDynNode<Marker>,
71{
72    type Output = DynamicNodeBuilder<N, Marker>;
73
74    #[inline]
75    fn into_child(self) -> Self::Output {
76        dynamic_node_builder(self)
77    }
78}