#[allow(deprecated)]
use crate::wrappers::read::{MaybeProp, MaybeSignal};
use crate::{
computed::{ArcMemo, Memo},
owner::Storage,
signal::{
ArcReadSignal, ArcRwSignal, ArcWriteSignal, ReadSignal, RwSignal,
WriteSignal,
},
wrappers::{
read::{ArcSignal, Signal, SignalTypes},
write::SignalSetter,
},
};
mod readable_deref_impl {
pub trait ReadableDerefImpl: crate::traits::Get {
#[doc(hidden)]
unsafe fn deref_impl<'a>(
&self,
) -> &'a (dyn Fn() -> Self::Value + Send + Sync)
where
Self: Send + Sync,
Self: Sized + 'a,
Self::Value: Clone + 'static,
{
let uninit_callable = std::mem::MaybeUninit::<Self>::uninit();
let uninit_closure =
move || Self::get(unsafe { &*uninit_callable.as_ptr() });
let size_of_closure = std::mem::size_of_val(&uninit_closure);
assert_eq!(size_of_closure, std::mem::size_of::<Self>());
fn cast_lifetime<'a, T>(_a: &T, b: &'a T) -> &'a T {
b
}
let reference_to_closure = cast_lifetime(
{
&uninit_closure
},
#[allow(clippy::missing_transmute_annotations)]
unsafe {
std::mem::transmute(self)
},
);
reference_to_closure as &_
}
}
}
mod writable_deref_impl {
pub trait WritableDerefImpl: crate::traits::Set {
#[doc(hidden)]
unsafe fn deref_impl<'a>(
&self,
) -> &'a (dyn Fn(Self::Value) + Send + Sync)
where
Self: Send + Sync,
Self: Sized + 'a,
{
let uninit_callable = std::mem::MaybeUninit::<Self>::uninit();
let uninit_closure = move |value| {
Self::set(unsafe { &*uninit_callable.as_ptr() }, value);
};
let size_of_closure = std::mem::size_of_val(&uninit_closure);
assert_eq!(size_of_closure, std::mem::size_of::<Self>());
fn cast_lifetime<'a, T>(_a: &T, b: &'a T) -> &'a T {
b
}
let reference_to_closure = cast_lifetime(
&uninit_closure,
#[allow(clippy::missing_transmute_annotations)]
unsafe {
std::mem::transmute(self)
},
);
reference_to_closure as &_
}
}
}
macro_rules! impl_readable_deref_arc {
($($ty:ident),*) => {
$(
impl<T: Clone + 'static> std::ops::Deref for $ty<T>
where
$ty<T>: crate::traits::Get<Value = T>,
T: Send + Sync,
{
type Target = dyn Fn() -> T + Send + Sync;
fn deref(&self) -> &Self::Target {
unsafe { readable_deref_impl::ReadableDerefImpl::deref_impl(self) }
}
}
impl<T: Clone + 'static> readable_deref_impl::ReadableDerefImpl for $ty<T>
where
$ty<T>: crate::traits::Get<Value = T>,
{
}
impl<T: Clone + 'static> crate::signal_or_fn::SignalOrFn for $ty<T>
where
$ty<T>: crate::traits::Get<Value = T>,
{
type Output = T;
fn run(&self) -> T {
crate::traits::Get::get(self)
}
}
)*
};
}
macro_rules! impl_readable_deref_arena {
($($ty:ident),*) => {
$(
impl<T: Clone + 'static, S: Storage<T> + 'static> std::ops::Deref for $ty<T, S>
where
$ty<T, S>: crate::traits::Get<Value = T>,
{
type Target = dyn Fn() -> T + Send + Sync;
fn deref(&self) -> &Self::Target {
unsafe { readable_deref_impl::ReadableDerefImpl::deref_impl(self) }
}
}
impl<T: Clone + 'static, S: Storage<T> + 'static> readable_deref_impl::ReadableDerefImpl for $ty<T, S>
where
$ty<T, S>: crate::traits::Get<Value = T>,
{
}
impl<T: Clone + 'static, S: Storage<T> + 'static> crate::signal_or_fn::SignalOrFn for $ty<T, S>
where
$ty<T, S>: crate::traits::Get<Value = T>,
{
type Output = T;
fn run(&self) -> T {
crate::traits::Get::get(self)
}
}
)*
};
}
macro_rules! impl_readable_deref_arena_signal_types {
($($ty:ident),*) => {
$(
#[allow(deprecated)]
impl<T: Clone + 'static, S: Storage<T> + Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>> + 'static> std::ops::Deref
for $ty<T, S>
where
$ty<T, S>: crate::traits::Get<Value = T>,
T: Send + Sync,
{
type Target = dyn Fn() -> T + Send + Sync;
fn deref(&self) -> &Self::Target {
unsafe { readable_deref_impl::ReadableDerefImpl::deref_impl(self) }
}
}
#[allow(deprecated)]
impl<T: Clone + 'static, S: Storage<T> + Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>> + 'static> readable_deref_impl::ReadableDerefImpl
for $ty<T, S>
where
$ty<T, S>: crate::traits::Get<Value = T>,
{
}
#[allow(deprecated)]
impl<T: Clone + 'static, S: Storage<T> + Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>> + 'static> crate::signal_or_fn::SignalOrFn
for $ty<T, S>
where
$ty<T, S>: crate::traits::Get<Value = T>,
{
type Output = T;
fn run(&self) -> T {
crate::traits::Get::get(self)
}
}
)*
};
}
impl_readable_deref_arc![ArcReadSignal, ArcRwSignal];
impl_readable_deref_arena![ReadSignal, RwSignal, Memo];
impl_readable_deref_arena_signal_types![
Signal,
ArcSignal,
ArcMemo,
MaybeSignal
];
#[allow(deprecated)]
impl<
T: Clone + 'static,
S: Storage<T>
+ Storage<Option<T>>
+ Storage<SignalTypes<Option<T>, S>>
+ 'static,
> std::ops::Deref for MaybeProp<T, S>
where
MaybeProp<T, S>: crate::traits::Get<Value = Option<T>>,
{
type Target = dyn Fn() -> Option<T> + Send + Sync;
fn deref(&self) -> &Self::Target {
unsafe { readable_deref_impl::ReadableDerefImpl::deref_impl(self) }
}
}
#[allow(deprecated)]
impl<
T: Clone + 'static,
S: Storage<T>
+ Storage<Option<T>>
+ Storage<SignalTypes<Option<T>, S>>
+ 'static,
> readable_deref_impl::ReadableDerefImpl for MaybeProp<T, S>
where
MaybeProp<T, S>: crate::traits::Get<Value = Option<T>>,
{
}
#[allow(deprecated)]
impl<T, S> crate::signal_or_fn::SignalOrFn for MaybeProp<T, S>
where
T: Clone + 'static,
MaybeProp<T, S>: crate::traits::Get<Value = Option<T>>,
S: Storage<Option<T>> + Storage<SignalTypes<Option<T>, S>>,
S: Send + Sync + 'static,
{
type Output = Option<T>;
fn run(&self) -> Option<T> {
crate::traits::Get::get(self)
}
}
macro_rules! impl_writable_deref_arc {
($($ty:ident),*) => {
$(
impl<T: 'static> std::ops::Deref for $ty<T>
where
T: Send + Sync,
$ty<T>: crate::traits::Set<Value = T>,
{
type Target = dyn Fn(T) + Send + Sync;
fn deref(&self) -> &Self::Target {
unsafe { writable_deref_impl::WritableDerefImpl::deref_impl(self) }
}
}
impl<T: 'static> writable_deref_impl::WritableDerefImpl for $ty<T>
where
$ty<T>: crate::traits::Set<Value = T>,
{
}
)*
};
}
impl_writable_deref_arc![ArcWriteSignal];
impl<T: 'static, S: Storage<ArcWriteSignal<T>> + 'static> std::ops::Deref
for WriteSignal<T, S>
where
WriteSignal<T, S>: crate::traits::Set<Value = T>,
{
type Target = dyn Fn(T) + Send + Sync;
fn deref(&self) -> &Self::Target {
unsafe { writable_deref_impl::WritableDerefImpl::deref_impl(self) }
}
}
impl<T: 'static, S: Storage<ArcWriteSignal<T>> + 'static>
writable_deref_impl::WritableDerefImpl for WriteSignal<T, S>
where
WriteSignal<T, S>: crate::traits::Set<Value = T>,
{
}
impl<
T: 'static,
S: Storage<ArcWriteSignal<T>>
+ Storage<Box<dyn Fn(T) + Send + Sync>>
+ 'static,
> std::ops::Deref for SignalSetter<T, S>
where
SignalSetter<T, S>: crate::traits::Set<Value = T>,
{
type Target = dyn Fn(T) + Send + Sync;
fn deref(&self) -> &Self::Target {
unsafe { writable_deref_impl::WritableDerefImpl::deref_impl(self) }
}
}
impl<
T: 'static,
S: Storage<ArcWriteSignal<T>>
+ Storage<Box<dyn Fn(T) + Send + Sync>>
+ 'static,
> writable_deref_impl::WritableDerefImpl for SignalSetter<T, S>
where
SignalSetter<T, S>: crate::traits::Set<Value = T>,
{
}