dioxus_core/view/
traits.rs1use crate::{DynamicValues, Template, VNode};
5use dioxus_core_template::{
6 TEMPLATE_STORAGE_DYNAMIC_CAP, TEMPLATE_STORAGE_OPS_CAP, TEMPLATE_STORAGE_STRING_CAP,
7 TemplateRawTree, TemplateStorage,
8};
9use std::marker::PhantomData;
10
11pub trait ViewTemplate {
13 const TEMPLATE_TREE: &'static TemplateRawTree;
15}
16
17struct StaticViewTemplate<
18 V,
19 const OPS_CAP: usize,
20 const STRING_CAP: usize,
21 const DYNAMIC_CAP: usize,
22>(PhantomData<fn() -> V>);
23
24impl<V: ViewTemplate, const OPS_CAP: usize, const STRING_CAP: usize, const DYNAMIC_CAP: usize>
25 StaticViewTemplate<V, OPS_CAP, STRING_CAP, DYNAMIC_CAP>
26{
27 const TEMPLATE: &'static Template =
28 &TemplateStorage::<OPS_CAP, STRING_CAP, DYNAMIC_CAP>::build_from_tree(V::TEMPLATE_TREE)
29 .as_template();
30}
31
32impl ViewTemplate for () {
33 const TEMPLATE_TREE: &'static TemplateRawTree = &TemplateRawTree::Empty;
34}
35
36pub trait View: ViewTemplate + Sized {
38 #[inline]
40 fn push(self, _: &mut DynamicValues) {}
41}
42
43pub struct KeyedView<V> {
45 key: Option<String>,
46 view: V,
47}
48
49impl<V: ViewTemplate> ViewTemplate for KeyedView<V> {
50 const TEMPLATE_TREE: &'static TemplateRawTree = V::TEMPLATE_TREE;
51}
52
53impl<V: View> View for KeyedView<V> {
54 #[inline]
55 fn push(self, dynamic: &mut DynamicValues) {
56 dynamic.set_key(self.key);
57 self.view.push(dynamic);
58 }
59}
60
61pub trait ViewKeyExt: View {
63 fn key(self, key: Option<String>) -> KeyedView<Self>;
65}
66
67impl<V: View> ViewKeyExt for V {
68 #[inline]
69 fn key(self, key: Option<String>) -> KeyedView<Self> {
70 KeyedView { key, view: self }
71 }
72}
73
74pub trait ViewExt: View {
76 fn into_vnode(self) -> VNode;
78}
79
80impl<V: View> ViewExt for V {
81 #[inline]
82 fn into_vnode(self) -> VNode {
83 into_vnode_with_template(
84 self,
85 StaticViewTemplate::<
86 V,
87 TEMPLATE_STORAGE_OPS_CAP,
88 TEMPLATE_STORAGE_STRING_CAP,
89 TEMPLATE_STORAGE_DYNAMIC_CAP,
90 >::TEMPLATE,
91 )
92 }
93}
94
95#[inline]
97fn into_vnode_with_template<V: View>(view: V, template: &Template) -> VNode {
98 let mut dynamic = DynamicValues::new();
99 view.push(&mut dynamic);
100 VNode::new(*template, dynamic)
101}
102
103#[cfg(debug_assertions)]
110#[doc(hidden)]
111pub fn into_vnode_cached<V: View>(view: V, cache: &std::sync::OnceLock<Template>) -> VNode {
112 let template =
113 *cache.get_or_init(|| dioxus_core_template::build_runtime_template(V::TEMPLATE_TREE));
114 into_vnode_with_template(view, &template)
115}
116
117pub fn into_vnode_with_capacity<
119 const OPS_CAP: usize,
120 const STRING_CAP: usize,
121 const DYNAMIC_CAP: usize,
122 V: View,
123>(
124 view: V,
125) -> VNode {
126 into_vnode_with_template(
127 view,
128 StaticViewTemplate::<V, OPS_CAP, STRING_CAP, DYNAMIC_CAP>::TEMPLATE,
129 )
130}
131
132impl View for () {}