1use crate::{
2 path::{StorePath, StorePathSegment},
3 ArcStore, AtIndex, AtKeyed, DerefedField, KeyMap, KeyedAccess,
4 KeyedSubfield, Store, StoreField, StoreFieldTrigger, Subfield,
5};
6use reactive_graph::{
7 owner::Storage,
8 traits::{
9 DefinedAt, IsDisposed, Notify, ReadUntracked, Track, UntrackableGuard,
10 Write,
11 },
12};
13use std::{
14 fmt::Debug,
15 hash::Hash,
16 ops::{Deref, DerefMut, IndexMut},
17 panic::Location,
18 sync::Arc,
19};
20
21pub struct ArcField<T>
26where
27 T: 'static,
28{
29 #[cfg(any(debug_assertions, leptos_debuginfo))]
30 defined_at: &'static Location<'static>,
31 path: Arc<dyn Fn() -> StorePath + Send + Sync>,
32 path_unkeyed: Arc<dyn Fn() -> StorePath + Send + Sync>,
33 get_trigger: Arc<dyn Fn(StorePath) -> StoreFieldTrigger + Send + Sync>,
34 get_trigger_unkeyed:
35 Arc<dyn Fn(StorePath) -> StoreFieldTrigger + Send + Sync>,
36 read: Arc<dyn Fn() -> Option<StoreFieldReader<T>> + Send + Sync>,
37 pub(crate) write:
38 Arc<dyn Fn() -> Option<StoreFieldWriter<T>> + Send + Sync>,
39 keys: Arc<dyn Fn() -> Option<KeyMap> + Send + Sync>,
40 track_field: Arc<dyn Fn() + Send + Sync>,
41 notify: Arc<dyn Fn() + Send + Sync>,
42}
43
44impl<T> Debug for ArcField<T>
45where
46 T: 'static,
47{
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 let mut f = f.debug_struct("ArcField");
50 #[cfg(any(debug_assertions, leptos_debuginfo))]
51 let f = f.field("defined_at", &self.defined_at);
52 f.finish_non_exhaustive()
53 }
54}
55
56pub struct StoreFieldReader<T>(Box<dyn Deref<Target = T>>);
57
58impl<T> StoreFieldReader<T> {
59 pub fn new(inner: impl Deref<Target = T> + 'static) -> Self {
60 Self(Box::new(inner))
61 }
62}
63
64impl<T> Deref for StoreFieldReader<T> {
65 type Target = T;
66
67 fn deref(&self) -> &Self::Target {
68 self.0.deref()
69 }
70}
71
72pub struct StoreFieldWriter<T>(Box<dyn UntrackableGuard<Target = T>>);
73
74impl<T> StoreFieldWriter<T> {
75 pub fn new(inner: impl UntrackableGuard<Target = T> + 'static) -> Self {
76 Self(Box::new(inner))
77 }
78}
79
80impl<T> Deref for StoreFieldWriter<T> {
81 type Target = T;
82
83 fn deref(&self) -> &Self::Target {
84 self.0.deref()
85 }
86}
87
88impl<T> DerefMut for StoreFieldWriter<T> {
89 fn deref_mut(&mut self) -> &mut Self::Target {
90 self.0.deref_mut()
91 }
92}
93
94impl<T> UntrackableGuard for StoreFieldWriter<T> {
95 fn untrack(&mut self) {
96 self.0.untrack();
97 }
98}
99
100impl<T> StoreField for ArcField<T> {
101 type Value = T;
102 type Reader = StoreFieldReader<T>;
103 type Writer = StoreFieldWriter<T>;
104
105 fn get_trigger(&self, path: StorePath) -> StoreFieldTrigger {
106 (self.get_trigger)(path)
107 }
108
109 fn get_trigger_unkeyed(&self, path: StorePath) -> StoreFieldTrigger {
110 (self.get_trigger_unkeyed)(path)
111 }
112
113 fn path(&self) -> impl IntoIterator<Item = StorePathSegment> {
114 (self.path)()
115 }
116
117 fn path_unkeyed(&self) -> impl IntoIterator<Item = StorePathSegment> {
118 (self.path_unkeyed)()
119 }
120
121 fn reader(&self) -> Option<Self::Reader> {
122 (self.read)().map(StoreFieldReader::new)
123 }
124
125 fn writer(&self) -> Option<Self::Writer> {
126 (self.write)().map(StoreFieldWriter::new)
127 }
128
129 fn keys(&self) -> Option<KeyMap> {
130 (self.keys)()
131 }
132}
133
134impl<T, S> From<Store<T, S>> for ArcField<T>
135where
136 T: 'static,
137 S: Storage<ArcStore<T>>,
138{
139 #[track_caller]
140 fn from(value: Store<T, S>) -> Self {
141 ArcField {
142 #[cfg(any(debug_assertions, leptos_debuginfo))]
143 defined_at: Location::caller(),
144 path: Arc::new(move || value.path().into_iter().collect()),
145 path_unkeyed: Arc::new(move || {
146 value.path_unkeyed().into_iter().collect()
147 }),
148 get_trigger: Arc::new(move |path| value.get_trigger(path)),
149 get_trigger_unkeyed: Arc::new(move |path| {
150 value.get_trigger_unkeyed(path)
151 }),
152 read: Arc::new(move || value.reader().map(StoreFieldReader::new)),
153 write: Arc::new(move || value.writer().map(StoreFieldWriter::new)),
154 keys: Arc::new(move || value.keys()),
155 track_field: Arc::new(move || value.track_field()),
156 notify: Arc::new(move || value.notify()),
157 }
158 }
159}
160
161impl<T> From<ArcStore<T>> for ArcField<T>
162where
163 T: Send + Sync + 'static,
164{
165 #[track_caller]
166 fn from(value: ArcStore<T>) -> Self {
167 ArcField {
168 #[cfg(any(debug_assertions, leptos_debuginfo))]
169 defined_at: Location::caller(),
170 path: Arc::new({
171 let value = value.clone();
172 move || value.path().into_iter().collect()
173 }),
174 path_unkeyed: Arc::new({
175 let value = value.clone();
176 move || value.path_unkeyed().into_iter().collect()
177 }),
178 get_trigger: Arc::new({
179 let value = value.clone();
180 move |path| value.get_trigger(path)
181 }),
182 get_trigger_unkeyed: Arc::new({
183 let value = value.clone();
184 move |path| value.get_trigger_unkeyed(path)
185 }),
186 read: Arc::new({
187 let value = value.clone();
188 move || value.reader().map(StoreFieldReader::new)
189 }),
190 write: Arc::new({
191 let value = value.clone();
192 move || value.writer().map(StoreFieldWriter::new)
193 }),
194 keys: Arc::new({
195 let value = value.clone();
196 move || value.keys()
197 }),
198 track_field: Arc::new({
199 let value = value.clone();
200 move || value.track_field()
201 }),
202 notify: Arc::new({
203 let value = value.clone();
204 move || value.notify()
205 }),
206 }
207 }
208}
209
210impl<Inner, Prev, T> From<Subfield<Inner, Prev, T>> for ArcField<T>
211where
212 T: Send + Sync,
213 Subfield<Inner, Prev, T>: Clone,
214 Inner: StoreField<Value = Prev> + Send + Sync + 'static,
215 Prev: 'static,
216{
217 #[track_caller]
218 fn from(value: Subfield<Inner, Prev, T>) -> Self {
219 ArcField {
220 #[cfg(any(debug_assertions, leptos_debuginfo))]
221 defined_at: Location::caller(),
222 path: Arc::new({
223 let value = value.clone();
224 move || value.path().into_iter().collect()
225 }),
226 path_unkeyed: Arc::new({
227 let value = value.clone();
228 move || value.path_unkeyed().into_iter().collect()
229 }),
230 get_trigger: Arc::new({
231 let value = value.clone();
232 move |path| value.get_trigger(path)
233 }),
234 get_trigger_unkeyed: Arc::new({
235 let value = value.clone();
236 move |path| value.get_trigger_unkeyed(path)
237 }),
238 read: Arc::new({
239 let value = value.clone();
240 move || value.reader().map(StoreFieldReader::new)
241 }),
242 write: Arc::new({
243 let value = value.clone();
244 move || value.writer().map(StoreFieldWriter::new)
245 }),
246 keys: Arc::new({
247 let value = value.clone();
248 move || value.keys()
249 }),
250 track_field: Arc::new({
251 let value = value.clone();
252 move || value.track_field()
253 }),
254 notify: Arc::new({
255 let value = value.clone();
256 move || value.notify()
257 }),
258 }
259 }
260}
261
262impl<Inner, T> From<DerefedField<Inner>> for ArcField<T>
263where
264 Inner: Clone + StoreField + Send + Sync + 'static,
265 Inner::Value: Deref<Target = T> + DerefMut,
266 T: Sized + 'static,
267{
268 #[track_caller]
269 fn from(value: DerefedField<Inner>) -> Self {
270 ArcField {
271 #[cfg(any(debug_assertions, leptos_debuginfo))]
272 defined_at: Location::caller(),
273 path: Arc::new({
274 let value = value.clone();
275 move || value.path().into_iter().collect()
276 }),
277 path_unkeyed: Arc::new({
278 let value = value.clone();
279 move || value.path_unkeyed().into_iter().collect()
280 }),
281 get_trigger: Arc::new({
282 let value = value.clone();
283 move |path| value.get_trigger(path)
284 }),
285 get_trigger_unkeyed: Arc::new({
286 let value = value.clone();
287 move |path| value.get_trigger_unkeyed(path)
288 }),
289 read: Arc::new({
290 let value = value.clone();
291 move || value.reader().map(StoreFieldReader::new)
292 }),
293 write: Arc::new({
294 let value = value.clone();
295 move || value.writer().map(StoreFieldWriter::new)
296 }),
297 keys: Arc::new({
298 let value = value.clone();
299 move || value.keys()
300 }),
301 track_field: Arc::new({
302 let value = value.clone();
303 move || value.track_field()
304 }),
305 notify: Arc::new({
306 let value = value.clone();
307 move || value.notify()
308 }),
309 }
310 }
311}
312
313impl<Inner, Prev> From<AtIndex<Inner, Prev>> for ArcField<Prev::Output>
314where
315 AtIndex<Inner, Prev>: Clone,
316 Inner: StoreField<Value = Prev> + Send + Sync + 'static,
317 Prev: IndexMut<usize> + Send + Sync + 'static,
318 Prev::Output: Sized + Send + Sync,
319{
320 #[track_caller]
321 fn from(value: AtIndex<Inner, Prev>) -> Self {
322 ArcField {
323 #[cfg(any(debug_assertions, leptos_debuginfo))]
324 defined_at: Location::caller(),
325 path: Arc::new({
326 let value = value.clone();
327 move || value.path().into_iter().collect()
328 }),
329 path_unkeyed: Arc::new({
330 let value = value.clone();
331 move || value.path_unkeyed().into_iter().collect()
332 }),
333 get_trigger: Arc::new({
334 let value = value.clone();
335 move |path| value.get_trigger(path)
336 }),
337 get_trigger_unkeyed: Arc::new({
338 let value = value.clone();
339 move |path| value.get_trigger_unkeyed(path)
340 }),
341 read: Arc::new({
342 let value = value.clone();
343 move || value.reader().map(StoreFieldReader::new)
344 }),
345 write: Arc::new({
346 let value = value.clone();
347 move || value.writer().map(StoreFieldWriter::new)
348 }),
349 keys: Arc::new({
350 let value = value.clone();
351 move || value.keys()
352 }),
353 track_field: Arc::new({
354 let value = value.clone();
355 move || value.track_field()
356 }),
357 notify: Arc::new({
358 let value = value.clone();
359 move || value.notify()
360 }),
361 }
362 }
363}
364
365impl<Inner, Prev, K, T> From<AtKeyed<Inner, Prev, K, T>> for ArcField<T::Value>
366where
367 AtKeyed<Inner, Prev, K, T>: Clone,
368 K: Clone + Debug + Send + Sync + PartialEq + Eq + Hash + 'static,
369 KeyedSubfield<Inner, Prev, K, T>: Clone,
370 for<'a> &'a T: IntoIterator,
371 Inner: StoreField<Value = Prev> + Send + Sync + 'static,
372 Prev: 'static,
373 T: KeyedAccess<K> + 'static,
374 T::Value: Sized,
375{
376 #[track_caller]
377 fn from(value: AtKeyed<Inner, Prev, K, T>) -> Self {
378 ArcField {
379 #[cfg(any(debug_assertions, leptos_debuginfo))]
380 defined_at: Location::caller(),
381 path: Arc::new({
382 let value = value.clone();
383 move || value.path().into_iter().collect()
384 }),
385 path_unkeyed: Arc::new({
386 let value = value.clone();
387 move || value.path_unkeyed().into_iter().collect()
388 }),
389 get_trigger: Arc::new({
390 let value = value.clone();
391 move |path| value.get_trigger(path)
392 }),
393 get_trigger_unkeyed: Arc::new({
394 let value = value.clone();
395 move |path| value.get_trigger_unkeyed(path)
396 }),
397 read: Arc::new({
398 let value = value.clone();
399 move || value.reader().map(StoreFieldReader::new)
400 }),
401 write: Arc::new({
402 let value = value.clone();
403 move || value.writer().map(StoreFieldWriter::new)
404 }),
405 keys: Arc::new({
406 let value = value.clone();
407 move || value.keys()
408 }),
409 track_field: Arc::new({
410 let value = value.clone();
411 move || value.track_field()
412 }),
413 notify: Arc::new({
414 let value = value.clone();
415 move || value.notify()
416 }),
417 }
418 }
419}
420
421impl<T> Clone for ArcField<T> {
422 fn clone(&self) -> Self {
423 Self {
424 #[cfg(any(debug_assertions, leptos_debuginfo))]
425 defined_at: self.defined_at,
426 path: self.path.clone(),
427 path_unkeyed: self.path_unkeyed.clone(),
428 get_trigger: Arc::clone(&self.get_trigger),
429 get_trigger_unkeyed: Arc::clone(&self.get_trigger_unkeyed),
430 read: Arc::clone(&self.read),
431 write: Arc::clone(&self.write),
432 keys: Arc::clone(&self.keys),
433 track_field: Arc::clone(&self.track_field),
434 notify: Arc::clone(&self.notify),
435 }
436 }
437}
438
439impl<T> DefinedAt for ArcField<T> {
440 fn defined_at(&self) -> Option<&'static Location<'static>> {
441 #[cfg(any(debug_assertions, leptos_debuginfo))]
442 {
443 Some(self.defined_at)
444 }
445 #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
446 {
447 None
448 }
449 }
450}
451
452impl<T> Notify for ArcField<T> {
453 fn notify(&self) {
454 (self.notify)()
455 }
456}
457
458impl<T> Track for ArcField<T> {
459 fn track(&self) {
460 (self.track_field)();
461 }
462}
463
464impl<T> ReadUntracked for ArcField<T> {
465 type Value = StoreFieldReader<T>;
466
467 fn try_read_untracked(&self) -> Option<Self::Value> {
468 (self.read)()
469 }
470}
471
472impl<T> Write for ArcField<T> {
473 type Value = T;
474
475 fn try_write(&self) -> Option<impl UntrackableGuard<Target = Self::Value>> {
476 (self.write)()
477 }
478
479 fn try_write_untracked(
480 &self,
481 ) -> Option<impl DerefMut<Target = Self::Value>> {
482 let mut guard = (self.write)()?;
483 guard.untrack();
484 Some(guard)
485 }
486}
487
488impl<T> IsDisposed for ArcField<T> {
489 fn is_disposed(&self) -> bool {
490 false
491 }
492}