1use std::sync::Arc;
2use std::marker::PhantomData;
3use std::any::{Any, TypeId};
4use std::rc::Rc;
5
6#[derive(Clone)]
8pub struct KeyPath<Root, Value, F>
9where
10 F: for<'r> Fn(&'r Root) -> &'r Value,
11{
12 getter: F,
13 _phantom: PhantomData<(Root, Value)>,
14}
15
16impl<Root, Value, F> KeyPath<Root, Value, F>
17where
18 F: for<'r> Fn(&'r Root) -> &'r Value,
19{
20 pub fn new(getter: F) -> Self {
21 Self {
22 getter,
23 _phantom: PhantomData,
24 }
25 }
26
27 pub fn get<'r>(&self, root: &'r Root) -> &'r Value {
28 (self.getter)(root)
29}
30
31 pub fn for_box<Target>(self) -> KeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> &'r Target + 'static>
34 where
35 Value: std::ops::Deref<Target = Target>,
36 F: 'static,
37 Value: 'static,
38 {
39 let getter = self.getter;
40
41 KeyPath {
42 getter: move |root: &Root| {
43 getter(root).deref()
44 },
45 _phantom: PhantomData,
46 }
47 }
48
49 pub fn for_arc<Target>(self) -> KeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> &'r Target + 'static>
51 where
52 Value: std::ops::Deref<Target = Target>,
53 F: 'static,
54 Value: 'static,
55 {
56 let getter = self.getter;
57
58 KeyPath {
59 getter: move |root: &Root| {
60 getter(root).deref()
61 },
62 _phantom: PhantomData,
63 }
64 }
65
66 pub fn for_rc<Target>(self) -> KeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> &'r Target + 'static>
68 where
69 Value: std::ops::Deref<Target = Target>,
70 F: 'static,
71 Value: 'static,
72 {
73 let getter = self.getter;
74
75 KeyPath {
76 getter: move |root: &Root| {
77 getter(root).deref()
78 },
79 _phantom: PhantomData,
80 }
81 }
82
83}
84
85pub fn for_slice<T>() -> impl for<'r> Fn(&'r [T], usize) -> Option<&'r T> {
87 |slice: &[T], index: usize| slice.get(index)
88}
89
90pub mod containers {
92 use super::{OptionalKeyPath, WritableOptionalKeyPath, KeyPath, WritableKeyPath};
93 use std::collections::{HashMap, BTreeMap, HashSet, BTreeSet, VecDeque, LinkedList, BinaryHeap};
94 use std::sync::{Mutex, RwLock, Weak as StdWeak, Arc};
95 use std::rc::{Weak as RcWeak, Rc};
96 use std::ops::{Deref, DerefMut};
97
98 #[cfg(feature = "parking_lot")]
99 use parking_lot::{Mutex as ParkingMutex, RwLock as ParkingRwLock};
100
101 #[cfg(feature = "tagged")]
102 use tagged_core::Tagged;
103
104 pub fn for_vec_index<T>(index: usize) -> OptionalKeyPath<Vec<T>, T, impl for<'r> Fn(&'r Vec<T>) -> Option<&'r T>> {
106 OptionalKeyPath::new(move |vec: &Vec<T>| vec.get(index))
107 }
108
109 pub fn for_vecdeque_index<T>(index: usize) -> OptionalKeyPath<VecDeque<T>, T, impl for<'r> Fn(&'r VecDeque<T>) -> Option<&'r T>> {
111 OptionalKeyPath::new(move |deque: &VecDeque<T>| deque.get(index))
112 }
113
114 pub fn for_linkedlist_index<T>(index: usize) -> OptionalKeyPath<LinkedList<T>, T, impl for<'r> Fn(&'r LinkedList<T>) -> Option<&'r T>> {
116 OptionalKeyPath::new(move |list: &LinkedList<T>| {
117 list.iter().nth(index)
118 })
119 }
120
121 pub fn for_hashmap_key<K, V>(key: K) -> OptionalKeyPath<HashMap<K, V>, V, impl for<'r> Fn(&'r HashMap<K, V>) -> Option<&'r V>>
123 where
124 K: std::hash::Hash + Eq + Clone + 'static,
125 V: 'static,
126 {
127 OptionalKeyPath::new(move |map: &HashMap<K, V>| map.get(&key))
128 }
129
130 pub fn for_btreemap_key<K, V>(key: K) -> OptionalKeyPath<BTreeMap<K, V>, V, impl for<'r> Fn(&'r BTreeMap<K, V>) -> Option<&'r V>>
132 where
133 K: Ord + Clone + 'static,
134 V: 'static,
135 {
136 OptionalKeyPath::new(move |map: &BTreeMap<K, V>| map.get(&key))
137 }
138
139 pub fn for_hashset_get<T>(value: T) -> OptionalKeyPath<HashSet<T>, T, impl for<'r> Fn(&'r HashSet<T>) -> Option<&'r T>>
141 where
142 T: std::hash::Hash + Eq + Clone + 'static,
143 {
144 OptionalKeyPath::new(move |set: &HashSet<T>| set.get(&value))
145 }
146
147 pub fn for_btreeset_get<T>(value: T) -> OptionalKeyPath<BTreeSet<T>, T, impl for<'r> Fn(&'r BTreeSet<T>) -> Option<&'r T>>
149 where
150 T: Ord + Clone + 'static,
151 {
152 OptionalKeyPath::new(move |set: &BTreeSet<T>| set.get(&value))
153 }
154
155 pub fn for_binaryheap_peek<T>() -> OptionalKeyPath<BinaryHeap<T>, T, impl for<'r> Fn(&'r BinaryHeap<T>) -> Option<&'r T>>
157 where
158 T: Ord + 'static,
159 {
160 OptionalKeyPath::new(|heap: &BinaryHeap<T>| heap.peek())
161 }
162
163 pub fn for_vec_index_mut<T>(index: usize) -> WritableOptionalKeyPath<Vec<T>, T, impl for<'r> Fn(&'r mut Vec<T>) -> Option<&'r mut T>> {
167 WritableOptionalKeyPath::new(move |vec: &mut Vec<T>| vec.get_mut(index))
168 }
169
170 pub fn for_vecdeque_index_mut<T>(index: usize) -> WritableOptionalKeyPath<VecDeque<T>, T, impl for<'r> Fn(&'r mut VecDeque<T>) -> Option<&'r mut T>> {
172 WritableOptionalKeyPath::new(move |deque: &mut VecDeque<T>| deque.get_mut(index))
173 }
174
175 pub fn for_linkedlist_index_mut<T>(index: usize) -> WritableOptionalKeyPath<LinkedList<T>, T, impl for<'r> Fn(&'r mut LinkedList<T>) -> Option<&'r mut T>> {
177 WritableOptionalKeyPath::new(move |list: &mut LinkedList<T>| {
178 let mut iter = list.iter_mut();
180 iter.nth(index)
181 })
182 }
183
184 pub fn for_hashmap_key_mut<K, V>(key: K) -> WritableOptionalKeyPath<HashMap<K, V>, V, impl for<'r> Fn(&'r mut HashMap<K, V>) -> Option<&'r mut V>>
186 where
187 K: std::hash::Hash + Eq + Clone + 'static,
188 V: 'static,
189 {
190 WritableOptionalKeyPath::new(move |map: &mut HashMap<K, V>| map.get_mut(&key))
191 }
192
193 pub fn for_btreemap_key_mut<K, V>(key: K) -> WritableOptionalKeyPath<BTreeMap<K, V>, V, impl for<'r> Fn(&'r mut BTreeMap<K, V>) -> Option<&'r mut V>>
195 where
196 K: Ord + Clone + 'static,
197 V: 'static,
198 {
199 WritableOptionalKeyPath::new(move |map: &mut BTreeMap<K, V>| map.get_mut(&key))
200 }
201
202 pub fn for_hashset_get_mut<T>(value: T) -> WritableOptionalKeyPath<HashSet<T>, T, impl for<'r> Fn(&'r mut HashSet<T>) -> Option<&'r mut T>>
205 where
206 T: std::hash::Hash + Eq + Clone + 'static,
207 {
208 WritableOptionalKeyPath::new(move |set: &mut HashSet<T>| {
209 if set.contains(&value) {
212 None
215 } else {
216 None
217 }
218 })
219 }
220
221 pub fn for_btreeset_get_mut<T>(value: T) -> WritableOptionalKeyPath<BTreeSet<T>, T, impl for<'r> Fn(&'r mut BTreeSet<T>) -> Option<&'r mut T>>
224 where
225 T: Ord + Clone + 'static,
226 {
227 WritableOptionalKeyPath::new(move |set: &mut BTreeSet<T>| {
228 if set.contains(&value) {
231 None
234 } else {
235 None
236 }
237 })
238 }
239
240 pub fn for_binaryheap_peek_mut<T>() -> WritableOptionalKeyPath<BinaryHeap<T>, T, impl for<'r> Fn(&'r mut BinaryHeap<T>) -> Option<&'r mut T>>
246 where
247 T: Ord + 'static,
248 {
249 WritableOptionalKeyPath::new(|_heap: &mut BinaryHeap<T>| {
253 None
254 })
255 }
256
257 pub fn lock_mutex<T>(mutex: &Mutex<T>) -> Option<std::sync::MutexGuard<'_, T>> {
266 mutex.lock().ok()
267 }
268
269 pub fn read_rwlock<T>(rwlock: &RwLock<T>) -> Option<std::sync::RwLockReadGuard<'_, T>> {
273 rwlock.read().ok()
274 }
275
276 pub fn write_rwlock<T>(rwlock: &RwLock<T>) -> Option<std::sync::RwLockWriteGuard<'_, T>> {
280 rwlock.write().ok()
281 }
282
283 pub fn lock_arc_mutex<T>(arc_mutex: &Arc<Mutex<T>>) -> Option<std::sync::MutexGuard<'_, T>> {
287 arc_mutex.lock().ok()
288 }
289
290 pub fn read_arc_rwlock<T>(arc_rwlock: &Arc<RwLock<T>>) -> Option<std::sync::RwLockReadGuard<'_, T>> {
294 arc_rwlock.read().ok()
295 }
296
297 pub fn write_arc_rwlock<T>(arc_rwlock: &Arc<RwLock<T>>) -> Option<std::sync::RwLockWriteGuard<'_, T>> {
301 arc_rwlock.write().ok()
302 }
303
304 pub fn upgrade_weak<T>(weak: &StdWeak<T>) -> Option<Arc<T>> {
308 weak.upgrade()
309 }
310
311 pub fn upgrade_rc_weak<T>(weak: &RcWeak<T>) -> Option<Rc<T>> {
315 weak.upgrade()
316 }
317
318 #[cfg(feature = "parking_lot")]
319 pub fn lock_parking_mutex<T>(mutex: &ParkingMutex<T>) -> parking_lot::MutexGuard<'_, T> {
322 mutex.lock()
323 }
324
325 #[cfg(feature = "parking_lot")]
326 pub fn read_parking_rwlock<T>(rwlock: &ParkingRwLock<T>) -> parking_lot::RwLockReadGuard<'_, T> {
329 rwlock.read()
330 }
331
332 #[cfg(feature = "parking_lot")]
333 pub fn write_parking_rwlock<T>(rwlock: &ParkingRwLock<T>) -> parking_lot::RwLockWriteGuard<'_, T> {
336 rwlock.write()
337 }
338
339 #[cfg(feature = "tagged")]
340 pub fn for_tagged<Tag, T>() -> KeyPath<Tagged<Tag, T>, T, impl for<'r> Fn(&'r Tagged<Tag, T>) -> &'r T>
343 where
344 Tagged<Tag, T>: std::ops::Deref<Target = T>,
345 Tag: 'static,
346 T: 'static,
347 {
348 KeyPath::new(|tagged: &Tagged<Tag, T>| tagged.deref())
349 }
350
351 #[cfg(feature = "tagged")]
352 pub fn for_tagged_mut<Tag, T>() -> WritableKeyPath<Tagged<Tag, T>, T, impl for<'r> Fn(&'r mut Tagged<Tag, T>) -> &'r mut T>
355 where
356 Tagged<Tag, T>: std::ops::DerefMut<Target = T>,
357 Tag: 'static,
358 T: 'static,
359 {
360 WritableKeyPath::new(|tagged: &mut Tagged<Tag, T>| tagged.deref_mut())
361 }
362}
363
364#[derive(Clone)]
366pub struct OptionalKeyPath<Root, Value, F>
367where
368 F: for<'r> Fn(&'r Root) -> Option<&'r Value>,
369{
370 getter: F,
371 _phantom: PhantomData<(Root, Value)>,
372}
373
374impl<Root, Value, F> OptionalKeyPath<Root, Value, F>
375where
376 F: for<'r> Fn(&'r Root) -> Option<&'r Value>,
377{
378 pub fn new(getter: F) -> Self {
379 Self {
380 getter,
381 _phantom: PhantomData,
382 }
383 }
384
385 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r Value> {
386 (self.getter)(root)
387 }
388
389 pub fn then<SubValue, G>(
391 self,
392 next: OptionalKeyPath<Value, SubValue, G>,
393 ) -> OptionalKeyPath<Root, SubValue, impl for<'r> Fn(&'r Root) -> Option<&'r SubValue>>
394 where
395 G: for<'r> Fn(&'r Value) -> Option<&'r SubValue>,
396 F: 'static,
397 G: 'static,
398 Value: 'static,
399 {
400 let first = self.getter;
401 let second = next.getter;
402
403 OptionalKeyPath::new(move |root: &Root| {
404 first(root).and_then(|value| second(value))
405 })
406 }
407
408 pub fn for_box<Target>(self) -> OptionalKeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> Option<&'r Target> + 'static>
411 where
412 Value: std::ops::Deref<Target = Target>,
413 F: 'static,
414 Value: 'static,
415 {
416 let getter = self.getter;
417
418 OptionalKeyPath {
419 getter: move |root: &Root| {
420 getter(root).map(|boxed| boxed.deref())
421 },
422 _phantom: PhantomData,
423 }
424 }
425
426 pub fn for_arc<Target>(self) -> OptionalKeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> Option<&'r Target> + 'static>
428 where
429 Value: std::ops::Deref<Target = Target>,
430 F: 'static,
431 Value: 'static,
432 {
433 let getter = self.getter;
434
435 OptionalKeyPath {
436 getter: move |root: &Root| {
437 getter(root).map(|arc| arc.deref())
438 },
439 _phantom: PhantomData,
440 }
441 }
442
443 pub fn for_rc<Target>(self) -> OptionalKeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> Option<&'r Target> + 'static>
445 where
446 Value: std::ops::Deref<Target = Target>,
447 F: 'static,
448 Value: 'static,
449 {
450 let getter = self.getter;
451
452 OptionalKeyPath {
453 getter: move |root: &Root| {
454 getter(root).map(|rc| rc.deref())
455 },
456 _phantom: PhantomData,
457 }
458 }
459
460 pub fn for_option<T>() -> OptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r Option<T>) -> Option<&'r T>> {
462 OptionalKeyPath::new(|opt: &Option<T>| opt.as_ref())
463 }
464}
465
466#[derive(Clone)]
468pub struct WritableKeyPath<Root, Value, F>
469where
470 F: for<'r> Fn(&'r mut Root) -> &'r mut Value,
471{
472 getter: F,
473 _phantom: PhantomData<(Root, Value)>,
474}
475
476impl<Root, Value, F> WritableKeyPath<Root, Value, F>
477where
478 F: for<'r> Fn(&'r mut Root) -> &'r mut Value,
479{
480 pub fn new(getter: F) -> Self {
481 Self {
482 getter,
483 _phantom: PhantomData,
484 }
485 }
486
487 pub fn get_mut<'r>(&self, root: &'r mut Root) -> &'r mut Value {
488 (self.getter)(root)
489 }
490
491 pub fn for_box<Target>(self) -> WritableKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> &'r mut Target + 'static>
494 where
495 Value: std::ops::DerefMut<Target = Target>,
496 F: 'static,
497 Value: 'static,
498 {
499 let getter = self.getter;
500
501 WritableKeyPath {
502 getter: move |root: &mut Root| {
503 getter(root).deref_mut()
504 },
505 _phantom: PhantomData,
506 }
507 }
508
509 pub fn for_arc<Target>(self) -> WritableKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> &'r mut Target + 'static>
512 where
513 Value: std::ops::DerefMut<Target = Target>,
514 F: 'static,
515 Value: 'static,
516 {
517 let getter = self.getter;
518
519 WritableKeyPath {
520 getter: move |root: &mut Root| {
521 getter(root).deref_mut()
522 },
523 _phantom: PhantomData,
524 }
525 }
526
527 pub fn for_rc<Target>(self) -> WritableKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> &'r mut Target + 'static>
530 where
531 Value: std::ops::DerefMut<Target = Target>,
532 F: 'static,
533 Value: 'static,
534 {
535 let getter = self.getter;
536
537 WritableKeyPath {
538 getter: move |root: &mut Root| {
539 getter(root).deref_mut()
540 },
541 _phantom: PhantomData,
542 }
543 }
544}
545
546#[derive(Clone)]
548pub struct WritableOptionalKeyPath<Root, Value, F>
549where
550 F: for<'r> Fn(&'r mut Root) -> Option<&'r mut Value>,
551{
552 getter: F,
553 _phantom: PhantomData<(Root, Value)>,
554}
555
556impl<Root, Value, F> WritableOptionalKeyPath<Root, Value, F>
557where
558 F: for<'r> Fn(&'r mut Root) -> Option<&'r mut Value>,
559{
560 pub fn new(getter: F) -> Self {
561 Self {
562 getter,
563 _phantom: PhantomData,
564 }
565 }
566
567 pub fn get_mut<'r>(&self, root: &'r mut Root) -> Option<&'r mut Value> {
568 (self.getter)(root)
569 }
570
571 pub fn then<SubValue, G>(
573 self,
574 next: WritableOptionalKeyPath<Value, SubValue, G>,
575 ) -> WritableOptionalKeyPath<Root, SubValue, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut SubValue>>
576 where
577 G: for<'r> Fn(&'r mut Value) -> Option<&'r mut SubValue>,
578 F: 'static,
579 G: 'static,
580 Value: 'static,
581 {
582 let first = self.getter;
583 let second = next.getter;
584
585 WritableOptionalKeyPath::new(move |root: &mut Root| {
586 first(root).and_then(|value| second(value))
587 })
588 }
589
590 pub fn for_box<Target>(self) -> WritableOptionalKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Target> + 'static>
593 where
594 Value: std::ops::DerefMut<Target = Target>,
595 F: 'static,
596 Value: 'static,
597 {
598 let getter = self.getter;
599
600 WritableOptionalKeyPath {
601 getter: move |root: &mut Root| {
602 getter(root).map(|boxed| boxed.deref_mut())
603 },
604 _phantom: PhantomData,
605 }
606 }
607
608 pub fn for_arc<Target>(self) -> WritableOptionalKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Target> + 'static>
610 where
611 Value: std::ops::DerefMut<Target = Target>,
612 F: 'static,
613 Value: 'static,
614 {
615 let getter = self.getter;
616
617 WritableOptionalKeyPath {
618 getter: move |root: &mut Root| {
619 getter(root).map(|arc| arc.deref_mut())
620 },
621 _phantom: PhantomData,
622 }
623 }
624
625 pub fn for_rc<Target>(self) -> WritableOptionalKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Target> + 'static>
627 where
628 Value: std::ops::DerefMut<Target = Target>,
629 F: 'static,
630 Value: 'static,
631 {
632 let getter = self.getter;
633
634 WritableOptionalKeyPath {
635 getter: move |root: &mut Root| {
636 getter(root).map(|rc| rc.deref_mut())
637 },
638 _phantom: PhantomData,
639 }
640 }
641
642 pub fn for_option<T>() -> WritableOptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r mut Option<T>) -> Option<&'r mut T>> {
644 WritableOptionalKeyPath::new(|opt: &mut Option<T>| opt.as_mut())
645 }
646}
647
648#[derive(Clone)]
650pub struct EnumKeyPaths;
651
652impl EnumKeyPaths {
653 pub fn for_variant<Enum, Variant, ExtractFn>(
655 extractor: ExtractFn
656 ) -> OptionalKeyPath<Enum, Variant, impl for<'r> Fn(&'r Enum) -> Option<&'r Variant>>
657 where
658 ExtractFn: Fn(&Enum) -> Option<&Variant>,
659 {
660 OptionalKeyPath::new(extractor)
661 }
662
663 pub fn for_match<Enum, Output, MatchFn>(
665 matcher: MatchFn
666 ) -> KeyPath<Enum, Output, impl for<'r> Fn(&'r Enum) -> &'r Output>
667 where
668 MatchFn: Fn(&Enum) -> &Output,
669 {
670 KeyPath::new(matcher)
671 }
672
673 pub fn for_ok<T, E>() -> OptionalKeyPath<Result<T, E>, T, impl for<'r> Fn(&'r Result<T, E>) -> Option<&'r T>> {
675 OptionalKeyPath::new(|result: &Result<T, E>| result.as_ref().ok())
676 }
677
678 pub fn for_err<T, E>() -> OptionalKeyPath<Result<T, E>, E, impl for<'r> Fn(&'r Result<T, E>) -> Option<&'r E>> {
679 OptionalKeyPath::new(|result: &Result<T, E>| result.as_ref().err())
680 }
681
682 pub fn for_some<T>() -> OptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r Option<T>) -> Option<&'r T>> {
684 OptionalKeyPath::new(|opt: &Option<T>| opt.as_ref())
685 }
686
687 pub fn for_option<T>() -> OptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r Option<T>) -> Option<&'r T>> {
689 OptionalKeyPath::new(|opt: &Option<T>| opt.as_ref())
690 }
691
692 pub fn for_box<T>() -> KeyPath<Box<T>, T, impl for<'r> Fn(&'r Box<T>) -> &'r T> {
695 KeyPath::new(|b: &Box<T>| b.as_ref())
696 }
697
698 pub fn for_arc<T>() -> KeyPath<Arc<T>, T, impl for<'r> Fn(&'r Arc<T>) -> &'r T> {
700 KeyPath::new(|arc: &Arc<T>| arc.as_ref())
701 }
702
703 pub fn for_rc<T>() -> KeyPath<std::rc::Rc<T>, T, impl for<'r> Fn(&'r std::rc::Rc<T>) -> &'r T> {
705 KeyPath::new(|rc: &std::rc::Rc<T>| rc.as_ref())
706 }
707
708 pub fn for_box_mut<T>() -> WritableKeyPath<Box<T>, T, impl for<'r> Fn(&'r mut Box<T>) -> &'r mut T> {
711 WritableKeyPath::new(|b: &mut Box<T>| b.as_mut())
712 }
713
714 }
718
719pub fn variant_of<Enum, Variant, F>(extractor: F) -> OptionalKeyPath<Enum, Variant, F>
721where
722 F: for<'r> Fn(&'r Enum) -> Option<&'r Variant>,
723{
724 OptionalKeyPath::new(extractor)
725}
726
727#[derive(Clone)]
743pub struct PartialKeyPath<Root> {
744 getter: Rc<dyn for<'r> Fn(&'r Root) -> &'r dyn Any>,
745 value_type_id: TypeId,
746 _phantom: PhantomData<Root>,
747}
748
749impl<Root> PartialKeyPath<Root> {
750 pub fn new<Value>(keypath: KeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> &'r Value + 'static>) -> Self
751 where
752 Value: Any + 'static,
753 Root: 'static,
754 {
755 let value_type_id = TypeId::of::<Value>();
756 let getter = Rc::new(keypath.getter);
757
758 Self {
759 getter: Rc::new(move |root: &Root| {
760 let value: &Value = getter(root);
761 value as &dyn Any
762 }),
763 value_type_id,
764 _phantom: PhantomData,
765 }
766 }
767
768 pub fn from<Value>(keypath: KeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> &'r Value + 'static>) -> Self
771 where
772 Value: Any + 'static,
773 Root: 'static,
774 {
775 Self::new(keypath)
776 }
777
778 pub fn get<'r>(&self, root: &'r Root) -> &'r dyn Any {
779 (self.getter)(root)
780 }
781
782 pub fn value_type_id(&self) -> TypeId {
784 self.value_type_id
785 }
786
787 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
789 if self.value_type_id == TypeId::of::<Value>() {
790 self.get(root).downcast_ref::<Value>()
791 } else {
792 None
793 }
794 }
795}
796
797#[derive(Clone)]
804pub struct PartialOptionalKeyPath<Root> {
805 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
806 value_type_id: TypeId,
807 _phantom: PhantomData<Root>,
808}
809
810impl<Root> PartialOptionalKeyPath<Root> {
811 pub fn new<Value>(keypath: OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>) -> Self
812 where
813 Value: Any + 'static,
814 Root: 'static,
815 {
816 let value_type_id = TypeId::of::<Value>();
817 let getter = Rc::new(keypath.getter);
818
819 Self {
820 getter: Rc::new(move |root: &Root| {
821 getter(root).map(|value: &Value| value as &dyn Any)
822 }),
823 value_type_id,
824 _phantom: PhantomData,
825 }
826 }
827
828 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
829 (self.getter)(root)
830 }
831
832 pub fn value_type_id(&self) -> TypeId {
834 self.value_type_id
835 }
836
837 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
839 if self.value_type_id == TypeId::of::<Value>() {
840 self.get(root).map(|any| any.downcast_ref::<Value>())
841 } else {
842 None
843 }
844 }
845
846 pub fn then<MidValue>(
850 self,
851 next: PartialOptionalKeyPath<MidValue>,
852 ) -> PartialOptionalKeyPath<Root>
853 where
854 MidValue: Any + 'static,
855 Root: 'static,
856 {
857 let first = self.getter;
858 let second = next.getter;
859 let value_type_id = next.value_type_id;
860
861 PartialOptionalKeyPath {
862 getter: Rc::new(move |root: &Root| {
863 first(root).and_then(|any| {
864 if let Some(mid_value) = any.downcast_ref::<MidValue>() {
865 second(mid_value)
866 } else {
867 None
868 }
869 })
870 }),
871 value_type_id,
872 _phantom: PhantomData,
873 }
874 }
875}
876
877#[derive(Clone)]
883pub struct PartialWritableKeyPath<Root> {
884 getter: Rc<dyn for<'r> Fn(&'r mut Root) -> &'r mut dyn Any>,
885 value_type_id: TypeId,
886 _phantom: PhantomData<Root>,
887}
888
889impl<Root> PartialWritableKeyPath<Root> {
890 pub fn new<Value>(keypath: WritableKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> &'r mut Value + 'static>) -> Self
891 where
892 Value: Any + 'static,
893 Root: 'static,
894 {
895 let value_type_id = TypeId::of::<Value>();
896 let getter = Rc::new(keypath.getter);
897
898 Self {
899 getter: Rc::new(move |root: &mut Root| {
900 let value: &mut Value = getter(root);
901 value as &mut dyn Any
902 }),
903 value_type_id,
904 _phantom: PhantomData,
905 }
906 }
907
908 pub fn from<Value>(keypath: WritableKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> &'r mut Value + 'static>) -> Self
911 where
912 Value: Any + 'static,
913 Root: 'static,
914 {
915 Self::new(keypath)
916 }
917
918 pub fn get_mut<'r>(&self, root: &'r mut Root) -> &'r mut dyn Any {
919 (self.getter)(root)
920 }
921
922 pub fn value_type_id(&self) -> TypeId {
924 self.value_type_id
925 }
926
927 pub fn get_mut_as<'a, Value: Any>(&self, root: &'a mut Root) -> Option<&'a mut Value> {
929 if self.value_type_id == TypeId::of::<Value>() {
930 self.get_mut(root).downcast_mut::<Value>()
931 } else {
932 None
933 }
934 }
935}
936
937#[derive(Clone)]
943pub struct PartialWritableOptionalKeyPath<Root> {
944 getter: Rc<dyn for<'r> Fn(&'r mut Root) -> Option<&'r mut dyn Any>>,
945 value_type_id: TypeId,
946 _phantom: PhantomData<Root>,
947}
948
949impl<Root> PartialWritableOptionalKeyPath<Root> {
950 pub fn new<Value>(keypath: WritableOptionalKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static>) -> Self
951 where
952 Value: Any + 'static,
953 Root: 'static,
954 {
955 let value_type_id = TypeId::of::<Value>();
956 let getter = Rc::new(keypath.getter);
957
958 Self {
959 getter: Rc::new(move |root: &mut Root| {
960 getter(root).map(|value: &mut Value| value as &mut dyn Any)
961 }),
962 value_type_id,
963 _phantom: PhantomData,
964 }
965 }
966
967 pub fn get_mut<'r>(&self, root: &'r mut Root) -> Option<&'r mut dyn Any> {
968 (self.getter)(root)
969 }
970
971 pub fn value_type_id(&self) -> TypeId {
973 self.value_type_id
974 }
975
976 pub fn get_mut_as<'a, Value: Any>(&self, root: &'a mut Root) -> Option<Option<&'a mut Value>> {
978 if self.value_type_id == TypeId::of::<Value>() {
979 self.get_mut(root).map(|any| any.downcast_mut::<Value>())
980 } else {
981 None
982 }
983 }
984}
985
986#[derive(Clone)]
1000pub struct AnyKeyPath {
1001 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
1002 root_type_id: TypeId,
1003 value_type_id: TypeId,
1004}
1005
1006impl AnyKeyPath {
1007 pub fn new<Root, Value>(keypath: OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>) -> Self
1008 where
1009 Root: Any + 'static,
1010 Value: Any + 'static,
1011 {
1012 let root_type_id = TypeId::of::<Root>();
1013 let value_type_id = TypeId::of::<Value>();
1014 let getter = keypath.getter;
1015
1016 Self {
1017 getter: Rc::new(move |any: &dyn Any| {
1018 if let Some(root) = any.downcast_ref::<Root>() {
1019 getter(root).map(|value: &Value| value as &dyn Any)
1020 } else {
1021 None
1022 }
1023 }),
1024 root_type_id,
1025 value_type_id,
1026 }
1027 }
1028
1029 pub fn from<Root, Value>(keypath: OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>) -> Self
1032 where
1033 Root: Any + 'static,
1034 Value: Any + 'static,
1035 {
1036 Self::new(keypath)
1037 }
1038
1039 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
1040 (self.getter)(root)
1041 }
1042
1043 pub fn root_type_id(&self) -> TypeId {
1045 self.root_type_id
1046 }
1047
1048 pub fn value_type_id(&self) -> TypeId {
1050 self.value_type_id
1051 }
1052
1053 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
1055 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>() {
1056 self.get(root as &dyn Any).map(|any| any.downcast_ref::<Value>())
1057 } else {
1058 None
1059 }
1060 }
1061}
1062
1063#[derive(Clone)]
1065pub struct AnyWritableKeyPath {
1066 getter: Rc<dyn for<'r> Fn(&'r mut dyn Any) -> Option<&'r mut dyn Any>>,
1067 root_type_id: TypeId,
1068 value_type_id: TypeId,
1069}
1070
1071impl AnyWritableKeyPath {
1072 pub fn new<Root, Value>(keypath: WritableOptionalKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static>) -> Self
1073 where
1074 Root: Any + 'static,
1075 Value: Any + 'static,
1076 {
1077 let root_type_id = TypeId::of::<Root>();
1078 let value_type_id = TypeId::of::<Value>();
1079 let getter = keypath.getter;
1080
1081 Self {
1082 getter: Rc::new(move |any: &mut dyn Any| {
1083 if let Some(root) = any.downcast_mut::<Root>() {
1084 getter(root).map(|value: &mut Value| value as &mut dyn Any)
1085 } else {
1086 None
1087 }
1088 }),
1089 root_type_id,
1090 value_type_id,
1091 }
1092 }
1093
1094 pub fn get_mut<'r>(&self, root: &'r mut dyn Any) -> Option<&'r mut dyn Any> {
1095 (self.getter)(root)
1096 }
1097
1098 pub fn root_type_id(&self) -> TypeId {
1100 self.root_type_id
1101 }
1102
1103 pub fn value_type_id(&self) -> TypeId {
1105 self.value_type_id
1106 }
1107
1108 pub fn get_mut_as<'a, Root: Any, Value: Any>(&self, root: &'a mut Root) -> Option<Option<&'a mut Value>> {
1110 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>() {
1111 self.get_mut(root as &mut dyn Any).map(|any| any.downcast_mut::<Value>())
1112 } else {
1113 None
1114 }
1115 }
1116}
1117
1118impl<Root, Value, F> KeyPath<Root, Value, F>
1120where
1121 F: for<'r> Fn(&'r Root) -> &'r Value + 'static,
1122 Root: 'static,
1123 Value: Any + 'static,
1124{
1125 pub fn to_partial(self) -> PartialKeyPath<Root> {
1127 PartialKeyPath::new(self)
1128 }
1129
1130 pub fn to(self) -> PartialKeyPath<Root> {
1132 self.to_partial()
1133 }
1134}
1135
1136impl<Root, Value, F> OptionalKeyPath<Root, Value, F>
1137where
1138 F: for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static,
1139 Root: Any + 'static,
1140 Value: Any + 'static,
1141{
1142 pub fn to_partial(self) -> PartialOptionalKeyPath<Root> {
1144 PartialOptionalKeyPath::new(self)
1145 }
1146
1147 pub fn to_any(self) -> AnyKeyPath {
1149 AnyKeyPath::new(self)
1150 }
1151
1152 pub fn to(self) -> PartialOptionalKeyPath<Root> {
1154 self.to_partial()
1155 }
1156}
1157
1158impl<Root, Value, F> WritableKeyPath<Root, Value, F>
1159where
1160 F: for<'r> Fn(&'r mut Root) -> &'r mut Value + 'static,
1161 Root: 'static,
1162 Value: Any + 'static,
1163{
1164 pub fn to_partial(self) -> PartialWritableKeyPath<Root> {
1166 PartialWritableKeyPath::new(self)
1167 }
1168
1169 pub fn to(self) -> PartialWritableKeyPath<Root> {
1171 self.to_partial()
1172 }
1173}
1174
1175impl<Root, Value, F> WritableOptionalKeyPath<Root, Value, F>
1176where
1177 F: for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static,
1178 Root: Any + 'static,
1179 Value: Any + 'static,
1180{
1181 pub fn to_partial(self) -> PartialWritableOptionalKeyPath<Root> {
1183 PartialWritableOptionalKeyPath::new(self)
1184 }
1185
1186 pub fn to_any(self) -> AnyWritableKeyPath {
1188 AnyWritableKeyPath::new(self)
1189 }
1190
1191 pub fn to(self) -> PartialWritableOptionalKeyPath<Root> {
1193 self.to_partial()
1194 }
1195}
1196
1197#[cfg(test)]
1198mod tests {
1199 use super::*;
1200 use std::sync::atomic::{AtomicUsize, Ordering};
1201 use std::rc::Rc;
1202
1203 static ALLOC_COUNT: AtomicUsize = AtomicUsize::new(0);
1205 static DEALLOC_COUNT: AtomicUsize = AtomicUsize::new(0);
1206
1207 #[derive(Debug)]
1209 struct NoCloneType {
1210 id: usize,
1211 data: String,
1212 }
1213
1214 impl NoCloneType {
1215 fn new(data: String) -> Self {
1216 ALLOC_COUNT.fetch_add(1, Ordering::SeqCst);
1217 Self {
1218 id: ALLOC_COUNT.load(Ordering::SeqCst),
1219 data,
1220 }
1221 }
1222 }
1223
1224 impl Clone for NoCloneType {
1225 fn clone(&self) -> Self {
1226 panic!("NoCloneType should not be cloned! ID: {}", self.id);
1227 }
1228 }
1229
1230 impl Drop for NoCloneType {
1231 fn drop(&mut self) {
1232 DEALLOC_COUNT.fetch_add(1, Ordering::SeqCst);
1233 }
1234 }
1235
1236 fn reset_memory_counters() {
1238 ALLOC_COUNT.store(0, Ordering::SeqCst);
1239 DEALLOC_COUNT.store(0, Ordering::SeqCst);
1240 }
1241
1242 fn get_alloc_count() -> usize {
1243 ALLOC_COUNT.load(Ordering::SeqCst)
1244 }
1245
1246 fn get_dealloc_count() -> usize {
1247 DEALLOC_COUNT.load(Ordering::SeqCst)
1248 }
1249
1250#[derive(Debug)]
1252struct User {
1253 name: String,
1254 metadata: Option<Box<UserMetadata>>,
1255 friends: Vec<Arc<User>>,
1256}
1257
1258#[derive(Debug)]
1259struct UserMetadata {
1260 created_at: String,
1261}
1262
1263fn some_fn() {
1264 let akash = User {
1265 name: "Alice".to_string(),
1266 metadata: Some(Box::new(UserMetadata {
1267 created_at: "2024-01-01".to_string(),
1268 })),
1269 friends: vec![
1270 Arc::new(User {
1271 name: "Bob".to_string(),
1272 metadata: None,
1273 friends: vec![],
1274 }),
1275 ],
1276 };
1277
1278 let name_kp = KeyPath::new(|u: &User| &u.name);
1280 let metadata_kp = OptionalKeyPath::new(|u: &User| u.metadata.as_ref());
1281 let friends_kp = KeyPath::new(|u: &User| &u.friends);
1282
1283 println!("Name: {}", name_kp.get(&akash));
1285
1286 if let Some(metadata) = metadata_kp.get(&akash) {
1287 println!("Has metadata: {:?}", metadata);
1288 }
1289
1290 if let Some(first_friend) = akash.friends.get(0) {
1292 println!("First friend: {}", name_kp.get(first_friend));
1293 }
1294
1295 let created_at_kp = KeyPath::new(|m: &UserMetadata| &m.created_at);
1297
1298 if let Some(metadata) = akash.metadata.as_ref() {
1299 let boxed_metadata: &Box<UserMetadata> = metadata;
1301 let unwrapped = boxed_metadata.as_ref();
1302 println!("Created at: {:?}", created_at_kp.get(unwrapped));
1303 }
1304 }
1305
1306 #[test]
1307 fn test_name() {
1308 some_fn();
1309 }
1310
1311 #[test]
1312 fn test_no_cloning_on_keypath_operations() {
1313 reset_memory_counters();
1314
1315 let value = NoCloneType::new("test".to_string());
1317 let boxed = Box::new(value);
1318
1319 let kp = KeyPath::new(|b: &Box<NoCloneType>| b.as_ref());
1321
1322 let _ref = kp.get(&boxed);
1324
1325 let _kp_clone = kp.clone();
1327
1328 let _ref2 = _kp_clone.get(&boxed);
1330
1331 assert_eq!(get_alloc_count(), 1);
1333 }
1334
1335 #[test]
1336 fn test_no_cloning_on_optional_keypath_operations() {
1337 reset_memory_counters();
1338
1339 let value = NoCloneType::new("test".to_string());
1340 let opt = Some(Box::new(value));
1341
1342 let okp = OptionalKeyPath::new(|o: &Option<Box<NoCloneType>>| o.as_ref());
1344
1345 let _ref = okp.get(&opt);
1347
1348 let _okp_clone = okp.clone();
1350
1351 let chained = okp.then(OptionalKeyPath::new(|b: &Box<NoCloneType>| Some(b.as_ref())));
1353 let _ref2 = chained.get(&opt);
1354
1355 assert_eq!(get_alloc_count(), 1);
1356 }
1357
1358 #[test]
1359 fn test_memory_release() {
1360 reset_memory_counters();
1361
1362 {
1363 let value = NoCloneType::new("test".to_string());
1364 let boxed = Box::new(value);
1365 let kp = KeyPath::new(|b: &Box<NoCloneType>| b.as_ref());
1366
1367 let _ref = kp.get(&boxed);
1369
1370 }
1372
1373 assert_eq!(get_alloc_count(), 1);
1376 }
1379
1380 #[test]
1381 fn test_keypath_clone_does_not_clone_underlying_data() {
1382 reset_memory_counters();
1383
1384 let value = NoCloneType::new("data".to_string());
1385 let rc_value = Rc::new(value);
1386
1387 let kp = KeyPath::new(|r: &Rc<NoCloneType>| r.as_ref());
1389
1390 let kp1 = kp.clone();
1392 let kp2 = kp.clone();
1393 let kp3 = kp1.clone();
1394
1395 let _ref1 = kp.get(&rc_value);
1397 let _ref2 = kp1.get(&rc_value);
1398 let _ref3 = kp2.get(&rc_value);
1399 let _ref4 = kp3.get(&rc_value);
1400
1401 assert_eq!(get_alloc_count(), 1);
1403 }
1404
1405 #[test]
1406 fn test_optional_keypath_chaining_no_clone() {
1407 reset_memory_counters();
1408
1409 let value = NoCloneType::new("value1".to_string());
1410
1411 struct Container {
1412 inner: Option<Box<NoCloneType>>,
1413 }
1414
1415 let container = Container {
1416 inner: Some(Box::new(value)),
1417 };
1418
1419 let kp1 = OptionalKeyPath::new(|c: &Container| c.inner.as_ref());
1421 let kp2 = OptionalKeyPath::new(|b: &Box<NoCloneType>| Some(b.as_ref()));
1422
1423 let chained = kp1.then(kp2);
1425
1426 let _result = chained.get(&container);
1428
1429 assert_eq!(get_alloc_count(), 1);
1431 }
1432
1433 #[test]
1434 fn test_for_box_no_clone() {
1435 reset_memory_counters();
1436
1437 let value = NoCloneType::new("test".to_string());
1438 let boxed = Box::new(value);
1439 let opt_boxed = Some(boxed);
1440
1441 let kp = OptionalKeyPath::new(|o: &Option<Box<NoCloneType>>| o.as_ref());
1443 let unwrapped = kp.for_box();
1444
1445 let _ref = unwrapped.get(&opt_boxed);
1447
1448 assert_eq!(get_alloc_count(), 1);
1449 }
1450}