1use super::{
2 add_attr::AddAnyAttr, Mountable, Position, PositionState, Render,
3 RenderHtml, ToTemplate,
4};
5use crate::{
6 html::attribute::{any_attribute::AnyAttribute, Attribute},
7 hydration::Cursor,
8 renderer::Rndr,
9};
10
11pub struct ViewTemplate<V> {
17 view: V,
18}
19
20impl<V> ViewTemplate<V>
21where
22 V: Render + ToTemplate + 'static,
23{
24 pub fn new(view: V) -> Self {
26 Self { view }
27 }
28
29 fn to_template() -> crate::renderer::types::TemplateElement {
30 Rndr::get_template::<V>()
31 }
32}
33
34impl<V> Render for ViewTemplate<V>
35where
36 V: Render + RenderHtml + ToTemplate + 'static,
37 V::State: Mountable,
38{
39 type State = V::State;
40
41 fn build(self) -> Self::State {
44 let tpl = Self::to_template();
45 let contents = Rndr::clone_template(&tpl);
46 self.view
47 .hydrate::<false>(&Cursor::new(contents), &Default::default())
48 }
49
50 fn rebuild(self, state: &mut Self::State) {
51 self.view.rebuild(state)
52 }
53}
54
55impl<V> AddAnyAttr for ViewTemplate<V>
56where
57 V: RenderHtml + ToTemplate + 'static,
58 V::State: Mountable,
59{
60 type Output<SomeNewAttr: Attribute> = ViewTemplate<V>;
61
62 fn add_any_attr<NewAttr: Attribute>(
63 self,
64 _attr: NewAttr,
65 ) -> Self::Output<NewAttr> {
66 panic!("AddAnyAttr not supported on ViewTemplate");
67 }
68}
69
70impl<V> RenderHtml for ViewTemplate<V>
71where
72 V: RenderHtml + ToTemplate + 'static,
73 V::State: Mountable,
74{
75 type AsyncOutput = V::AsyncOutput;
76 type Owned = V::Owned;
77
78 const MIN_LENGTH: usize = V::MIN_LENGTH;
79
80 fn to_html_with_buf(
81 self,
82 buf: &mut String,
83 position: &mut Position,
84 escape: bool,
85 mark_branches: bool,
86 extra_attrs: Vec<AnyAttribute>,
87 ) {
88 self.view.to_html_with_buf(
89 buf,
90 position,
91 escape,
92 mark_branches,
93 extra_attrs,
94 )
95 }
96
97 fn hydrate<const FROM_SERVER: bool>(
98 self,
99 cursor: &Cursor,
100 position: &PositionState,
101 ) -> Self::State {
102 self.view.hydrate::<FROM_SERVER>(cursor, position)
103 }
104
105 fn dry_resolve(&mut self) {
106 self.view.dry_resolve();
107 }
108
109 async fn resolve(self) -> Self::AsyncOutput {
110 self.view.resolve().await
111 }
112
113 fn into_owned(self) -> Self::Owned {
114 self.view.into_owned()
115 }
116}
117
118impl<V> ToTemplate for ViewTemplate<V>
119where
120 V: RenderHtml + ToTemplate + 'static,
121 V::State: Mountable,
122{
123 const TEMPLATE: &'static str = V::TEMPLATE;
124
125 fn to_template(
126 buf: &mut String,
127 class: &mut String,
128 style: &mut String,
129 inner_html: &mut String,
130 position: &mut Position,
131 ) {
132 V::to_template(buf, class, style, inner_html, position);
133 }
134}