1use std::{ops::Deref, rc::Rc};
2
3use crate::{read::Readable, read_impls, ReadableRef};
4use dioxus_core::prelude::*;
5use generational_box::{AnyStorage, BorrowResult, UnsyncStorage};
6
7pub struct MappedSignal<O: ?Sized + 'static, S: AnyStorage = UnsyncStorage> {
9 try_read: Rc<dyn Fn() -> Result<S::Ref<'static, O>, generational_box::BorrowError> + 'static>,
10 try_peek: Rc<dyn Fn() -> Result<S::Ref<'static, O>, generational_box::BorrowError> + 'static>,
11}
12
13impl<O: ?Sized, S: AnyStorage> Clone for MappedSignal<O, S> {
14 fn clone(&self) -> Self {
15 MappedSignal {
16 try_read: self.try_read.clone(),
17 try_peek: self.try_peek.clone(),
18 }
19 }
20}
21
22impl<O, S> MappedSignal<O, S>
23where
24 O: ?Sized,
25 S: AnyStorage,
26{
27 pub(crate) fn new(
29 try_read: Rc<
30 dyn Fn() -> Result<S::Ref<'static, O>, generational_box::BorrowError> + 'static,
31 >,
32 try_peek: Rc<
33 dyn Fn() -> Result<S::Ref<'static, O>, generational_box::BorrowError> + 'static,
34 >,
35 ) -> Self {
36 MappedSignal { try_read, try_peek }
37 }
38}
39
40impl<O, S> Readable for MappedSignal<O, S>
41where
42 O: ?Sized,
43 S: AnyStorage,
44{
45 type Target = O;
46 type Storage = S;
47
48 fn try_read_unchecked(
49 &self,
50 ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> {
51 (self.try_read)()
52 }
53
54 fn try_peek_unchecked(&self) -> BorrowResult<ReadableRef<'static, Self>> {
55 (self.try_peek)()
56 }
57}
58
59impl<O, S> IntoAttributeValue for MappedSignal<O, S>
60where
61 O: Clone + IntoAttributeValue,
62 S: AnyStorage,
63{
64 fn into_value(self) -> dioxus_core::AttributeValue {
65 self.with(|f| f.clone().into_value())
66 }
67}
68
69impl<O, S> PartialEq for MappedSignal<O, S>
70where
71 O: ?Sized,
72 S: AnyStorage,
73{
74 fn eq(&self, other: &Self) -> bool {
75 std::ptr::eq(&self.try_peek, &other.try_peek)
76 && std::ptr::eq(&self.try_read, &other.try_read)
77 }
78}
79
80impl<O, S> Deref for MappedSignal<O, S>
84where
85 O: Clone,
86 S: AnyStorage + 'static,
87{
88 type Target = dyn Fn() -> O;
89
90 fn deref(&self) -> &Self::Target {
91 unsafe { Readable::deref_impl(self) }
92 }
93}
94
95read_impls!(MappedSignal<T, S: AnyStorage>);