Compare commits

...

1 Commits

Author SHA1 Message Date
Greg Johnston
9d0d863cfa another try at adding AddAnyAttr to AnyView 2025-01-08 13:49:30 -05:00

View File

@@ -5,7 +5,12 @@ use super::{
RenderHtml,
};
use crate::{
html::attribute::Attribute, hydration::Cursor, ssr::StreamBuilder,
html::attribute::{
any_attribute::{AnyAttribute, IntoAnyAttribute},
Attribute,
},
hydration::Cursor,
ssr::StreamBuilder,
};
use std::{
any::{Any, TypeId},
@@ -29,6 +34,7 @@ pub struct AnyView {
value: Box<dyn Any + Send>,
build: fn(Box<dyn Any>) -> AnyViewState,
rebuild: fn(TypeId, Box<dyn Any>, &mut AnyViewState),
add_any_attr: fn(Box<dyn Any>, AnyAttribute) -> AnyView,
// The fields below are cfg-gated so they will not be included in WASM bundles if not needed.
// Ordinarily, the compiler can simply omit this dead code because the methods are not called.
// With this type-erased wrapper, however, the compiler is not *always* able to correctly
@@ -130,7 +136,6 @@ where
{
// inlining allows the compiler to remove the unused functions
// i.e., doesn't ship HTML-generating code that isn't used
#[inline(always)]
fn into_any(self) -> AnyView {
#[cfg(feature = "ssr")]
let html_len = self.html_len();
@@ -282,11 +287,19 @@ where
}
};
let add_any_attr = |value: Box<dyn Any>, attr: AnyAttribute| {
let value = value
.downcast::<T>()
.expect("AnyView::add_any_attr could not be downcast");
value.add_any_attr(attr).into_any()
};
AnyView {
type_id: TypeId::of::<T>(),
value,
build,
rebuild,
add_any_attr,
#[cfg(feature = "ssr")]
resolve,
#[cfg(feature = "ssr")]
@@ -324,12 +337,13 @@ impl AddAnyAttr for AnyView {
fn add_any_attr<NewAttr: Attribute>(
self,
_attr: NewAttr,
attr: NewAttr,
) -> Self::Output<NewAttr>
where
Self::Output<NewAttr>: RenderHtml,
{
self
let attr = attr.into_cloneable_owned();
(self.add_any_attr)(self.value, attr.into_any_attr())
}
}