1pub use UseSignal as use_signal;
2
3use std::pin::Pin;
4
5use hooks_core::{Hook, HookPollNextUpdate, HookUnmount};
6
7use crate::{ShareValue, ToOwnedShareValue};
8
9mod sealed {
10 use hooks_core::{HookValue, HookValueBounds};
11
12 use crate::ShareValue;
13
14 use super::Signal;
15
16 pub trait HookValueImplSignal<'hook, ImplicitBounds: HookValueBounds<'hook, Self> = &'hook Self>:
17 HookValue<'hook, ImplicitBounds, Value = Self::HookValueImplSignal>
18 {
19 type HookValueImplShareValueValue;
20 type HookValueImplSignal: Signal<
21 SignalHook = Self,
22 Value = Self::HookValueImplShareValueValue,
23 >;
24 }
25
26 impl<'hook, H: ?Sized> HookValueImplSignal<'hook> for H
27 where
28 H: HookValue<'hook>,
29 H::Value: Signal<SignalHook = Self>,
30 {
31 type HookValueImplShareValueValue = <H::Value as ShareValue>::Value;
32 type HookValueImplSignal = H::Value;
33 }
34}
35
36pub trait SignalHook:
38 Hook
39 + Signal<Value = Self::SignalShareValue, SignalHook = Self>
40 + for<'hook> sealed::HookValueImplSignal<
41 'hook,
42 HookValueImplShareValueValue = Self::SignalShareValue,
43 >
44{
45 type SignalShareValue;
46
47 type SignalHookUninitialized: HookPollNextUpdate + HookUnmount + Default;
48
49 fn to_signal(&self) -> crate::Value<'_, Self>;
55}
56
57pub trait Signal: ShareValue {
58 type SignalHook: SignalHook<SignalShareValue = Self::Value>;
59
60 fn is_signal_of(&self, signal_hook: &Self::SignalHook) -> bool;
61
62 fn to_signal_hook(&self) -> Self::SignalHook;
64
65 fn update_signal_hook(&self, hook: Pin<&mut Self::SignalHook>);
66 fn h_signal_hook<'hook>(
67 &self,
68 hook: Pin<&'hook mut <Self::SignalHook as SignalHook>::SignalHookUninitialized>,
69 ) -> crate::Value<'hook, Self::SignalHook>;
70
71 fn use_signal(&self) -> UseSignal<'_, Self> {
72 UseSignal(self)
73 }
74
75 fn notify_changed(&self);
76
77 fn map_mut_and_notify_if<R>(&self, f: impl FnOnce(&mut Self::Value) -> (R, bool)) -> R;
78}
79
80impl<S: Signal + ?Sized> Signal for &S {
81 type SignalHook = S::SignalHook;
82
83 fn is_signal_of(&self, signal_hook: &Self::SignalHook) -> bool {
84 S::is_signal_of(self, signal_hook)
85 }
86 fn to_signal_hook(&self) -> Self::SignalHook {
87 S::to_signal_hook(self)
88 }
89 fn update_signal_hook(&self, hook: Pin<&mut Self::SignalHook>) {
90 S::update_signal_hook(self, hook)
91 }
92 fn h_signal_hook<'hook>(
93 &self,
94 hook: ::core::pin::Pin<
95 &'hook mut <Self::SignalHook as SignalHook>::SignalHookUninitialized,
96 >,
97 ) -> crate::Value<'hook, Self::SignalHook> {
98 S::h_signal_hook(self, hook)
99 }
100 fn notify_changed(&self) {
101 S::notify_changed(self)
102 }
103 fn map_mut_and_notify_if<R>(&self, f: impl FnOnce(&mut Self::Value) -> (R, bool)) -> R {
104 S::map_mut_and_notify_if(self, f)
105 }
106}
107
108pub struct UseSignal<'a, S: Signal + ?Sized>(&'a S);
109
110hooks_core::impl_hook!(
111 impl<S: Signal> UseSignal<'_, S> {
112 fn into_hook(self) -> S::SignalHook {
113 self.0.to_signal_hook()
114 }
115
116 fn update_hook(self, hook: _) {
117 self.0.update_signal_hook(hook)
118 }
119
120 fn h(self, hook: <S::SignalHook as SignalHook>::SignalHookUninitialized) {
121 self.0.h_signal_hook(hook)
122 }
123 }
124);
125
126pub trait ToOwnedSignal: Signal + ToOwnedShareValue<OwnedShareValue = Self::OwnedSignal> {
127 type OwnedSignal: Signal<SignalHook = Self::SignalHook, Value = Self::Value>;
128}
129
130impl<T: ?Sized + ToOwnedShareValue> ToOwnedSignal for T
132where
133 T: Signal,
134 T::OwnedShareValue: Signal<SignalHook = Self::SignalHook>,
135{
136 type OwnedSignal = T::OwnedShareValue;
137}