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