1use std::pin::Pin;
2
3use hooks_core::{Hook, HookPollNextUpdate, HookUnmount, HookValue};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub struct SignalEq<S>(pub S);
17
18impl<H: HookUnmount + Unpin> HookUnmount for SignalEq<H> {
19 fn unmount(self: Pin<&mut Self>) {
20 H::unmount(Pin::new(&mut self.get_mut().0))
21 }
22}
23
24impl<H: HookPollNextUpdate + Unpin> HookPollNextUpdate for SignalEq<H> {
25 fn poll_next_update(
26 self: Pin<&mut Self>,
27 cx: &mut std::task::Context<'_>,
28 ) -> std::task::Poll<bool> {
29 H::poll_next_update(Pin::new(&mut self.get_mut().0), cx)
30 }
31}
32
33impl<'hook, H: HookValue<'hook> + Unpin> HookValue<'hook> for SignalEq<H> {
34 type Value = SignalEq<H::Value>;
35}
36
37impl<H: Hook + Unpin> Hook for SignalEq<H> {
38 fn use_hook(self: Pin<&mut Self>) -> <Self as HookValue<'_>>::Value {
39 SignalEq(H::use_hook(Pin::new(&mut self.get_mut().0)))
40 }
41}
42
43#[cfg(feature = "Signal")]
44impl<H: crate::SignalHook + Unpin> crate::SignalHook for SignalEq<H>
45where
46 H::SignalShareValue: PartialEq,
47{
48 type SignalShareValue = H::SignalShareValue;
49 type SignalHookUninitialized = H::SignalHookUninitialized;
50
51 fn to_signal(&self) -> SignalEq<crate::Value<'_, H>> {
52 SignalEq(self.0.to_signal())
53 }
54}
55
56#[cfg(feature = "Signal")]
57impl<S, T> crate::ShareValue for SignalEq<S>
58where
59 S: crate::Signal<Value = T>,
60 T: PartialEq,
61{
62 type Value = T;
63
64 crate::proxy_share_value_non_eq!(|self| -> S { &self.0 }, |other| &other.0);
65
66 fn try_unwrap(self) -> Result<Self::Value, Self>
67 where
68 Self: Sized,
69 {
70 self.0.try_unwrap().map_err(Self)
71 }
72
73 #[inline]
74 fn set(&self, new_value: T) {
75 self.0.map_mut_and_notify_if(move |old| {
76 let changed = *old != new_value;
77 *old = new_value;
78 ((), changed)
79 })
80 }
81
82 #[inline]
83 fn replace(&self, new_value: T) -> T {
84 self.0.map_mut_and_notify_if(move |old| {
85 let changed = *old != new_value;
86 let old = std::mem::replace(old, new_value);
87 (old, changed)
88 })
89 }
90
91 #[inline]
92 fn replace_with<F: FnOnce(&T) -> T>(&self, f: F) -> T {
93 self.0.map_mut_and_notify_if(move |v| {
94 let new_value = f(v);
95 let changed = new_value != *v;
96 let old = std::mem::replace(v, new_value);
97 (old, changed)
98 })
99 }
100}
101
102#[cfg(feature = "Signal")]
103impl<S> crate::Signal for SignalEq<S>
104where
105 S: crate::Signal,
106 S::Value: PartialEq,
107 S::SignalHook: Unpin,
108{
109 type SignalHook = SignalEq<S::SignalHook>;
110
111 fn is_signal_of(&self, signal_hook: &Self::SignalHook) -> bool {
112 self.0.is_signal_of(&signal_hook.0)
113 }
114
115 fn to_signal_hook(&self) -> Self::SignalHook {
116 SignalEq(self.0.to_signal_hook())
117 }
118
119 fn update_signal_hook(&self, hook: std::pin::Pin<&mut Self::SignalHook>) {
120 self.0.update_signal_hook(Pin::new(&mut hook.get_mut().0))
121 }
122
123 fn h_signal_hook<'hook>(
124 &self,
125 hook: std::pin::Pin<
126 &'hook mut <Self::SignalHook as crate::SignalHook>::SignalHookUninitialized,
127 >,
128 ) -> crate::Value<'hook, Self::SignalHook> {
129 SignalEq(self.0.h_signal_hook(hook))
130 }
131
132 fn notify_changed(&self) {
133 self.0.notify_changed()
134 }
135
136 fn map_mut_and_notify_if<R>(&self, f: impl FnOnce(&mut Self::Value) -> (R, bool)) -> R {
137 self.0.map_mut_and_notify_if(f)
138 }
139}
140
141#[cfg(feature = "Signal")]
142impl<S> crate::ToOwnedShareValue for SignalEq<S>
143where
144 S: crate::ToOwnedSignal,
145 S::Value: PartialEq,
146 S::SignalHook: Unpin,
147{
148 type OwnedShareValue = SignalEq<S::OwnedShareValue>;
149
150 #[inline]
151 fn to_owned_share_value(&self) -> Self::OwnedShareValue {
152 SignalEq(self.0.to_owned_share_value())
153 }
154}