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