#![allow(clippy::inline_always)]
use crate::sealed::Sealed;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DomRef<T> {
Added(T),
Removing(T),
}
impl<T> Sealed for DomRef<T> {}
macro_rules! web_types {
{$(
$(#[$($attrs:tt)*])*
($container:ident, $container_str:literal) => $contents:ty
),*$(,)?} => {$(
$(#[$($attrs)*])*
#[cfg_attr(feature = "callbacks", repr(transparent))]
#[derive(Debug, Clone)]
pub struct $container(
#[cfg(feature = "callbacks")] $contents,
#[cfg(not(feature = "callbacks"))] FeatureNeeded,
);
impl Sealed for $container {}
impl<'a> Sealed for &'a $container {}
impl $container {
#[doc = $container_str]
#[cfg_attr(
not(feature = "callbacks"),
deprecated = "The `\"callbacks\"` feature is required to use this function."
)]
#[inline(always)]
#[must_use]
pub fn new(
#[cfg(feature = "callbacks")] value: $contents,
#[cfg(not(feature = "callbacks"))] value: FeatureNeeded,
) -> Self {
Self(value)
}
}
)?};
}
web_types! {
(Comment, "Comment") => web_sys::Comment,
(Element, "Element") => web_sys::Element,
(Event, "Event") => web_sys::Event,
(HtmlElement, "HtmlElement") => web_sys::HtmlElement,
(SvgElement, "HtmlElement") => web_sys::SvgElement,
(Text, "Text") => web_sys::Text,
}
macro_rules! conversions {
{$(
$container:ty => $contents:ty
),*$(,)?} => {$(
#[cfg(feature = "callbacks")]
impl Materialize<$contents> for $container {
#[inline(always)] fn materialize(self) -> $contents {
self.0
}
}
#[cfg(feature = "callbacks")]
impl<'a> Materialize<&'a $contents> for &'a $container {
#[inline(always)] fn materialize(self) -> &'a $contents {
unsafe {&*(self as *const $container).cast() }
}
}
#[cfg(not(feature = "callbacks"))]
impl<AnyType> Materialize<AnyType> for $container {
#[inline(always)]
fn materialize(self) -> AnyType {
unreachable!()
}
}
#[cfg(not(feature = "callbacks"))]
impl<'a, AnyType> Materialize<&'a AnyType> for &'a $container {
#[inline(always)]
fn materialize(self) -> &'a AnyType {
unreachable!()
}
}
#[cfg(feature = "callbacks")]
impl From<$contents> for $container {
#[inline(always)] fn from(contents: $contents) -> Self {
Self(contents)
}
}
#[cfg(feature = "callbacks")]
impl<'a> From<&'a $contents> for &'a $container {
#[inline(always)] fn from(contents: &'a $contents) -> Self {
unsafe {
&*(contents as *const $contents).cast()
}
}
}
)*};
}
impl<T: Materialize<U>, U> Materialize<DomRef<U>> for DomRef<T> {
#[inline(always)]
fn materialize(self) -> DomRef<U> {
match self {
Self::Added(added) => DomRef::Added(added.materialize()),
Self::Removing(removing) => DomRef::Removing(removing.materialize()),
}
}
}
conversions! {
Comment => web_sys::Comment,
Element => web_sys::Element,
Event => web_sys::Event,
HtmlElement => web_sys::HtmlElement,
SvgElement => web_sys::SvgElement,
Text => web_sys::Text,
}
#[doc(hidden)]
#[allow(clippy::empty_enum)]
#[derive(Debug, Clone)]
pub enum FeatureNeeded {}
impl FeatureNeeded {
#[allow(dead_code)]
fn map<T, U>(self, _: T) -> Option<U> {
let _ = self;
unreachable!()
}
}
pub trait Materialize<T: Sized>: Sized + Sealed {
fn materialize(self) -> T;
}