leptos_use/core/
option_local_signal.rs1use leptos::prelude::*;
2use std::ops::{Deref, DerefMut};
3
4pub struct OptionLocalRwSignal<T> {
15 #[cfg(feature = "ssr")]
16 _data: std::marker::PhantomData<fn() -> T>,
17
18 #[cfg(not(feature = "ssr"))]
19 inner: RwSignal<Option<T>, LocalStorage>,
20
21 #[cfg(debug_assertions)]
22 defined_at: &'static std::panic::Location<'static>,
23}
24
25impl<T> OptionLocalRwSignal<T>
26where
27 T: 'static,
28{
29 #[track_caller]
30 pub fn new() -> Self {
31 Self {
32 #[cfg(feature = "ssr")]
33 _data: std::marker::PhantomData,
34
35 #[cfg(not(feature = "ssr"))]
36 inner: RwSignal::new_local(None),
37
38 #[cfg(debug_assertions)]
39 defined_at: std::panic::Location::caller(),
40 }
41 }
42
43 #[track_caller]
44 #[allow(unused_mut)]
45 pub fn read_only(mut self) -> OptionLocalSignal<T> {
46 #[cfg(not(feature = "ssr"))]
47 {
48 let new_inner = ArcRwSignal::from(self.inner);
51 self.inner = RwSignal::from_local(new_inner);
52 }
53
54 OptionLocalSignal {
55 inner: self,
56 #[cfg(debug_assertions)]
57 defined_at: std::panic::Location::caller(),
58 }
59 }
60}
61
62impl<T> Default for OptionLocalRwSignal<T>
63where
64 T: 'static,
65{
66 #[track_caller]
67 fn default() -> Self {
68 Self::new()
69 }
70}
71
72impl<T> Clone for OptionLocalRwSignal<T> {
73 fn clone(&self) -> Self {
74 *self
75 }
76}
77
78impl<T> Copy for OptionLocalRwSignal<T> {}
79
80impl<T> DefinedAt for OptionLocalRwSignal<T> {
81 #[inline(always)]
82 fn defined_at(&self) -> Option<&'static std::panic::Location<'static>> {
83 #[cfg(debug_assertions)]
84 {
85 Some(self.defined_at)
86 }
87
88 #[cfg(not(debug_assertions))]
89 {
90 None
91 }
92 }
93}
94
95#[cfg(feature = "ssr")]
99pub type OptionLocalGuard<T> = NoneGuard<T>;
100
101#[cfg(not(feature = "ssr"))]
102pub type OptionLocalGuard<T> = guards::ReadGuard<Option<T>, guards::Plain<Option<T>>>;
103
104impl<T> ReadUntracked for OptionLocalRwSignal<T>
105where
106 T: 'static,
107{
108 type Value = OptionLocalGuard<T>;
109
110 #[inline(always)]
111 fn try_read_untracked(&self) -> Option<Self::Value> {
112 #[cfg(feature = "ssr")]
113 {
114 Some(NoneGuard::default())
115 }
116 #[cfg(not(feature = "ssr"))]
117 {
118 self.inner.try_read_untracked()
119 }
120 }
121}
122
123impl<T> Track for OptionLocalRwSignal<T>
124where
125 T: 'static,
126{
127 #[inline(always)]
128 fn track(&self) {
129 #[cfg(feature = "ssr")]
130 {
131 }
133 #[cfg(not(feature = "ssr"))]
134 {
135 self.inner.track();
136 }
137 }
138}
139
140impl<T> Notify for OptionLocalRwSignal<T>
141where
142 T: 'static,
143{
144 #[inline(always)]
145 fn notify(&self) {
146 #[cfg(feature = "ssr")]
147 {
148 leptos::logging::warn!(
149 "Attempted to notify an OptionLocalRwSignal on the server; this has no effect."
150 );
151 }
152 #[cfg(not(feature = "ssr"))]
153 {
154 self.inner.notify();
155 }
156 }
157}
158
159impl<T> Write for OptionLocalRwSignal<T>
160where
161 T: 'static,
162{
163 type Value = Option<T>;
164
165 #[inline(always)]
166 fn try_write(&self) -> Option<impl UntrackableGuard<Target = Self::Value>> {
167 #[cfg(feature = "ssr")]
168 {
169 leptos::logging::warn!(
170 "Attempted to write to an OptionLocalRwSignal on the server; this has no effect."
171 );
172 None::<NoneGuard<T>>
173 }
174 #[cfg(not(feature = "ssr"))]
175 {
176 self.inner.try_write()
177 }
178 }
179
180 #[inline(always)]
181 fn try_write_untracked(&self) -> Option<impl DerefMut<Target = Self::Value>> {
182 #[cfg(feature = "ssr")]
183 {
184 leptos::logging::warn!(
185 "Attempted to write to an OptionLocalRwSignal on the server; this has no effect."
186 );
187 None::<NoneGuard<T>>
188 }
189 #[cfg(not(feature = "ssr"))]
190 {
191 self.inner.try_write_untracked()
192 }
193 }
194}
195
196impl<T> IsDisposed for OptionLocalRwSignal<T>
197where
198 T: 'static,
199{
200 #[inline(always)]
201 fn is_disposed(&self) -> bool {
202 #[cfg(feature = "ssr")]
203 {
204 false
205 }
206 #[cfg(not(feature = "ssr"))]
207 {
208 self.inner.is_disposed()
209 }
210 }
211}
212
213pub struct NoneGuard<T> {
217 _data: std::marker::PhantomData<T>,
218}
219
220impl<T> Default for NoneGuard<T> {
221 fn default() -> Self {
222 Self {
223 _data: std::marker::PhantomData,
224 }
225 }
226}
227
228impl<T> Deref for NoneGuard<T> {
229 type Target = Option<T>;
230
231 fn deref(&self) -> &Self::Target {
232 &None
233 }
234}
235
236impl<T> DerefMut for NoneGuard<T> {
238 fn deref_mut(&mut self) -> &mut Self::Target {
239 panic!("Attempted to mutably dereference a NoneGuard");
240 }
241}
242
243impl<T> UntrackableGuard for NoneGuard<T> {
245 fn untrack(&mut self) {
246 panic!("Attempted to untrack a NoneGuard");
247 }
248}
249
250pub struct OptionLocalSignal<T> {
252 #[cfg(debug_assertions)]
253 defined_at: &'static std::panic::Location<'static>,
254
255 inner: OptionLocalRwSignal<T>,
256}
257
258impl<T> Clone for OptionLocalSignal<T> {
259 fn clone(&self) -> Self {
260 *self
261 }
262}
263
264impl<T> Copy for OptionLocalSignal<T> {}
265
266impl<T> DefinedAt for OptionLocalSignal<T> {
267 #[inline(always)]
268 fn defined_at(&self) -> Option<&'static std::panic::Location<'static>> {
269 #[cfg(debug_assertions)]
270 {
271 Some(self.defined_at)
272 }
273 #[cfg(not(debug_assertions))]
274 {
275 None
276 }
277 }
278}
279
280impl<T> ReadUntracked for OptionLocalSignal<T>
281where
282 T: 'static,
283{
284 type Value = OptionLocalGuard<T>;
285
286 #[inline(always)]
287 fn try_read_untracked(&self) -> Option<Self::Value> {
288 self.inner.try_read_untracked()
289 }
290}
291
292impl<T> Track for OptionLocalSignal<T>
293where
294 T: 'static,
295{
296 #[inline(always)]
297 fn track(&self) {
298 self.inner.track();
299 }
300}