use wasm_bindgen::UnwrapThrowExt;
use crate::core::Mut;
use crate::core::one_of::{OneOf, OneOfCtx, PhantomElementCtx};
use crate::{DomNode, Pod, PodFlags, PodMut, ViewCtx};
impl<N1, N2, N3, N4, N5, N6, N7, N8, N9>
OneOfCtx<Pod<N1>, Pod<N2>, Pod<N3>, Pod<N4>, Pod<N5>, Pod<N6>, Pod<N7>, Pod<N8>, Pod<N9>>
for ViewCtx
where
N1: DomNode,
N2: DomNode,
N3: DomNode,
N4: DomNode,
N5: DomNode,
N6: DomNode,
N7: DomNode,
N8: DomNode,
N9: DomNode,
{
type OneOfElement = Pod<OneOf<N1, N2, N3, N4, N5, N6, N7, N8, N9>>;
fn upcast_one_of_element(
&mut self,
elem: OneOf<
Pod<N1>,
Pod<N2>,
Pod<N3>,
Pod<N4>,
Pod<N5>,
Pod<N6>,
Pod<N7>,
Pod<N8>,
Pod<N9>,
>,
) -> Self::OneOfElement {
match elem {
OneOf::A(e) => Pod::new(OneOf::A(e.node), OneOf::A(e.props), e.flags),
OneOf::B(e) => Pod::new(OneOf::B(e.node), OneOf::B(e.props), e.flags),
OneOf::C(e) => Pod::new(OneOf::C(e.node), OneOf::C(e.props), e.flags),
OneOf::D(e) => Pod::new(OneOf::D(e.node), OneOf::D(e.props), e.flags),
OneOf::E(e) => Pod::new(OneOf::E(e.node), OneOf::E(e.props), e.flags),
OneOf::F(e) => Pod::new(OneOf::F(e.node), OneOf::F(e.props), e.flags),
OneOf::G(e) => Pod::new(OneOf::G(e.node), OneOf::G(e.props), e.flags),
OneOf::H(e) => Pod::new(OneOf::H(e.node), OneOf::H(e.props), e.flags),
OneOf::I(e) => Pod::new(OneOf::I(e.node), OneOf::I(e.props), e.flags),
}
}
fn update_one_of_element_mut(
elem_mut: &mut Mut<'_, Self::OneOfElement>,
new_elem: OneOf<
Pod<N1>,
Pod<N2>,
Pod<N3>,
Pod<N4>,
Pod<N5>,
Pod<N6>,
Pod<N7>,
Pod<N8>,
Pod<N9>,
>,
) {
let old_node: &web_sys::Node = elem_mut.node.as_ref();
let new_node: &web_sys::Node = new_elem.as_ref();
if old_node != new_node
&& let Some(parent) = elem_mut.parent
{
parent.replace_child(new_node, old_node).unwrap_throw();
}
(*elem_mut.node, *elem_mut.props, *elem_mut.flags) = match new_elem {
OneOf::A(e) => (OneOf::A(e.node), OneOf::A(e.props), e.flags),
OneOf::B(e) => (OneOf::B(e.node), OneOf::B(e.props), e.flags),
OneOf::C(e) => (OneOf::C(e.node), OneOf::C(e.props), e.flags),
OneOf::D(e) => (OneOf::D(e.node), OneOf::D(e.props), e.flags),
OneOf::E(e) => (OneOf::E(e.node), OneOf::E(e.props), e.flags),
OneOf::F(e) => (OneOf::F(e.node), OneOf::F(e.props), e.flags),
OneOf::G(e) => (OneOf::G(e.node), OneOf::G(e.props), e.flags),
OneOf::H(e) => (OneOf::H(e.node), OneOf::H(e.props), e.flags),
OneOf::I(e) => (OneOf::I(e.node), OneOf::I(e.props), e.flags),
};
}
fn with_downcast_a<R>(
e: &mut Mut<'_, Self::OneOfElement>,
f: impl FnOnce(Mut<'_, Pod<N1>>) -> R,
) -> R {
let (OneOf::A(node), OneOf::A(props)) = (&mut e.node, &mut e.props) else {
unreachable!()
};
f(PodMut::new(node, props, e.flags, e.parent, e.was_removed))
}
fn with_downcast_b<R>(
e: &mut Mut<'_, Self::OneOfElement>,
f: impl FnOnce(Mut<'_, Pod<N2>>) -> R,
) -> R {
let (OneOf::B(node), OneOf::B(props)) = (&mut e.node, &mut e.props) else {
unreachable!()
};
f(PodMut::new(node, props, e.flags, e.parent, e.was_removed))
}
fn with_downcast_c<R>(
e: &mut Mut<'_, Self::OneOfElement>,
f: impl FnOnce(Mut<'_, Pod<N3>>) -> R,
) -> R {
let (OneOf::C(node), OneOf::C(props)) = (&mut e.node, &mut e.props) else {
unreachable!()
};
f(PodMut::new(node, props, e.flags, e.parent, e.was_removed))
}
fn with_downcast_d<R>(
e: &mut Mut<'_, Self::OneOfElement>,
f: impl FnOnce(Mut<'_, Pod<N4>>) -> R,
) -> R {
let (OneOf::D(node), OneOf::D(props)) = (&mut e.node, &mut e.props) else {
unreachable!()
};
f(PodMut::new(node, props, e.flags, e.parent, e.was_removed))
}
fn with_downcast_e<R>(
e: &mut Mut<'_, Self::OneOfElement>,
f: impl FnOnce(Mut<'_, Pod<N5>>) -> R,
) -> R {
let (OneOf::E(node), OneOf::E(props)) = (&mut e.node, &mut e.props) else {
unreachable!()
};
f(PodMut::new(node, props, e.flags, e.parent, e.was_removed))
}
fn with_downcast_f<R>(
e: &mut Mut<'_, Self::OneOfElement>,
f: impl FnOnce(Mut<'_, Pod<N6>>) -> R,
) -> R {
let (OneOf::F(node), OneOf::F(props)) = (&mut e.node, &mut e.props) else {
unreachable!()
};
f(PodMut::new(node, props, e.flags, e.parent, e.was_removed))
}
fn with_downcast_g<R>(
e: &mut Mut<'_, Self::OneOfElement>,
f: impl FnOnce(Mut<'_, Pod<N7>>) -> R,
) -> R {
let (OneOf::G(node), OneOf::G(props)) = (&mut e.node, &mut e.props) else {
unreachable!()
};
f(PodMut::new(node, props, e.flags, e.parent, e.was_removed))
}
fn with_downcast_h<R>(
e: &mut Mut<'_, Self::OneOfElement>,
f: impl FnOnce(Mut<'_, Pod<N8>>) -> R,
) -> R {
let (OneOf::H(node), OneOf::H(props)) = (&mut e.node, &mut e.props) else {
unreachable!()
};
f(PodMut::new(node, props, e.flags, e.parent, e.was_removed))
}
fn with_downcast_i<R>(
e: &mut Mut<'_, Self::OneOfElement>,
f: impl FnOnce(Mut<'_, Pod<N9>>) -> R,
) -> R {
let (OneOf::I(node), OneOf::I(props)) = (&mut e.node, &mut e.props) else {
unreachable!()
};
f(PodMut::new(node, props, e.flags, e.parent, e.was_removed))
}
}
impl<N1, N2, N3, N4, N5, N6, N7, N8, N9> DomNode for OneOf<N1, N2, N3, N4, N5, N6, N7, N8, N9>
where
N1: DomNode,
N2: DomNode,
N3: DomNode,
N4: DomNode,
N5: DomNode,
N6: DomNode,
N7: DomNode,
N8: DomNode,
N9: DomNode,
{
type Props = OneOf<
N1::Props,
N2::Props,
N3::Props,
N4::Props,
N5::Props,
N6::Props,
N7::Props,
N8::Props,
N9::Props,
>;
fn apply_props(&self, props: &mut Self::Props, flags: &mut PodFlags) {
match (self, props) {
(Self::A(el), OneOf::A(props)) => el.apply_props(props, flags),
(Self::B(el), OneOf::B(props)) => el.apply_props(props, flags),
(Self::C(el), OneOf::C(props)) => el.apply_props(props, flags),
(Self::D(el), OneOf::D(props)) => el.apply_props(props, flags),
(Self::E(el), OneOf::E(props)) => el.apply_props(props, flags),
(Self::F(el), OneOf::F(props)) => el.apply_props(props, flags),
(Self::G(el), OneOf::G(props)) => el.apply_props(props, flags),
(Self::H(el), OneOf::H(props)) => el.apply_props(props, flags),
(Self::I(el), OneOf::I(props)) => el.apply_props(props, flags),
_ => unreachable!(),
}
}
}
#[expect(
unnameable_types,
reason = "Implementation detail, public because of trait visibility rules"
)]
pub enum Noop {}
impl<T> AsRef<T> for Noop {
fn as_ref(&self) -> &T {
match *self {}
}
}
impl<T> AsMut<T> for Noop {
fn as_mut(&mut self) -> &mut T {
match *self {}
}
}
impl PhantomElementCtx for ViewCtx {
type PhantomElement = Pod<Noop>;
}
impl DomNode for Noop {
fn apply_props(&self, _props: &mut Self::Props, _: &mut PodFlags) {
match *self {}
}
type Props = Self;
}