1use std::sync::{Arc, Mutex, RwLock};
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 pub fn to_optional(self) -> OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>
86 where
87 F: 'static,
88 {
89 let getter = self.getter;
90 OptionalKeyPath::new(move |root: &Root| Some(getter(root)))
91 }
92
93 pub fn with_option<Callback, R>(&self, option: &Option<Root>, f: Callback) -> Option<R>
95 where
96 F: Clone,
97 Callback: FnOnce(&Value) -> R,
98 {
99 option.as_ref().map(|root| {
100 let value = self.get(root);
101 f(value)
102 })
103 }
104
105 pub fn with_mutex<Callback, R>(&self, mutex: &Mutex<Root>, f: Callback) -> Option<R>
107 where
108 F: Clone,
109 Callback: FnOnce(&Value) -> R,
110 {
111 mutex.lock().ok().map(|guard| {
112 let value = self.get(&*guard);
113 f(value)
114 })
115 }
116
117 pub fn with_rwlock<Callback, R>(&self, rwlock: &RwLock<Root>, f: Callback) -> Option<R>
119 where
120 F: Clone,
121 Callback: FnOnce(&Value) -> R,
122 {
123 rwlock.read().ok().map(|guard| {
124 let value = self.get(&*guard);
125 f(value)
126 })
127 }
128
129 pub fn with_arc_rwlock<Callback, R>(&self, arc_rwlock: &Arc<RwLock<Root>>, f: Callback) -> Option<R>
131 where
132 F: Clone,
133 Callback: FnOnce(&Value) -> R,
134 {
135 arc_rwlock.read().ok().map(|guard| {
136 let value = self.get(&*guard);
137 f(value)
138 })
139 }
140
141 pub fn with_arc_mutex<Callback, R>(&self, arc_mutex: &Arc<Mutex<Root>>, f: Callback) -> Option<R>
143 where
144 F: Clone,
145 Callback: FnOnce(&Value) -> R,
146 {
147 arc_mutex.lock().ok().map(|guard| {
148 let value = self.get(&*guard);
149 f(value)
150 })
151 }
152
153}
154
155impl<Root, Value, F> KeyPath<Root, Value, F>
157where
158 F: for<'r> Fn(&'r Root) -> &'r Value + Clone,
159{
160 pub fn with_arc_rwlock_direct<Callback, R>(&self, arc_rwlock: &Arc<RwLock<Root>>, f: Callback) -> Option<R>
163 where
164 Callback: FnOnce(&Value) -> R,
165 {
166 arc_rwlock.read().ok().map(|guard| {
167 let value = self.get(&*guard);
168 f(value)
169 })
170 }
171
172 pub fn with_arc_mutex_direct<Callback, R>(&self, arc_mutex: &Arc<Mutex<Root>>, f: Callback) -> Option<R>
175 where
176 Callback: FnOnce(&Value) -> R,
177 {
178 arc_mutex.lock().ok().map(|guard| {
179 let value = self.get(&*guard);
180 f(value)
181 })
182 }
183}
184
185pub fn for_slice<T>() -> impl for<'r> Fn(&'r [T], usize) -> Option<&'r T> {
187 |slice: &[T], index: usize| slice.get(index)
188}
189
190pub mod containers {
192 use super::{OptionalKeyPath, WritableOptionalKeyPath, KeyPath, WritableKeyPath};
193 use std::collections::{HashMap, BTreeMap, HashSet, BTreeSet, VecDeque, LinkedList, BinaryHeap};
194 use std::sync::{Mutex, RwLock, Weak as StdWeak, Arc};
195 use std::rc::{Weak as RcWeak, Rc};
196 use std::ops::{Deref, DerefMut};
197
198 #[cfg(feature = "parking_lot")]
199 use parking_lot::{Mutex as ParkingMutex, RwLock as ParkingRwLock};
200
201 #[cfg(feature = "tagged")]
202 use tagged_core::Tagged;
203
204 pub fn for_vec_index<T>(index: usize) -> OptionalKeyPath<Vec<T>, T, impl for<'r> Fn(&'r Vec<T>) -> Option<&'r T>> {
206 OptionalKeyPath::new(move |vec: &Vec<T>| vec.get(index))
207 }
208
209 pub fn for_vecdeque_index<T>(index: usize) -> OptionalKeyPath<VecDeque<T>, T, impl for<'r> Fn(&'r VecDeque<T>) -> Option<&'r T>> {
211 OptionalKeyPath::new(move |deque: &VecDeque<T>| deque.get(index))
212 }
213
214 pub fn for_linkedlist_index<T>(index: usize) -> OptionalKeyPath<LinkedList<T>, T, impl for<'r> Fn(&'r LinkedList<T>) -> Option<&'r T>> {
216 OptionalKeyPath::new(move |list: &LinkedList<T>| {
217 list.iter().nth(index)
218 })
219 }
220
221 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>>
223 where
224 K: std::hash::Hash + Eq + Clone + 'static,
225 V: 'static,
226 {
227 OptionalKeyPath::new(move |map: &HashMap<K, V>| map.get(&key))
228 }
229
230 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>>
232 where
233 K: Ord + Clone + 'static,
234 V: 'static,
235 {
236 OptionalKeyPath::new(move |map: &BTreeMap<K, V>| map.get(&key))
237 }
238
239 pub fn for_hashset_get<T>(value: T) -> OptionalKeyPath<HashSet<T>, T, impl for<'r> Fn(&'r HashSet<T>) -> Option<&'r T>>
241 where
242 T: std::hash::Hash + Eq + Clone + 'static,
243 {
244 OptionalKeyPath::new(move |set: &HashSet<T>| set.get(&value))
245 }
246
247 pub fn for_btreeset_get<T>(value: T) -> OptionalKeyPath<BTreeSet<T>, T, impl for<'r> Fn(&'r BTreeSet<T>) -> Option<&'r T>>
249 where
250 T: Ord + Clone + 'static,
251 {
252 OptionalKeyPath::new(move |set: &BTreeSet<T>| set.get(&value))
253 }
254
255 pub fn for_binaryheap_peek<T>() -> OptionalKeyPath<BinaryHeap<T>, T, impl for<'r> Fn(&'r BinaryHeap<T>) -> Option<&'r T>>
257 where
258 T: Ord + 'static,
259 {
260 OptionalKeyPath::new(|heap: &BinaryHeap<T>| heap.peek())
261 }
262
263 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>> {
267 WritableOptionalKeyPath::new(move |vec: &mut Vec<T>| vec.get_mut(index))
268 }
269
270 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>> {
272 WritableOptionalKeyPath::new(move |deque: &mut VecDeque<T>| deque.get_mut(index))
273 }
274
275 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>> {
277 WritableOptionalKeyPath::new(move |list: &mut LinkedList<T>| {
278 let mut iter = list.iter_mut();
280 iter.nth(index)
281 })
282 }
283
284 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>>
286 where
287 K: std::hash::Hash + Eq + Clone + 'static,
288 V: 'static,
289 {
290 WritableOptionalKeyPath::new(move |map: &mut HashMap<K, V>| map.get_mut(&key))
291 }
292
293 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>>
295 where
296 K: Ord + Clone + 'static,
297 V: 'static,
298 {
299 WritableOptionalKeyPath::new(move |map: &mut BTreeMap<K, V>| map.get_mut(&key))
300 }
301
302 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>>
305 where
306 T: std::hash::Hash + Eq + Clone + 'static,
307 {
308 WritableOptionalKeyPath::new(move |set: &mut HashSet<T>| {
309 if set.contains(&value) {
312 None
315 } else {
316 None
317 }
318 })
319 }
320
321 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>>
324 where
325 T: Ord + Clone + 'static,
326 {
327 WritableOptionalKeyPath::new(move |set: &mut BTreeSet<T>| {
328 if set.contains(&value) {
331 None
334 } else {
335 None
336 }
337 })
338 }
339
340 pub fn for_binaryheap_peek_mut<T>() -> WritableOptionalKeyPath<BinaryHeap<T>, T, impl for<'r> Fn(&'r mut BinaryHeap<T>) -> Option<&'r mut T>>
346 where
347 T: Ord + 'static,
348 {
349 WritableOptionalKeyPath::new(|_heap: &mut BinaryHeap<T>| {
353 None
354 })
355 }
356
357 pub fn lock_mutex<T>(mutex: &Mutex<T>) -> Option<std::sync::MutexGuard<'_, T>> {
366 mutex.lock().ok()
367 }
368
369 pub fn read_rwlock<T>(rwlock: &RwLock<T>) -> Option<std::sync::RwLockReadGuard<'_, T>> {
373 rwlock.read().ok()
374 }
375
376 pub fn write_rwlock<T>(rwlock: &RwLock<T>) -> Option<std::sync::RwLockWriteGuard<'_, T>> {
380 rwlock.write().ok()
381 }
382
383 pub fn lock_arc_mutex<T>(arc_mutex: &Arc<Mutex<T>>) -> Option<std::sync::MutexGuard<'_, T>> {
387 arc_mutex.lock().ok()
388 }
389
390 pub fn read_arc_rwlock<T>(arc_rwlock: &Arc<RwLock<T>>) -> Option<std::sync::RwLockReadGuard<'_, T>> {
394 arc_rwlock.read().ok()
395 }
396
397 pub fn write_arc_rwlock<T>(arc_rwlock: &Arc<RwLock<T>>) -> Option<std::sync::RwLockWriteGuard<'_, T>> {
401 arc_rwlock.write().ok()
402 }
403
404 pub fn upgrade_weak<T>(weak: &StdWeak<T>) -> Option<Arc<T>> {
408 weak.upgrade()
409 }
410
411 pub fn upgrade_rc_weak<T>(weak: &RcWeak<T>) -> Option<Rc<T>> {
415 weak.upgrade()
416 }
417
418 #[cfg(feature = "parking_lot")]
419 pub fn lock_parking_mutex<T>(mutex: &ParkingMutex<T>) -> parking_lot::MutexGuard<'_, T> {
422 mutex.lock()
423 }
424
425 #[cfg(feature = "parking_lot")]
426 pub fn read_parking_rwlock<T>(rwlock: &ParkingRwLock<T>) -> parking_lot::RwLockReadGuard<'_, T> {
429 rwlock.read()
430 }
431
432 #[cfg(feature = "parking_lot")]
433 pub fn write_parking_rwlock<T>(rwlock: &ParkingRwLock<T>) -> parking_lot::RwLockWriteGuard<'_, T> {
436 rwlock.write()
437 }
438
439 #[cfg(feature = "tagged")]
440 pub fn for_tagged<Tag, T>() -> KeyPath<Tagged<Tag, T>, T, impl for<'r> Fn(&'r Tagged<Tag, T>) -> &'r T>
443 where
444 Tagged<Tag, T>: std::ops::Deref<Target = T>,
445 Tag: 'static,
446 T: 'static,
447 {
448 KeyPath::new(|tagged: &Tagged<Tag, T>| tagged.deref())
449 }
450
451 #[cfg(feature = "tagged")]
452 pub fn for_tagged_mut<Tag, T>() -> WritableKeyPath<Tagged<Tag, T>, T, impl for<'r> Fn(&'r mut Tagged<Tag, T>) -> &'r mut T>
455 where
456 Tagged<Tag, T>: std::ops::DerefMut<Target = T>,
457 Tag: 'static,
458 T: 'static,
459 {
460 WritableKeyPath::new(|tagged: &mut Tagged<Tag, T>| tagged.deref_mut())
461 }
462}
463
464#[derive(Clone)]
466pub struct OptionalKeyPath<Root, Value, F>
467where
468 F: for<'r> Fn(&'r Root) -> Option<&'r Value>,
469{
470 getter: F,
471 _phantom: PhantomData<(Root, Value)>,
472}
473
474impl<Root, Value, F> OptionalKeyPath<Root, Value, F>
475where
476 F: for<'r> Fn(&'r Root) -> Option<&'r Value>,
477{
478 pub fn new(getter: F) -> Self {
479 Self {
480 getter,
481 _phantom: PhantomData,
482 }
483 }
484
485 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r Value> {
486 (self.getter)(root)
487 }
488
489 pub fn then<SubValue, G>(
491 self,
492 next: OptionalKeyPath<Value, SubValue, G>,
493 ) -> OptionalKeyPath<Root, SubValue, impl for<'r> Fn(&'r Root) -> Option<&'r SubValue>>
494 where
495 G: for<'r> Fn(&'r Value) -> Option<&'r SubValue>,
496 F: 'static,
497 G: 'static,
498 Value: 'static,
499 {
500 let first = self.getter;
501 let second = next.getter;
502
503 OptionalKeyPath::new(move |root: &Root| {
504 first(root).and_then(|value| second(value))
505 })
506 }
507
508 pub fn for_box<Target>(self) -> OptionalKeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> Option<&'r Target> + 'static>
511 where
512 Value: std::ops::Deref<Target = Target>,
513 F: 'static,
514 Value: 'static,
515 {
516 let getter = self.getter;
517
518 OptionalKeyPath {
519 getter: move |root: &Root| {
520 getter(root).map(|boxed| boxed.deref())
521 },
522 _phantom: PhantomData,
523 }
524 }
525
526 pub fn for_arc<Target>(self) -> OptionalKeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> Option<&'r Target> + 'static>
528 where
529 Value: std::ops::Deref<Target = Target>,
530 F: 'static,
531 Value: 'static,
532 {
533 let getter = self.getter;
534
535 OptionalKeyPath {
536 getter: move |root: &Root| {
537 getter(root).map(|arc| arc.deref())
538 },
539 _phantom: PhantomData,
540 }
541 }
542
543 pub fn for_rc<Target>(self) -> OptionalKeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> Option<&'r Target> + 'static>
545 where
546 Value: std::ops::Deref<Target = Target>,
547 F: 'static,
548 Value: 'static,
549 {
550 let getter = self.getter;
551
552 OptionalKeyPath {
553 getter: move |root: &Root| {
554 getter(root).map(|rc| rc.deref())
555 },
556 _phantom: PhantomData,
557 }
558 }
559
560 pub fn for_option<T>() -> OptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r Option<T>) -> Option<&'r T>> {
562 OptionalKeyPath::new(|opt: &Option<T>| opt.as_ref())
563 }
564
565 pub fn with_option<Callback, R>(&self, option: &Option<Root>, f: Callback) -> Option<R>
567 where
568 F: Clone,
569 Callback: FnOnce(&Value) -> R,
570 {
571 option.as_ref().and_then(|root| {
572 self.get(root).map(|value| f(value))
573 })
574 }
575
576 pub fn with_mutex<Callback, R>(&self, mutex: &Mutex<Root>, f: Callback) -> Option<R>
578 where
579 F: Clone,
580 Callback: FnOnce(&Value) -> R,
581 {
582 mutex.lock().ok().and_then(|guard| {
583 self.get(&*guard).map(|value| f(value))
584 })
585 }
586
587 pub fn with_rwlock<Callback, R>(&self, rwlock: &RwLock<Root>, f: Callback) -> Option<R>
589 where
590 F: Clone,
591 Callback: FnOnce(&Value) -> R,
592 {
593 rwlock.read().ok().and_then(|guard| {
594 self.get(&*guard).map(|value| f(value))
595 })
596 }
597
598 pub fn with_arc_rwlock<Callback, R>(&self, arc_rwlock: &Arc<RwLock<Root>>, f: Callback) -> Option<R>
600 where
601 F: Clone,
602 Callback: FnOnce(&Value) -> R,
603 {
604 arc_rwlock.read().ok().and_then(|guard| {
605 self.get(&*guard).map(|value| f(value))
606 })
607 }
608
609 pub fn with_arc_mutex<Callback, R>(&self, arc_mutex: &Arc<Mutex<Root>>, f: Callback) -> Option<R>
611 where
612 F: Clone,
613 Callback: FnOnce(&Value) -> R,
614 {
615 arc_mutex.lock().ok().and_then(|guard| {
616 self.get(&*guard).map(|value| f(value))
617 })
618 }
619}
620
621
622#[derive(Clone)]
624pub struct WritableKeyPath<Root, Value, F>
625where
626 F: for<'r> Fn(&'r mut Root) -> &'r mut Value,
627{
628 getter: F,
629 _phantom: PhantomData<(Root, Value)>,
630}
631
632impl<Root, Value, F> WritableKeyPath<Root, Value, F>
633where
634 F: for<'r> Fn(&'r mut Root) -> &'r mut Value,
635{
636 pub fn new(getter: F) -> Self {
637 Self {
638 getter,
639 _phantom: PhantomData,
640 }
641 }
642
643 pub fn get_mut<'r>(&self, root: &'r mut Root) -> &'r mut Value {
644 (self.getter)(root)
645 }
646
647 pub fn to_optional(self) -> WritableOptionalKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static>
650 where
651 F: 'static,
652 {
653 let getter = self.getter;
654 WritableOptionalKeyPath::new(move |root: &mut Root| Some(getter(root)))
655 }
656
657 pub fn for_box<Target>(self) -> WritableKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> &'r mut Target + 'static>
660 where
661 Value: std::ops::DerefMut<Target = Target>,
662 F: 'static,
663 Value: 'static,
664 {
665 let getter = self.getter;
666
667 WritableKeyPath {
668 getter: move |root: &mut Root| {
669 getter(root).deref_mut()
670 },
671 _phantom: PhantomData,
672 }
673 }
674
675 pub fn for_arc<Target>(self) -> WritableKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> &'r mut Target + 'static>
678 where
679 Value: std::ops::DerefMut<Target = Target>,
680 F: 'static,
681 Value: 'static,
682 {
683 let getter = self.getter;
684
685 WritableKeyPath {
686 getter: move |root: &mut Root| {
687 getter(root).deref_mut()
688 },
689 _phantom: PhantomData,
690 }
691 }
692
693 pub fn for_rc<Target>(self) -> WritableKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> &'r mut Target + 'static>
696 where
697 Value: std::ops::DerefMut<Target = Target>,
698 F: 'static,
699 Value: 'static,
700 {
701 let getter = self.getter;
702
703 WritableKeyPath {
704 getter: move |root: &mut Root| {
705 getter(root).deref_mut()
706 },
707 _phantom: PhantomData,
708 }
709 }
710}
711
712#[derive(Clone)]
714pub struct WritableOptionalKeyPath<Root, Value, F>
715where
716 F: for<'r> Fn(&'r mut Root) -> Option<&'r mut Value>,
717{
718 getter: F,
719 _phantom: PhantomData<(Root, Value)>,
720}
721
722impl<Root, Value, F> WritableOptionalKeyPath<Root, Value, F>
723where
724 F: for<'r> Fn(&'r mut Root) -> Option<&'r mut Value>,
725{
726 pub fn new(getter: F) -> Self {
727 Self {
728 getter,
729 _phantom: PhantomData,
730 }
731 }
732
733 pub fn get_mut<'r>(&self, root: &'r mut Root) -> Option<&'r mut Value> {
734 (self.getter)(root)
735 }
736
737 pub fn then<SubValue, G>(
739 self,
740 next: WritableOptionalKeyPath<Value, SubValue, G>,
741 ) -> WritableOptionalKeyPath<Root, SubValue, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut SubValue>>
742 where
743 G: for<'r> Fn(&'r mut Value) -> Option<&'r mut SubValue>,
744 F: 'static,
745 G: 'static,
746 Value: 'static,
747 {
748 let first = self.getter;
749 let second = next.getter;
750
751 WritableOptionalKeyPath::new(move |root: &mut Root| {
752 first(root).and_then(|value| second(value))
753 })
754 }
755
756 pub fn for_box<Target>(self) -> WritableOptionalKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Target> + 'static>
759 where
760 Value: std::ops::DerefMut<Target = Target>,
761 F: 'static,
762 Value: 'static,
763 {
764 let getter = self.getter;
765
766 WritableOptionalKeyPath {
767 getter: move |root: &mut Root| {
768 getter(root).map(|boxed| boxed.deref_mut())
769 },
770 _phantom: PhantomData,
771 }
772 }
773
774 pub fn for_arc<Target>(self) -> WritableOptionalKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Target> + 'static>
776 where
777 Value: std::ops::DerefMut<Target = Target>,
778 F: 'static,
779 Value: 'static,
780 {
781 let getter = self.getter;
782
783 WritableOptionalKeyPath {
784 getter: move |root: &mut Root| {
785 getter(root).map(|arc| arc.deref_mut())
786 },
787 _phantom: PhantomData,
788 }
789 }
790
791 pub fn for_rc<Target>(self) -> WritableOptionalKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Target> + 'static>
793 where
794 Value: std::ops::DerefMut<Target = Target>,
795 F: 'static,
796 Value: 'static,
797 {
798 let getter = self.getter;
799
800 WritableOptionalKeyPath {
801 getter: move |root: &mut Root| {
802 getter(root).map(|rc| rc.deref_mut())
803 },
804 _phantom: PhantomData,
805 }
806 }
807
808 pub fn for_option<T>() -> WritableOptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r mut Option<T>) -> Option<&'r mut T>> {
810 WritableOptionalKeyPath::new(|opt: &mut Option<T>| opt.as_mut())
811 }
812}
813
814#[derive(Clone)]
816pub struct EnumKeyPaths;
817
818impl EnumKeyPaths {
819 pub fn for_variant<Enum, Variant, ExtractFn>(
821 extractor: ExtractFn
822 ) -> OptionalKeyPath<Enum, Variant, impl for<'r> Fn(&'r Enum) -> Option<&'r Variant>>
823 where
824 ExtractFn: Fn(&Enum) -> Option<&Variant>,
825 {
826 OptionalKeyPath::new(extractor)
827 }
828
829 pub fn for_match<Enum, Output, MatchFn>(
831 matcher: MatchFn
832 ) -> KeyPath<Enum, Output, impl for<'r> Fn(&'r Enum) -> &'r Output>
833 where
834 MatchFn: Fn(&Enum) -> &Output,
835 {
836 KeyPath::new(matcher)
837 }
838
839 pub fn for_ok<T, E>() -> OptionalKeyPath<Result<T, E>, T, impl for<'r> Fn(&'r Result<T, E>) -> Option<&'r T>> {
841 OptionalKeyPath::new(|result: &Result<T, E>| result.as_ref().ok())
842 }
843
844 pub fn for_err<T, E>() -> OptionalKeyPath<Result<T, E>, E, impl for<'r> Fn(&'r Result<T, E>) -> Option<&'r E>> {
845 OptionalKeyPath::new(|result: &Result<T, E>| result.as_ref().err())
846 }
847
848 pub fn for_some<T>() -> OptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r Option<T>) -> Option<&'r T>> {
850 OptionalKeyPath::new(|opt: &Option<T>| opt.as_ref())
851 }
852
853 pub fn for_option<T>() -> OptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r Option<T>) -> Option<&'r T>> {
855 OptionalKeyPath::new(|opt: &Option<T>| opt.as_ref())
856 }
857
858 pub fn for_box<T>() -> KeyPath<Box<T>, T, impl for<'r> Fn(&'r Box<T>) -> &'r T> {
861 KeyPath::new(|b: &Box<T>| b.as_ref())
862 }
863
864 pub fn for_arc<T>() -> KeyPath<Arc<T>, T, impl for<'r> Fn(&'r Arc<T>) -> &'r T> {
866 KeyPath::new(|arc: &Arc<T>| arc.as_ref())
867 }
868
869 pub fn for_rc<T>() -> KeyPath<std::rc::Rc<T>, T, impl for<'r> Fn(&'r std::rc::Rc<T>) -> &'r T> {
871 KeyPath::new(|rc: &std::rc::Rc<T>| rc.as_ref())
872 }
873
874 pub fn for_box_mut<T>() -> WritableKeyPath<Box<T>, T, impl for<'r> Fn(&'r mut Box<T>) -> &'r mut T> {
877 WritableKeyPath::new(|b: &mut Box<T>| b.as_mut())
878 }
879
880 }
884
885pub fn variant_of<Enum, Variant, F>(extractor: F) -> OptionalKeyPath<Enum, Variant, F>
887where
888 F: for<'r> Fn(&'r Enum) -> Option<&'r Variant>,
889{
890 OptionalKeyPath::new(extractor)
891}
892
893#[derive(Clone)]
909pub struct PartialKeyPath<Root> {
910 getter: Rc<dyn for<'r> Fn(&'r Root) -> &'r dyn Any>,
911 value_type_id: TypeId,
912 _phantom: PhantomData<Root>,
913}
914
915impl<Root> PartialKeyPath<Root> {
916 pub fn new<Value>(keypath: KeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> &'r Value + 'static>) -> Self
917 where
918 Value: Any + 'static,
919 Root: 'static,
920 {
921 let value_type_id = TypeId::of::<Value>();
922 let getter = Rc::new(keypath.getter);
923
924 Self {
925 getter: Rc::new(move |root: &Root| {
926 let value: &Value = getter(root);
927 value as &dyn Any
928 }),
929 value_type_id,
930 _phantom: PhantomData,
931 }
932 }
933
934 pub fn from<Value>(keypath: KeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> &'r Value + 'static>) -> Self
937 where
938 Value: Any + 'static,
939 Root: 'static,
940 {
941 Self::new(keypath)
942 }
943
944 pub fn get<'r>(&self, root: &'r Root) -> &'r dyn Any {
945 (self.getter)(root)
946 }
947
948 pub fn value_type_id(&self) -> TypeId {
950 self.value_type_id
951 }
952
953 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
955 if self.value_type_id == TypeId::of::<Value>() {
956 self.get(root).downcast_ref::<Value>()
957 } else {
958 None
959 }
960 }
961}
962
963#[derive(Clone)]
970pub struct PartialOptionalKeyPath<Root> {
971 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
972 value_type_id: TypeId,
973 _phantom: PhantomData<Root>,
974}
975
976impl<Root> PartialOptionalKeyPath<Root> {
977 pub fn new<Value>(keypath: OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>) -> Self
978 where
979 Value: Any + 'static,
980 Root: 'static,
981 {
982 let value_type_id = TypeId::of::<Value>();
983 let getter = Rc::new(keypath.getter);
984
985 Self {
986 getter: Rc::new(move |root: &Root| {
987 getter(root).map(|value: &Value| value as &dyn Any)
988 }),
989 value_type_id,
990 _phantom: PhantomData,
991 }
992 }
993
994 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
995 (self.getter)(root)
996 }
997
998 pub fn value_type_id(&self) -> TypeId {
1000 self.value_type_id
1001 }
1002
1003 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
1005 if self.value_type_id == TypeId::of::<Value>() {
1006 self.get(root).map(|any| any.downcast_ref::<Value>())
1007 } else {
1008 None
1009 }
1010 }
1011
1012 pub fn then<MidValue>(
1016 self,
1017 next: PartialOptionalKeyPath<MidValue>,
1018 ) -> PartialOptionalKeyPath<Root>
1019 where
1020 MidValue: Any + 'static,
1021 Root: 'static,
1022 {
1023 let first = self.getter;
1024 let second = next.getter;
1025 let value_type_id = next.value_type_id;
1026
1027 PartialOptionalKeyPath {
1028 getter: Rc::new(move |root: &Root| {
1029 first(root).and_then(|any| {
1030 if let Some(mid_value) = any.downcast_ref::<MidValue>() {
1031 second(mid_value)
1032 } else {
1033 None
1034 }
1035 })
1036 }),
1037 value_type_id,
1038 _phantom: PhantomData,
1039 }
1040 }
1041}
1042
1043#[derive(Clone)]
1049pub struct PartialWritableKeyPath<Root> {
1050 getter: Rc<dyn for<'r> Fn(&'r mut Root) -> &'r mut dyn Any>,
1051 value_type_id: TypeId,
1052 _phantom: PhantomData<Root>,
1053}
1054
1055impl<Root> PartialWritableKeyPath<Root> {
1056 pub fn new<Value>(keypath: WritableKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> &'r mut Value + 'static>) -> Self
1057 where
1058 Value: Any + 'static,
1059 Root: 'static,
1060 {
1061 let value_type_id = TypeId::of::<Value>();
1062 let getter = Rc::new(keypath.getter);
1063
1064 Self {
1065 getter: Rc::new(move |root: &mut Root| {
1066 let value: &mut Value = getter(root);
1067 value as &mut dyn Any
1068 }),
1069 value_type_id,
1070 _phantom: PhantomData,
1071 }
1072 }
1073
1074 pub fn from<Value>(keypath: WritableKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> &'r mut Value + 'static>) -> Self
1077 where
1078 Value: Any + 'static,
1079 Root: 'static,
1080 {
1081 Self::new(keypath)
1082 }
1083
1084 pub fn get_mut<'r>(&self, root: &'r mut Root) -> &'r mut dyn Any {
1085 (self.getter)(root)
1086 }
1087
1088 pub fn value_type_id(&self) -> TypeId {
1090 self.value_type_id
1091 }
1092
1093 pub fn get_mut_as<'a, Value: Any>(&self, root: &'a mut Root) -> Option<&'a mut Value> {
1095 if self.value_type_id == TypeId::of::<Value>() {
1096 self.get_mut(root).downcast_mut::<Value>()
1097 } else {
1098 None
1099 }
1100 }
1101}
1102
1103#[derive(Clone)]
1109pub struct PartialWritableOptionalKeyPath<Root> {
1110 getter: Rc<dyn for<'r> Fn(&'r mut Root) -> Option<&'r mut dyn Any>>,
1111 value_type_id: TypeId,
1112 _phantom: PhantomData<Root>,
1113}
1114
1115impl<Root> PartialWritableOptionalKeyPath<Root> {
1116 pub fn new<Value>(keypath: WritableOptionalKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static>) -> Self
1117 where
1118 Value: Any + 'static,
1119 Root: 'static,
1120 {
1121 let value_type_id = TypeId::of::<Value>();
1122 let getter = Rc::new(keypath.getter);
1123
1124 Self {
1125 getter: Rc::new(move |root: &mut Root| {
1126 getter(root).map(|value: &mut Value| value as &mut dyn Any)
1127 }),
1128 value_type_id,
1129 _phantom: PhantomData,
1130 }
1131 }
1132
1133 pub fn get_mut<'r>(&self, root: &'r mut Root) -> Option<&'r mut dyn Any> {
1134 (self.getter)(root)
1135 }
1136
1137 pub fn value_type_id(&self) -> TypeId {
1139 self.value_type_id
1140 }
1141
1142 pub fn get_mut_as<'a, Value: Any>(&self, root: &'a mut Root) -> Option<Option<&'a mut Value>> {
1144 if self.value_type_id == TypeId::of::<Value>() {
1145 self.get_mut(root).map(|any| any.downcast_mut::<Value>())
1146 } else {
1147 None
1148 }
1149 }
1150}
1151
1152#[derive(Clone)]
1166pub struct AnyKeyPath {
1167 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
1168 root_type_id: TypeId,
1169 value_type_id: TypeId,
1170}
1171
1172impl AnyKeyPath {
1173 pub fn new<Root, Value>(keypath: OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>) -> Self
1174 where
1175 Root: Any + 'static,
1176 Value: Any + 'static,
1177 {
1178 let root_type_id = TypeId::of::<Root>();
1179 let value_type_id = TypeId::of::<Value>();
1180 let getter = keypath.getter;
1181
1182 Self {
1183 getter: Rc::new(move |any: &dyn Any| {
1184 if let Some(root) = any.downcast_ref::<Root>() {
1185 getter(root).map(|value: &Value| value as &dyn Any)
1186 } else {
1187 None
1188 }
1189 }),
1190 root_type_id,
1191 value_type_id,
1192 }
1193 }
1194
1195 pub fn from<Root, Value>(keypath: OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>) -> Self
1198 where
1199 Root: Any + 'static,
1200 Value: Any + 'static,
1201 {
1202 Self::new(keypath)
1203 }
1204
1205 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
1206 (self.getter)(root)
1207 }
1208
1209 pub fn root_type_id(&self) -> TypeId {
1211 self.root_type_id
1212 }
1213
1214 pub fn value_type_id(&self) -> TypeId {
1216 self.value_type_id
1217 }
1218
1219 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
1221 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>() {
1222 self.get(root as &dyn Any).map(|any| any.downcast_ref::<Value>())
1223 } else {
1224 None
1225 }
1226 }
1227}
1228
1229#[derive(Clone)]
1231pub struct AnyWritableKeyPath {
1232 getter: Rc<dyn for<'r> Fn(&'r mut dyn Any) -> Option<&'r mut dyn Any>>,
1233 root_type_id: TypeId,
1234 value_type_id: TypeId,
1235}
1236
1237impl AnyWritableKeyPath {
1238 pub fn new<Root, Value>(keypath: WritableOptionalKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static>) -> Self
1239 where
1240 Root: Any + 'static,
1241 Value: Any + 'static,
1242 {
1243 let root_type_id = TypeId::of::<Root>();
1244 let value_type_id = TypeId::of::<Value>();
1245 let getter = keypath.getter;
1246
1247 Self {
1248 getter: Rc::new(move |any: &mut dyn Any| {
1249 if let Some(root) = any.downcast_mut::<Root>() {
1250 getter(root).map(|value: &mut Value| value as &mut dyn Any)
1251 } else {
1252 None
1253 }
1254 }),
1255 root_type_id,
1256 value_type_id,
1257 }
1258 }
1259
1260 pub fn get_mut<'r>(&self, root: &'r mut dyn Any) -> Option<&'r mut dyn Any> {
1261 (self.getter)(root)
1262 }
1263
1264 pub fn root_type_id(&self) -> TypeId {
1266 self.root_type_id
1267 }
1268
1269 pub fn value_type_id(&self) -> TypeId {
1271 self.value_type_id
1272 }
1273
1274 pub fn get_mut_as<'a, Root: Any, Value: Any>(&self, root: &'a mut Root) -> Option<Option<&'a mut Value>> {
1276 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>() {
1277 self.get_mut(root as &mut dyn Any).map(|any| any.downcast_mut::<Value>())
1278 } else {
1279 None
1280 }
1281 }
1282}
1283
1284impl<Root, Value, F> KeyPath<Root, Value, F>
1286where
1287 F: for<'r> Fn(&'r Root) -> &'r Value + 'static,
1288 Root: 'static,
1289 Value: Any + 'static,
1290{
1291 pub fn to_partial(self) -> PartialKeyPath<Root> {
1293 PartialKeyPath::new(self)
1294 }
1295
1296 pub fn to(self) -> PartialKeyPath<Root> {
1298 self.to_partial()
1299 }
1300}
1301
1302impl<Root, Value, F> OptionalKeyPath<Root, Value, F>
1303where
1304 F: for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static,
1305 Root: Any + 'static,
1306 Value: Any + 'static,
1307{
1308 pub fn to_partial(self) -> PartialOptionalKeyPath<Root> {
1310 PartialOptionalKeyPath::new(self)
1311 }
1312
1313 pub fn to_any(self) -> AnyKeyPath {
1315 AnyKeyPath::new(self)
1316 }
1317
1318 pub fn to(self) -> PartialOptionalKeyPath<Root> {
1320 self.to_partial()
1321 }
1322}
1323
1324impl<Root, Value, F> WritableKeyPath<Root, Value, F>
1325where
1326 F: for<'r> Fn(&'r mut Root) -> &'r mut Value + 'static,
1327 Root: 'static,
1328 Value: Any + 'static,
1329{
1330 pub fn to_partial(self) -> PartialWritableKeyPath<Root> {
1332 PartialWritableKeyPath::new(self)
1333 }
1334
1335 pub fn to(self) -> PartialWritableKeyPath<Root> {
1337 self.to_partial()
1338 }
1339}
1340
1341impl<Root, Value, F> WritableOptionalKeyPath<Root, Value, F>
1342where
1343 F: for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static,
1344 Root: Any + 'static,
1345 Value: Any + 'static,
1346{
1347 pub fn to_partial(self) -> PartialWritableOptionalKeyPath<Root> {
1349 PartialWritableOptionalKeyPath::new(self)
1350 }
1351
1352 pub fn to_any(self) -> AnyWritableKeyPath {
1354 AnyWritableKeyPath::new(self)
1355 }
1356
1357 pub fn to(self) -> PartialWritableOptionalKeyPath<Root> {
1359 self.to_partial()
1360 }
1361}
1362
1363#[cfg(test)]
1364mod tests {
1365 use super::*;
1366 use std::sync::atomic::{AtomicUsize, Ordering};
1367 use std::rc::Rc;
1368
1369 static ALLOC_COUNT: AtomicUsize = AtomicUsize::new(0);
1371 static DEALLOC_COUNT: AtomicUsize = AtomicUsize::new(0);
1372
1373 #[derive(Debug)]
1375 struct NoCloneType {
1376 id: usize,
1377 data: String,
1378 }
1379
1380 impl NoCloneType {
1381 fn new(data: String) -> Self {
1382 ALLOC_COUNT.fetch_add(1, Ordering::SeqCst);
1383 Self {
1384 id: ALLOC_COUNT.load(Ordering::SeqCst),
1385 data,
1386 }
1387 }
1388 }
1389
1390 impl Clone for NoCloneType {
1391 fn clone(&self) -> Self {
1392 panic!("NoCloneType should not be cloned! ID: {}", self.id);
1393 }
1394 }
1395
1396 impl Drop for NoCloneType {
1397 fn drop(&mut self) {
1398 DEALLOC_COUNT.fetch_add(1, Ordering::SeqCst);
1399 }
1400 }
1401
1402 fn reset_memory_counters() {
1404 ALLOC_COUNT.store(0, Ordering::SeqCst);
1405 DEALLOC_COUNT.store(0, Ordering::SeqCst);
1406 }
1407
1408 fn get_alloc_count() -> usize {
1409 ALLOC_COUNT.load(Ordering::SeqCst)
1410 }
1411
1412 fn get_dealloc_count() -> usize {
1413 DEALLOC_COUNT.load(Ordering::SeqCst)
1414 }
1415
1416#[derive(Debug)]
1418struct User {
1419 name: String,
1420 metadata: Option<Box<UserMetadata>>,
1421 friends: Vec<Arc<User>>,
1422}
1423
1424#[derive(Debug)]
1425struct UserMetadata {
1426 created_at: String,
1427}
1428
1429fn some_fn() {
1430 let akash = User {
1431 name: "Alice".to_string(),
1432 metadata: Some(Box::new(UserMetadata {
1433 created_at: "2024-01-01".to_string(),
1434 })),
1435 friends: vec![
1436 Arc::new(User {
1437 name: "Bob".to_string(),
1438 metadata: None,
1439 friends: vec![],
1440 }),
1441 ],
1442 };
1443
1444 let name_kp = KeyPath::new(|u: &User| &u.name);
1446 let metadata_kp = OptionalKeyPath::new(|u: &User| u.metadata.as_ref());
1447 let friends_kp = KeyPath::new(|u: &User| &u.friends);
1448
1449 println!("Name: {}", name_kp.get(&akash));
1451
1452 if let Some(metadata) = metadata_kp.get(&akash) {
1453 println!("Has metadata: {:?}", metadata);
1454 }
1455
1456 if let Some(first_friend) = akash.friends.get(0) {
1458 println!("First friend: {}", name_kp.get(first_friend));
1459 }
1460
1461 let created_at_kp = KeyPath::new(|m: &UserMetadata| &m.created_at);
1463
1464 if let Some(metadata) = akash.metadata.as_ref() {
1465 let boxed_metadata: &Box<UserMetadata> = metadata;
1467 let unwrapped = boxed_metadata.as_ref();
1468 println!("Created at: {:?}", created_at_kp.get(unwrapped));
1469 }
1470 }
1471
1472 #[test]
1473 fn test_name() {
1474 some_fn();
1475 }
1476
1477 #[test]
1478 fn test_no_cloning_on_keypath_operations() {
1479 reset_memory_counters();
1480
1481 let value = NoCloneType::new("test".to_string());
1483 let boxed = Box::new(value);
1484
1485 let kp = KeyPath::new(|b: &Box<NoCloneType>| b.as_ref());
1487
1488 let _ref = kp.get(&boxed);
1490
1491 let _kp_clone = kp.clone();
1493
1494 let _ref2 = _kp_clone.get(&boxed);
1496
1497 assert_eq!(get_alloc_count(), 1);
1499 }
1500
1501 #[test]
1502 fn test_no_cloning_on_optional_keypath_operations() {
1503 reset_memory_counters();
1504
1505 let value = NoCloneType::new("test".to_string());
1506 let opt = Some(Box::new(value));
1507
1508 let okp = OptionalKeyPath::new(|o: &Option<Box<NoCloneType>>| o.as_ref());
1510
1511 let _ref = okp.get(&opt);
1513
1514 let _okp_clone = okp.clone();
1516
1517 let chained = okp.then(OptionalKeyPath::new(|b: &Box<NoCloneType>| Some(b.as_ref())));
1519 let _ref2 = chained.get(&opt);
1520
1521 assert_eq!(get_alloc_count(), 1);
1522 }
1523
1524 #[test]
1525 fn test_memory_release() {
1526 reset_memory_counters();
1527
1528 {
1529 let value = NoCloneType::new("test".to_string());
1530 let boxed = Box::new(value);
1531 let kp = KeyPath::new(|b: &Box<NoCloneType>| b.as_ref());
1532
1533 let _ref = kp.get(&boxed);
1535
1536 }
1538
1539 assert_eq!(get_alloc_count(), 1);
1542 }
1545
1546 #[test]
1547 fn test_keypath_clone_does_not_clone_underlying_data() {
1548 reset_memory_counters();
1549
1550 let value = NoCloneType::new("data".to_string());
1551 let rc_value = Rc::new(value);
1552
1553 let kp = KeyPath::new(|r: &Rc<NoCloneType>| r.as_ref());
1555
1556 let kp1 = kp.clone();
1558 let kp2 = kp.clone();
1559 let kp3 = kp1.clone();
1560
1561 let _ref1 = kp.get(&rc_value);
1563 let _ref2 = kp1.get(&rc_value);
1564 let _ref3 = kp2.get(&rc_value);
1565 let _ref4 = kp3.get(&rc_value);
1566
1567 assert_eq!(get_alloc_count(), 1);
1569 }
1570
1571 #[test]
1572 fn test_optional_keypath_chaining_no_clone() {
1573 reset_memory_counters();
1574
1575 let value = NoCloneType::new("value1".to_string());
1576
1577 struct Container {
1578 inner: Option<Box<NoCloneType>>,
1579 }
1580
1581 let container = Container {
1582 inner: Some(Box::new(value)),
1583 };
1584
1585 let kp1 = OptionalKeyPath::new(|c: &Container| c.inner.as_ref());
1587 let kp2 = OptionalKeyPath::new(|b: &Box<NoCloneType>| Some(b.as_ref()));
1588
1589 let chained = kp1.then(kp2);
1591
1592 let _result = chained.get(&container);
1594
1595 assert_eq!(get_alloc_count(), 1);
1597 }
1598
1599 #[test]
1600 fn test_for_box_no_clone() {
1601 reset_memory_counters();
1602
1603 let value = NoCloneType::new("test".to_string());
1604 let boxed = Box::new(value);
1605 let opt_boxed = Some(boxed);
1606
1607 let kp = OptionalKeyPath::new(|o: &Option<Box<NoCloneType>>| o.as_ref());
1609 let unwrapped = kp.for_box();
1610
1611 let _ref = unwrapped.get(&opt_boxed);
1613
1614 assert_eq!(get_alloc_count(), 1);
1615 }
1616}