dioxus_signals/
map.rs

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
7/// A read only signal that has been mapped to a new type.
8pub 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    /// Create a new mapped signal.
28    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
80/// Allow calling a signal with signal() syntax
81///
82/// Currently only limited to copy types, though could probably specialize for string/arc/rc
83impl<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>);