1use std::sync::{Arc, Mutex};
14
15pub mod lock;
17pub use lock::{
18 ArcMutexAccess, ArcRwLockAccess, LockAccess, LockKp, LockKpType, RcRefCellAccess,
19 StdMutexAccess, StdRwLockAccess,
20};
21
22#[cfg(feature = "parking_lot")]
23pub use lock::{
24 DirectParkingLotMutexAccess, DirectParkingLotRwLockAccess, ParkingLotMutexAccess,
25 ParkingLotRwLockAccess,
26};
27
28pub mod async_lock;
30
31pub trait KeyPathValueTarget {
35 type Target: Sized;
36}
37impl<T> KeyPathValueTarget for &T {
38 type Target = T;
39}
40impl<T> KeyPathValueTarget for &mut T {
41 type Target = T;
42}
43
44pub type KpDynamic<R, V> = Kp<
45 R,
46 V,
47 &'static R,
48 &'static V,
49 &'static mut R,
50 &'static mut V,
51 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V>>,
52 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V>>,
53>;
54
55pub type KpType<'a, R, V> = Kp<
56 R,
57 V,
58 &'a R,
59 &'a V,
60 &'a mut R,
61 &'a mut V,
62 for<'b> fn(&'b R) -> Option<&'b V>,
63 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
64>;
65
66pub type KpComposed<R, V> = Kp<
102 R,
103 V,
104 &'static R,
105 &'static V,
106 &'static mut R,
107 &'static mut V,
108 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V>>,
109 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V>>,
110>;
111
112impl<R, V> Kp<
113 R,
114 V,
115 &'static R,
116 &'static V,
117 &'static mut R,
118 &'static mut V,
119 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V>>,
120 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V>>,
121> {
122 pub fn from_closures<G, S>(get: G, set: S) -> Self
125 where
126 G: for<'b> Fn(&'b R) -> Option<&'b V> + 'static,
127 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + 'static,
128 {
129 Self::new(Box::new(get), Box::new(set))
130 }
131}
132
133pub struct AKp {
134 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
135 root_type_id: TypeId,
136 value_type_id: TypeId,
137}
138
139impl AKp {
140 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
142 where
143 R: Any + 'static,
144 V: Any + 'static,
145 {
146 let root_type_id = TypeId::of::<R>();
147 let value_type_id = TypeId::of::<V>();
148 let getter_fn = keypath.get;
149
150 Self {
151 getter: Rc::new(move |any: &dyn Any| {
152 if let Some(root) = any.downcast_ref::<R>() {
153 getter_fn(root).map(|value: &V| value as &dyn Any)
154 } else {
155 None
156 }
157 }),
158 root_type_id,
159 value_type_id,
160 }
161 }
162
163 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
165 where
166 R: Any + 'static,
167 V: Any + 'static,
168 {
169 Self::new(keypath)
170 }
171
172 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
174 (self.getter)(root)
175 }
176
177 pub fn root_type_id(&self) -> TypeId {
179 self.root_type_id
180 }
181
182 pub fn value_type_id(&self) -> TypeId {
184 self.value_type_id
185 }
186
187 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
189 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
190 {
191 Some(
192 self.get(root as &dyn Any)
193 .and_then(|any| any.downcast_ref::<Value>()),
194 )
195 } else {
196 None
197 }
198 }
199
200 pub fn kind_name(&self) -> String {
202 format!("{:?}", self.value_type_id)
203 }
204
205 pub fn root_kind_name(&self) -> String {
207 format!("{:?}", self.root_type_id)
208 }
209
210 pub fn for_arc<Root>(&self) -> AKp
212 where
213 Root: Any + 'static,
214 {
215 let value_type_id = self.value_type_id;
216 let getter = self.getter.clone();
217
218 AKp {
219 getter: Rc::new(move |any: &dyn Any| {
220 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
221 getter(arc.as_ref() as &dyn Any)
222 } else {
223 None
224 }
225 }),
226 root_type_id: TypeId::of::<Arc<Root>>(),
227 value_type_id,
228 }
229 }
230
231 pub fn for_box<Root>(&self) -> AKp
233 where
234 Root: Any + 'static,
235 {
236 let value_type_id = self.value_type_id;
237 let getter = self.getter.clone();
238
239 AKp {
240 getter: Rc::new(move |any: &dyn Any| {
241 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
242 getter(boxed.as_ref() as &dyn Any)
243 } else {
244 None
245 }
246 }),
247 root_type_id: TypeId::of::<Box<Root>>(),
248 value_type_id,
249 }
250 }
251
252 pub fn for_rc<Root>(&self) -> AKp
254 where
255 Root: Any + 'static,
256 {
257 let value_type_id = self.value_type_id;
258 let getter = self.getter.clone();
259
260 AKp {
261 getter: Rc::new(move |any: &dyn Any| {
262 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
263 getter(rc.as_ref() as &dyn Any)
264 } else {
265 None
266 }
267 }),
268 root_type_id: TypeId::of::<Rc<Root>>(),
269 value_type_id,
270 }
271 }
272
273 pub fn for_option<Root>(&self) -> AKp
275 where
276 Root: Any + 'static,
277 {
278 let value_type_id = self.value_type_id;
279 let getter = self.getter.clone();
280
281 AKp {
282 getter: Rc::new(move |any: &dyn Any| {
283 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
284 opt.as_ref().and_then(|root| getter(root as &dyn Any))
285 } else {
286 None
287 }
288 }),
289 root_type_id: TypeId::of::<Option<Root>>(),
290 value_type_id,
291 }
292 }
293
294 pub fn for_result<Root, E>(&self) -> AKp
296 where
297 Root: Any + 'static,
298 E: Any + 'static,
299 {
300 let value_type_id = self.value_type_id;
301 let getter = self.getter.clone();
302
303 AKp {
304 getter: Rc::new(move |any: &dyn Any| {
305 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
306 result
307 .as_ref()
308 .ok()
309 .and_then(|root| getter(root as &dyn Any))
310 } else {
311 None
312 }
313 }),
314 root_type_id: TypeId::of::<Result<Root, E>>(),
315 value_type_id,
316 }
317 }
318
319 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
332 where
333 Root: Any + 'static,
334 OrigValue: Any + 'static,
335 MappedValue: Any + 'static,
336 F: Fn(&OrigValue) -> MappedValue + 'static,
337 {
338 let orig_root_type_id = self.root_type_id;
339 let orig_value_type_id = self.value_type_id;
340 let getter = self.getter.clone();
341 let mapped_type_id = TypeId::of::<MappedValue>();
342
343 AKp {
344 getter: Rc::new(move |any_root: &dyn Any| {
345 if any_root.type_id() == orig_root_type_id {
347 getter(any_root).and_then(|any_value| {
348 if orig_value_type_id == TypeId::of::<OrigValue>() {
350 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
351 let mapped = mapper(orig_val);
352 Box::leak(Box::new(mapped)) as &dyn Any
354 })
355 } else {
356 None
357 }
358 })
359 } else {
360 None
361 }
362 }),
363 root_type_id: orig_root_type_id,
364 value_type_id: mapped_type_id,
365 }
366 }
367
368 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
381 where
382 Root: Any + 'static,
383 Value: Any + 'static,
384 F: Fn(&Value) -> bool + 'static,
385 {
386 let orig_root_type_id = self.root_type_id;
387 let orig_value_type_id = self.value_type_id;
388 let getter = self.getter.clone();
389
390 AKp {
391 getter: Rc::new(move |any_root: &dyn Any| {
392 if any_root.type_id() == orig_root_type_id {
394 getter(any_root).filter(|any_value| {
395 if orig_value_type_id == TypeId::of::<Value>() {
397 any_value
398 .downcast_ref::<Value>()
399 .map(|val| predicate(val))
400 .unwrap_or(false)
401 } else {
402 false
403 }
404 })
405 } else {
406 None
407 }
408 }),
409 root_type_id: orig_root_type_id,
410 value_type_id: orig_value_type_id,
411 }
412 }
413}
414pub struct PKp<Root> {
415 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
416 value_type_id: TypeId,
417 _phantom: std::marker::PhantomData<Root>,
418}
419
420impl<Root> PKp<Root>
421where
422 Root: 'static,
423{
424 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
426 where
427 V: Any + 'static,
428 {
429 let value_type_id = TypeId::of::<V>();
430 let getter_fn = keypath.get;
431
432 Self {
433 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
434 value_type_id,
435 _phantom: std::marker::PhantomData,
436 }
437 }
438
439 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
441 where
442 V: Any + 'static,
443 {
444 Self::new(keypath)
445 }
446
447 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
449 (self.getter)(root)
450 }
451
452 pub fn value_type_id(&self) -> TypeId {
454 self.value_type_id
455 }
456
457 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
459 if self.value_type_id == TypeId::of::<Value>() {
460 self.get(root).and_then(|any| any.downcast_ref::<Value>())
461 } else {
462 None
463 }
464 }
465
466 pub fn kind_name(&self) -> String {
468 format!("{:?}", self.value_type_id)
469 }
470
471 pub fn for_arc(&self) -> PKp<Arc<Root>> {
473 let getter = self.getter.clone();
474 let value_type_id = self.value_type_id;
475
476 PKp {
477 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
478 value_type_id,
479 _phantom: std::marker::PhantomData,
480 }
481 }
482
483 pub fn for_box(&self) -> PKp<Box<Root>> {
485 let getter = self.getter.clone();
486 let value_type_id = self.value_type_id;
487
488 PKp {
489 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
490 value_type_id,
491 _phantom: std::marker::PhantomData,
492 }
493 }
494
495 pub fn for_rc(&self) -> PKp<Rc<Root>> {
497 let getter = self.getter.clone();
498 let value_type_id = self.value_type_id;
499
500 PKp {
501 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
502 value_type_id,
503 _phantom: std::marker::PhantomData,
504 }
505 }
506
507 pub fn for_option(&self) -> PKp<Option<Root>> {
509 let getter = self.getter.clone();
510 let value_type_id = self.value_type_id;
511
512 PKp {
513 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
514 value_type_id,
515 _phantom: std::marker::PhantomData,
516 }
517 }
518
519 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
521 where
522 E: 'static,
523 {
524 let getter = self.getter.clone();
525 let value_type_id = self.value_type_id;
526
527 PKp {
528 getter: Rc::new(move |result: &Result<Root, E>| {
529 result.as_ref().ok().and_then(|root| getter(root))
530 }),
531 value_type_id,
532 _phantom: std::marker::PhantomData,
533 }
534 }
535
536 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
550 where
551 OrigValue: Any + 'static,
552 MappedValue: Any + 'static,
553 F: Fn(&OrigValue) -> MappedValue + 'static,
554 {
555 let orig_type_id = self.value_type_id;
556 let getter = self.getter.clone();
557 let mapped_type_id = TypeId::of::<MappedValue>();
558
559 PKp {
560 getter: Rc::new(move |root: &Root| {
561 getter(root).and_then(|any_value| {
562 if orig_type_id == TypeId::of::<OrigValue>() {
564 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
565 let mapped = mapper(orig_val);
566 Box::leak(Box::new(mapped)) as &dyn Any
569 })
570 } else {
571 None
572 }
573 })
574 }),
575 value_type_id: mapped_type_id,
576 _phantom: std::marker::PhantomData,
577 }
578 }
579
580 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
594 where
595 Value: Any + 'static,
596 F: Fn(&Value) -> bool + 'static,
597 {
598 let orig_type_id = self.value_type_id;
599 let getter = self.getter.clone();
600
601 PKp {
602 getter: Rc::new(move |root: &Root| {
603 getter(root).filter(|any_value| {
604 if orig_type_id == TypeId::of::<Value>() {
606 any_value
607 .downcast_ref::<Value>()
608 .map(|val| predicate(val))
609 .unwrap_or(false)
610 } else {
611 false
612 }
613 })
614 }),
615 value_type_id: orig_type_id,
616 _phantom: std::marker::PhantomData,
617 }
618 }
619}
620
621#[derive(Clone)]
635pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
636where
637 Root: std::borrow::Borrow<R>,
638 MutRoot: std::borrow::BorrowMut<R>,
639 MutValue: std::borrow::BorrowMut<V>,
640 G: Fn(Root) -> Option<Value>,
641 S: Fn(MutRoot) -> Option<MutValue>,
642{
643 pub(crate) get: G,
645 pub(crate) set: S,
647 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
648}
649
650impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
651where
652 Root: std::borrow::Borrow<R>,
653 Value: std::borrow::Borrow<V>,
654 MutRoot: std::borrow::BorrowMut<R>,
655 MutValue: std::borrow::BorrowMut<V>,
656 G: Fn(Root) -> Option<Value>,
657 S: Fn(MutRoot) -> Option<MutValue>,
658{
659 pub fn new(get: G, set: S) -> Self {
660 Self {
661 get: get,
662 set: set,
663 _p: std::marker::PhantomData,
664 }
665 }
666
667 #[inline]
668 pub fn get(&self, root: Root) -> Option<Value> {
669 (self.get)(root)
670 }
671 #[inline]
672 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
673 (self.set)(root)
674 }
675
676 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
677 self,
678 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
679 ) -> Kp<
680 R,
681 SV,
682 Root,
683 SubValue,
684 MutRoot,
685 MutSubValue,
686 impl Fn(Root) -> Option<SubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
687 impl Fn(MutRoot) -> Option<MutSubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
688 >
689 where
690 SubValue: std::borrow::Borrow<SV>,
691 MutSubValue: std::borrow::BorrowMut<SV>,
692 G2: Fn(Value) -> Option<SubValue>,
693 S2: Fn(MutValue) -> Option<MutSubValue>,
694 V: 'static,
695 {
696 Kp::new(
697 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
698 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
699 )
700 }
701
702 pub fn then_lock<
704 Lock,
705 Mid,
706 V2,
707 LockValue,
708 MidValue,
709 Value2,
710 MutLock,
711 MutMid,
712 MutValue2,
713 G1,
714 S1,
715 L,
716 G2,
717 S2,
718 >(
719 self,
720 lock_kp: crate::lock::LockKp<
721 V,
722 Lock,
723 Mid,
724 V2,
725 Value,
726 LockValue,
727 MidValue,
728 Value2,
729 MutValue,
730 MutLock,
731 MutMid,
732 MutValue2,
733 G1,
734 S1,
735 L,
736 G2,
737 S2,
738 >,
739 ) -> crate::lock::KpThenLockKp<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, Self, crate::lock::LockKp<V, Lock, Mid, V2, Value, LockValue, MidValue, Value2, MutValue, MutLock, MutMid, MutValue2, G1, S1, L, G2, S2>>
740 where
741 V: 'static + Clone,
742 V2: 'static,
743 Value: std::borrow::Borrow<V>,
744 Value2: std::borrow::Borrow<V2>,
745 MutValue: std::borrow::BorrowMut<V>,
746 MutValue2: std::borrow::BorrowMut<V2>,
747 LockValue: std::borrow::Borrow<Lock>,
748 MidValue: std::borrow::Borrow<Mid>,
749 MutLock: std::borrow::BorrowMut<Lock>,
750 MutMid: std::borrow::BorrowMut<Mid>,
751 G1: Fn(Value) -> Option<LockValue>,
752 S1: Fn(MutValue) -> Option<MutLock>,
753 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
754 G2: Fn(MidValue) -> Option<Value2>,
755 S2: Fn(MutMid) -> Option<MutValue2>,
756 {
757 crate::lock::KpThenLockKp {
758 first: self,
759 second: lock_kp,
760 _p: std::marker::PhantomData,
761 }
762 }
763
764 pub fn then_async<AsyncKp>(
767 self,
768 async_kp: AsyncKp,
769 ) -> crate::async_lock::KpThenAsyncKeyPath<
770 R,
771 V,
772 <AsyncKp::Value as KeyPathValueTarget>::Target,
773 Root,
774 Value,
775 AsyncKp::Value,
776 MutRoot,
777 MutValue,
778 AsyncKp::MutValue,
779 Self,
780 AsyncKp,
781 >
782 where
783 V: 'static,
784 Value: std::borrow::Borrow<V>,
785 MutValue: std::borrow::BorrowMut<V>,
786 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
787 AsyncKp::Value: KeyPathValueTarget
788 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
789 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
790 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
791 {
792 crate::async_lock::KpThenAsyncKeyPath {
793 first: self,
794 second: async_kp,
795 _p: std::marker::PhantomData,
796 }
797 }
798
799 pub fn map<MappedValue, F>(
812 &self,
813 mapper: F,
814 ) -> Kp<
815 R,
816 MappedValue,
817 Root,
818 MappedValue,
819 MutRoot,
820 MappedValue,
821 impl Fn(Root) -> Option<MappedValue>,
822 impl Fn(MutRoot) -> Option<MappedValue>,
823 >
824 where
825 F: Fn(&V) -> MappedValue + Copy + 'static,
828 V: 'static,
829 MappedValue: 'static,
830 {
831 Kp::new(
832 move |root: Root| {
833 (&self.get)(root).map(|value| {
834 let v: &V = value.borrow();
835 mapper(v)
836 })
837 },
838 move |root: MutRoot| {
839 (&self.set)(root).map(|value| {
840 let v: &V = value.borrow();
841 mapper(v)
842 })
843 },
844 )
845 }
846
847 pub fn filter<F>(
860 &self,
861 predicate: F,
862 ) -> Kp<
863 R,
864 V,
865 Root,
866 Value,
867 MutRoot,
868 MutValue,
869 impl Fn(Root) -> Option<Value>,
870 impl Fn(MutRoot) -> Option<MutValue>,
871 >
872 where
873 F: Fn(&V) -> bool + Copy + 'static,
876 V: 'static,
877 {
878 Kp::new(
879 move |root: Root| {
880 (&self.get)(root).filter(|value| {
881 let v: &V = value.borrow();
882 predicate(v)
883 })
884 },
885 move |root: MutRoot| {
886 (&self.set)(root).filter(|value| {
887 let v: &V = value.borrow();
888 predicate(v)
889 })
890 },
891 )
892 }
893
894 pub fn filter_map<MappedValue, F>(
907 &self,
908 mapper: F,
909 ) -> Kp<
910 R,
911 MappedValue,
912 Root,
913 MappedValue,
914 MutRoot,
915 MappedValue,
916 impl Fn(Root) -> Option<MappedValue>,
917 impl Fn(MutRoot) -> Option<MappedValue>,
918 >
919 where
920 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
923 V: 'static,
924 MappedValue: 'static,
925 {
926 Kp::new(
927 move |root: Root| {
928 (&self.get)(root).and_then(|value| {
929 let v: &V = value.borrow();
930 mapper(v)
931 })
932 },
933 move |root: MutRoot| {
934 (&self.set)(root).and_then(|value| {
935 let v: &V = value.borrow();
936 mapper(v)
937 })
938 },
939 )
940 }
941
942 pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
954 where
955 F: Fn(&V) -> I + 'static,
958 V: 'static,
959 I: IntoIterator<Item = Item>,
960 Item: 'static,
961 {
962 move |root: Root| {
963 (&self.get)(root)
964 .map(|value| {
965 let v: &V = value.borrow();
966 mapper(v).into_iter().collect()
967 })
968 .unwrap_or_else(Vec::new)
969 }
970 }
971
972 pub fn inspect<F>(
983 &self,
984 inspector: F,
985 ) -> Kp<
986 R,
987 V,
988 Root,
989 Value,
990 MutRoot,
991 MutValue,
992 impl Fn(Root) -> Option<Value>,
993 impl Fn(MutRoot) -> Option<MutValue>,
994 >
995 where
996 F: Fn(&V) + Copy + 'static,
999 V: 'static,
1000 {
1001 Kp::new(
1002 move |root: Root| {
1003 (&self.get)(root).map(|value| {
1004 let v: &V = value.borrow();
1005 inspector(v);
1006 value
1007 })
1008 },
1009 move |root: MutRoot| {
1010 (&self.set)(root).map(|value| {
1011 let v: &V = value.borrow();
1012 inspector(v);
1013 value
1014 })
1015 },
1016 )
1017 }
1018
1019 pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
1033 where
1034 F: Fn(Acc, &V) -> Acc + 'static,
1037 V: 'static,
1038 Acc: Copy + 'static,
1040 {
1041 move |root: Root| {
1042 (&self.get)(root)
1043 .map(|value| {
1044 let v: &V = value.borrow();
1045 folder(init, v)
1046 })
1047 .unwrap_or(init)
1048 }
1049 }
1050
1051 pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1063 where
1064 F: Fn(&V) -> bool + 'static,
1067 V: 'static,
1068 {
1069 move |root: Root| {
1070 (&self.get)(root)
1071 .map(|value| {
1072 let v: &V = value.borrow();
1073 predicate(v)
1074 })
1075 .unwrap_or(false)
1076 }
1077 }
1078
1079 pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1091 where
1092 F: Fn(&V) -> bool + 'static,
1095 V: 'static,
1096 {
1097 move |root: Root| {
1098 (&self.get)(root)
1099 .map(|value| {
1100 let v: &V = value.borrow();
1101 predicate(v)
1102 })
1103 .unwrap_or(true)
1104 }
1105 }
1106
1107 pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
1119 where
1120 F: Fn(&V) -> usize + 'static,
1123 V: 'static,
1124 {
1125 move |root: Root| {
1126 (&self.get)(root).map(|value| {
1127 let v: &V = value.borrow();
1128 counter(v)
1129 })
1130 }
1131 }
1132
1133 pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
1147 where
1148 F: Fn(&V) -> Option<Item> + 'static,
1151 V: 'static,
1152 Item: 'static,
1153 {
1154 move |root: Root| {
1155 (&self.get)(root).and_then(|value| {
1156 let v: &V = value.borrow();
1157 finder(v)
1158 })
1159 }
1160 }
1161
1162 pub fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output>
1173 where
1174 F: Fn(&V, usize) -> Output + 'static,
1177 V: 'static,
1178 Output: 'static,
1179 {
1180 move |root: Root| {
1181 (&self.get)(root).map(|value| {
1182 let v: &V = value.borrow();
1183 taker(v, n)
1184 })
1185 }
1186 }
1187
1188 pub fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output>
1199 where
1200 F: Fn(&V, usize) -> Output + 'static,
1203 V: 'static,
1204 Output: 'static,
1205 {
1206 move |root: Root| {
1207 (&self.get)(root).map(|value| {
1208 let v: &V = value.borrow();
1209 skipper(v, n)
1210 })
1211 }
1212 }
1213
1214 pub fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output>
1227 where
1228 F: Fn(&V) -> Output + 'static,
1231 V: 'static,
1232 Output: 'static,
1233 {
1234 move |root: Root| {
1235 (&self.get)(root).map(|value| {
1236 let v: &V = value.borrow();
1237 partitioner(v)
1238 })
1239 }
1240 }
1241
1242 pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
1254 where
1255 F: Fn(&V) -> Option<Item> + 'static,
1258 V: 'static,
1259 Item: 'static,
1260 {
1261 move |root: Root| {
1262 (&self.get)(root).and_then(|value| {
1263 let v: &V = value.borrow();
1264 min_fn(v)
1265 })
1266 }
1267 }
1268
1269 pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
1281 where
1282 F: Fn(&V) -> Option<Item> + 'static,
1285 V: 'static,
1286 Item: 'static,
1287 {
1288 move |root: Root| {
1289 (&self.get)(root).and_then(|value| {
1290 let v: &V = value.borrow();
1291 max_fn(v)
1292 })
1293 }
1294 }
1295
1296 pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
1308 where
1309 F: Fn(&V) -> Sum + 'static,
1312 V: 'static,
1313 Sum: 'static,
1314 {
1315 move |root: Root| {
1316 (&self.get)(root).map(|value| {
1317 let v: &V = value.borrow();
1318 sum_fn(v)
1319 })
1320 }
1321 }
1322
1323 pub fn chain<SV, SubValue, MutSubValue, G2, S2>(
1326 self,
1327 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1328 ) -> Kp<
1329 R,
1330 SV,
1331 Root,
1332 SubValue,
1333 MutRoot,
1334 MutSubValue,
1335 impl Fn(Root) -> Option<SubValue>,
1336 impl Fn(MutRoot) -> Option<MutSubValue>,
1337 >
1338 where
1339 SubValue: std::borrow::Borrow<SV>,
1340 MutSubValue: std::borrow::BorrowMut<SV>,
1341 G2: Fn(Value) -> Option<SubValue>,
1342 S2: Fn(MutValue) -> Option<MutSubValue>,
1343 V: 'static,
1344 {
1345 self.then(next)
1346 }
1347
1348 pub fn for_arc<'b>(
1349 &self,
1350 ) -> Kp<
1351 std::sync::Arc<R>,
1352 V,
1353 std::sync::Arc<R>,
1354 Value,
1355 std::sync::Arc<R>,
1356 MutValue,
1357 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1358 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1359 >
1360 where
1361 R: 'b,
1362 V: 'b,
1363 Root: for<'a> From<&'a R>,
1364 MutRoot: for<'a> From<&'a mut R>,
1365 {
1366 Kp::new(
1367 move |arc_root: std::sync::Arc<R>| {
1368 let r_ref: &R = &*arc_root;
1369 (&self.get)(Root::from(r_ref))
1370 },
1371 move |mut arc_root: std::sync::Arc<R>| {
1372 std::sync::Arc::get_mut(&mut arc_root)
1374 .and_then(|r_mut| (&self.set)(MutRoot::from(r_mut)))
1375 },
1376 )
1377 }
1378
1379 pub fn for_box<'a>(
1380 &self,
1381 ) -> Kp<
1382 Box<R>,
1383 V,
1384 Box<R>,
1385 Value,
1386 Box<R>,
1387 MutValue,
1388 impl Fn(Box<R>) -> Option<Value>,
1389 impl Fn(Box<R>) -> Option<MutValue>,
1390 >
1391 where
1392 R: 'a,
1393 V: 'a,
1394 Root: for<'b> From<&'b R>,
1395 MutRoot: for<'b> From<&'b mut R>,
1396 {
1397 Kp::new(
1398 move |r: Box<R>| {
1399 let r_ref: &R = r.as_ref();
1400 (&self.get)(Root::from(r_ref))
1401 },
1402 move |mut r: Box<R>| {
1403 (self.set)(MutRoot::from(r.as_mut()))
1405 },
1406 )
1407 }
1408}
1409
1410pub fn zip_kps<'a, RootType, Value1, Value2>(
1424 kp1: &'a KpType<'a, RootType, Value1>,
1425 kp2: &'a KpType<'a, RootType, Value2>,
1426) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1427where
1428 RootType: 'a,
1429 Value1: 'a,
1430 Value2: 'a,
1431{
1432 move |root: &'a RootType| {
1433 let val1 = (kp1.get)(root)?;
1434 let val2 = (kp2.get)(root)?;
1435 Some((val1, val2))
1436 }
1437}
1438
1439impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1440where
1441 Root: std::borrow::Borrow<R>,
1442 MutRoot: std::borrow::BorrowMut<R>,
1443 G: Fn(Root) -> Option<Root>,
1444 S: Fn(MutRoot) -> Option<MutRoot>,
1445{
1446 pub fn identity_typed() -> Kp<
1447 R,
1448 R,
1449 Root,
1450 Root,
1451 MutRoot,
1452 MutRoot,
1453 fn(Root) -> Option<Root>,
1454 fn(MutRoot) -> Option<MutRoot>,
1455 > {
1456 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1457 }
1458
1459 pub fn identity<'a>() -> KpType<'a, R, R> {
1460 KpType::new(|r| Some(r), |r| Some(r))
1461 }
1462}
1463
1464pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1473where
1474 Root: std::borrow::Borrow<Enum>,
1475 Value: std::borrow::Borrow<Variant>,
1476 MutRoot: std::borrow::BorrowMut<Enum>,
1477 MutValue: std::borrow::BorrowMut<Variant>,
1478 G: Fn(Root) -> Option<Value>,
1479 S: Fn(MutRoot) -> Option<MutValue>,
1480 E: Fn(Variant) -> Enum,
1481{
1482 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1483 embedder: E,
1484}
1485
1486impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1487 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1488where
1489 Root: std::borrow::Borrow<Enum>,
1490 Value: std::borrow::Borrow<Variant>,
1491 MutRoot: std::borrow::BorrowMut<Enum>,
1492 MutValue: std::borrow::BorrowMut<Variant>,
1493 G: Fn(Root) -> Option<Value>,
1494 S: Fn(MutRoot) -> Option<MutValue>,
1495 E: Fn(Variant) -> Enum,
1496{
1497 pub fn new(
1499 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1500 embedder: E,
1501 ) -> Self {
1502 Self {
1503 extractor,
1504 embedder,
1505 }
1506 }
1507
1508 pub fn get(&self, enum_value: Root) -> Option<Value> {
1510 self.extractor.get(enum_value)
1511 }
1512
1513 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1515 self.extractor.get_mut(enum_value)
1516 }
1517
1518 pub fn embed(&self, value: Variant) -> Enum {
1520 (self.embedder)(value)
1521 }
1522
1523 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1525 &self.extractor
1526 }
1527
1528 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1530 self.extractor
1531 }
1532
1533 pub fn map<MappedValue, F>(
1544 &self,
1545 mapper: F,
1546 ) -> EnumKp<
1547 Enum,
1548 MappedValue,
1549 Root,
1550 MappedValue,
1551 MutRoot,
1552 MappedValue,
1553 impl Fn(Root) -> Option<MappedValue>,
1554 impl Fn(MutRoot) -> Option<MappedValue>,
1555 impl Fn(MappedValue) -> Enum,
1556 >
1557 where
1558 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1561 Variant: 'static,
1562 MappedValue: 'static,
1563 E: Fn(Variant) -> Enum + Copy + 'static,
1565 {
1566 let mapped_extractor = self.extractor.map(mapper);
1567
1568 let new_embedder = move |_value: MappedValue| -> Enum {
1572 panic!(
1573 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1574 )
1575 };
1576
1577 EnumKp::new(mapped_extractor, new_embedder)
1578 }
1579
1580 pub fn filter<F>(
1592 &self,
1593 predicate: F,
1594 ) -> EnumKp<
1595 Enum,
1596 Variant,
1597 Root,
1598 Value,
1599 MutRoot,
1600 MutValue,
1601 impl Fn(Root) -> Option<Value>,
1602 impl Fn(MutRoot) -> Option<MutValue>,
1603 E,
1604 >
1605 where
1606 F: Fn(&Variant) -> bool + Copy + 'static,
1609 Variant: 'static,
1610 E: Copy,
1612 {
1613 let filtered_extractor = self.extractor.filter(predicate);
1614 EnumKp::new(filtered_extractor, self.embedder)
1615 }
1616}
1617
1618pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1620 Enum,
1621 Variant,
1622 &'a Enum,
1623 &'a Variant,
1624 &'a mut Enum,
1625 &'a mut Variant,
1626 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1627 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1628 fn(Variant) -> Enum,
1629>;
1630
1631pub fn enum_variant<'a, Enum, Variant>(
1649 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1650 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1651 embedder: fn(Variant) -> Enum,
1652) -> EnumKpType<'a, Enum, Variant> {
1653 EnumKp::new(Kp::new(getter, setter), embedder)
1654}
1655
1656pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1666 EnumKp::new(
1667 Kp::new(
1668 |r: &Result<T, E>| r.as_ref().ok(),
1669 |r: &mut Result<T, E>| r.as_mut().ok(),
1670 ),
1671 |t: T| Ok(t),
1672 )
1673}
1674
1675pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1685 EnumKp::new(
1686 Kp::new(
1687 |r: &Result<T, E>| r.as_ref().err(),
1688 |r: &mut Result<T, E>| r.as_mut().err(),
1689 ),
1690 |e: E| Err(e),
1691 )
1692}
1693
1694pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1704 EnumKp::new(
1705 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1706 |t: T| Some(t),
1707 )
1708}
1709
1710pub fn variant_of<'a, Enum, Variant>(
1728 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1729 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1730 embedder: fn(Variant) -> Enum,
1731) -> EnumKpType<'a, Enum, Variant> {
1732 enum_variant(getter, setter, embedder)
1733}
1734
1735pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1748 Kp::new(
1749 |b: &Box<T>| Some(b.as_ref()),
1750 |b: &mut Box<T>| Some(b.as_mut()),
1751 )
1752}
1753
1754pub fn kp_arc<'a, T>() -> Kp<
1765 Arc<T>,
1766 T,
1767 &'a Arc<T>,
1768 &'a T,
1769 &'a mut Arc<T>,
1770 &'a mut T,
1771 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
1772 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
1773> {
1774 Kp::new(
1775 |arc: &Arc<T>| Some(arc.as_ref()),
1776 |arc: &mut Arc<T>| Arc::get_mut(arc),
1777 )
1778}
1779
1780pub fn kp_rc<'a, T>() -> Kp<
1791 std::rc::Rc<T>,
1792 T,
1793 &'a std::rc::Rc<T>,
1794 &'a T,
1795 &'a mut std::rc::Rc<T>,
1796 &'a mut T,
1797 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
1798 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
1799> {
1800 Kp::new(
1801 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
1802 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
1803 )
1804}
1805
1806use std::any::{Any, TypeId};
1809use std::rc::Rc;
1810
1811#[cfg(test)]
1826mod tests {
1827 use super::*;
1828 use std::collections::HashMap;
1829
1830 #[derive(Debug)]
1831 struct TestKP {
1832 a: String,
1833 b: String,
1834 c: std::sync::Arc<String>,
1835 d: std::sync::Mutex<String>,
1836 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
1837 f: Option<TestKP2>,
1838 g: HashMap<i32, TestKP2>,
1839 }
1840
1841 impl TestKP {
1842 fn new() -> Self {
1843 Self {
1844 a: String::from("a"),
1845 b: String::from("b"),
1846 c: std::sync::Arc::new(String::from("c")),
1847 d: std::sync::Mutex::new(String::from("d")),
1848 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
1849 f: Some(TestKP2 {
1850 a: String::from("a3"),
1851 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1852 }),
1853 g: HashMap::new(),
1854 }
1855 }
1856
1857 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
1858 KpComposed::from_closures(
1859 move |r: &TestKP| r.g.get(&index),
1860 move |r: &mut TestKP| r.g.get_mut(&index),
1861 )
1862 }
1863
1864 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
1867 TestKP2,
1868 String,
1869 Root,
1870 Value,
1871 MutRoot,
1872 MutValue,
1873 impl Fn(Root) -> Option<Value>,
1874 impl Fn(MutRoot) -> Option<MutValue>,
1875 >
1876 where
1877 Root: std::borrow::Borrow<TestKP2>,
1878 MutRoot: std::borrow::BorrowMut<TestKP2>,
1879 Value: std::borrow::Borrow<String> + From<String>,
1880 MutValue: std::borrow::BorrowMut<String> + From<String>,
1881 {
1882 Kp::new(
1883 |r: Root| Some(Value::from(r.borrow().a.clone())),
1884 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
1885 )
1886 }
1887
1888 fn c<'a>() -> KpType<'a, TestKP, String> {
1891 KpType::new(
1892 |r: &TestKP| Some(r.c.as_ref()),
1893 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
1894 Some(arc_str) => Some(arc_str),
1895 None => None,
1896 },
1897 )
1898 }
1899
1900 fn a<'a>() -> KpType<'a, TestKP, String> {
1901 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
1902 }
1903
1904 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
1905 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
1906 }
1907
1908 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
1909 KpType::identity()
1910 }
1911 }
1912
1913 #[derive(Debug)]
1914 struct TestKP2 {
1915 a: String,
1916 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
1917 }
1918
1919 impl TestKP2 {
1920 fn new() -> Self {
1921 TestKP2 {
1922 a: String::from("a2"),
1923 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1924 }
1925 }
1926
1927 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1928 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
1935 fn(MutRoot) -> Option<MutRoot>,
1936 >
1937 where
1938 Root: std::borrow::Borrow<TestKP2>,
1939 MutRoot: std::borrow::BorrowMut<TestKP2>,
1940 G: Fn(Root) -> Option<Root>,
1941 S: Fn(MutRoot) -> Option<MutRoot>,
1942 {
1943 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1944 }
1945
1946 fn a<'a>() -> KpType<'a, TestKP2, String> {
1947 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
1948 }
1949
1950 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
1951 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
1952 }
1953
1954 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
1959 KpType::identity()
1960 }
1961 }
1962
1963 #[derive(Debug)]
1964 struct TestKP3 {
1965 a: String,
1966 b: std::sync::Arc<std::sync::Mutex<String>>,
1967 }
1968
1969 impl TestKP3 {
1970 fn new() -> Self {
1971 TestKP3 {
1972 a: String::from("a2"),
1973 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
1974 }
1975 }
1976
1977 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1978 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
1985 fn(MutRoot) -> Option<MutRoot>,
1986 >
1987 where
1988 Root: std::borrow::Borrow<TestKP3>,
1989 MutRoot: std::borrow::BorrowMut<TestKP3>,
1990 G: Fn(Root) -> Option<Root>,
1991 S: Fn(MutRoot) -> Option<MutRoot>,
1992 {
1993 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1994 }
1995
1996 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
1997 KpType::identity()
1998 }
1999 }
2000
2001 impl TestKP3 {}
2002
2003 impl TestKP {}
2004 #[test]
2005 fn test_a() {
2006 let instance2 = TestKP2::new();
2007 let mut instance = TestKP::new();
2008 let kp = TestKP::identity();
2009 let kp_a = TestKP::a();
2010 let wres = TestKP::f().then(TestKP2::a()).get_mut(&mut instance).unwrap();
2012 *wres = String::from("a3 changed successfully");
2013 let res = TestKP::f().then(TestKP2::a()).get(&instance);
2014 println!("{:?}", res);
2015 let res = TestKP::f().then(TestKP2::identity()).get(&instance);
2016 println!("{:?}", res);
2017 let res = kp.get(&instance);
2018 println!("{:?}", res);
2019
2020 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2021 println!("{:?}", new_kp_from_hashmap.get(&instance));
2022 }
2023
2024 #[test]
2060 fn test_enum_kp_result_ok() {
2061 let ok_result: Result<String, i32> = Ok("success".to_string());
2062 let mut err_result: Result<String, i32> = Err(42);
2063
2064 let ok_kp = enum_ok();
2065
2066 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2068 assert_eq!(ok_kp.get(&err_result), None);
2069
2070 let embedded = ok_kp.embed("embedded".to_string());
2072 assert_eq!(embedded, Ok("embedded".to_string()));
2073
2074 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2076 *val = "modified".to_string();
2077 }
2078 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2081 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2082 *val = "modified".to_string();
2083 }
2084 assert_eq!(ok_result2, Ok("modified".to_string()));
2085 }
2086
2087 #[test]
2088 fn test_enum_kp_result_err() {
2089 let ok_result: Result<String, i32> = Ok("success".to_string());
2090 let mut err_result: Result<String, i32> = Err(42);
2091
2092 let err_kp = enum_err();
2093
2094 assert_eq!(err_kp.get(&err_result), Some(&42));
2096 assert_eq!(err_kp.get(&ok_result), None);
2097
2098 let embedded = err_kp.embed(99);
2100 assert_eq!(embedded, Err(99));
2101
2102 if let Some(val) = err_kp.get_mut(&mut err_result) {
2104 *val = 100;
2105 }
2106 assert_eq!(err_result, Err(100));
2107 }
2108
2109 #[test]
2110 fn test_enum_kp_option_some() {
2111 let some_opt = Some("value".to_string());
2112 let mut none_opt: Option<String> = None;
2113
2114 let some_kp = enum_some();
2115
2116 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2118 assert_eq!(some_kp.get(&none_opt), None);
2119
2120 let embedded = some_kp.embed("embedded".to_string());
2122 assert_eq!(embedded, Some("embedded".to_string()));
2123
2124 let mut some_opt2 = Some("original".to_string());
2126 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2127 *val = "modified".to_string();
2128 }
2129 assert_eq!(some_opt2, Some("modified".to_string()));
2130 }
2131
2132 #[test]
2133 fn test_enum_kp_custom_enum() {
2134 #[derive(Debug, PartialEq)]
2135 enum MyEnum {
2136 A(String),
2137 B(i32),
2138 C,
2139 }
2140
2141 let mut enum_a = MyEnum::A("hello".to_string());
2142 let enum_b = MyEnum::B(42);
2143 let enum_c = MyEnum::C;
2144
2145 let kp_a = enum_variant(
2147 |e: &MyEnum| match e {
2148 MyEnum::A(s) => Some(s),
2149 _ => None,
2150 },
2151 |e: &mut MyEnum| match e {
2152 MyEnum::A(s) => Some(s),
2153 _ => None,
2154 },
2155 |s: String| MyEnum::A(s),
2156 );
2157
2158 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2160 assert_eq!(kp_a.get(&enum_b), None);
2161 assert_eq!(kp_a.get(&enum_c), None);
2162
2163 let embedded = kp_a.embed("world".to_string());
2165 assert_eq!(embedded, MyEnum::A("world".to_string()));
2166
2167 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2169 *val = "modified".to_string();
2170 }
2171 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2172 }
2173
2174 #[test]
2175 fn test_container_kp_box() {
2176 let boxed = Box::new("value".to_string());
2177 let mut boxed_mut = Box::new("original".to_string());
2178
2179 let box_kp = kp_box();
2180
2181 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2183
2184 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2186 *val = "modified".to_string();
2187 }
2188 assert_eq!(*boxed_mut, "modified".to_string());
2189 }
2190
2191 #[test]
2192 fn test_container_kp_arc() {
2193 let arc = Arc::new("value".to_string());
2194 let mut arc_mut = Arc::new("original".to_string());
2195
2196 let arc_kp = kp_arc();
2197
2198 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2200
2201 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2203 *val = "modified".to_string();
2204 }
2205 assert_eq!(*arc_mut, "modified".to_string());
2206
2207 let arc_shared = Arc::new("shared".to_string());
2209 let arc_shared2 = Arc::clone(&arc_shared);
2210 let mut arc_shared_mut = arc_shared;
2211 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2212 }
2213
2214 #[test]
2215 fn test_enum_kp_composition() {
2216 #[derive(Debug, PartialEq)]
2218 struct Inner {
2219 value: String,
2220 }
2221
2222 let result: Result<Inner, i32> = Ok(Inner {
2223 value: "nested".to_string(),
2224 });
2225
2226 let inner_kp = KpType::new(
2228 |i: &Inner| Some(&i.value),
2229 |i: &mut Inner| Some(&mut i.value),
2230 );
2231
2232 let ok_kp = enum_ok::<Inner, i32>();
2234 let ok_kp_base = ok_kp.into_kp();
2235 let composed = ok_kp_base.then(inner_kp);
2236
2237 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2238 }
2239
2240 #[test]
2241 fn test_pkp_basic() {
2242 #[derive(Debug)]
2243 struct User {
2244 name: String,
2245 age: i32,
2246 }
2247
2248 let user = User {
2249 name: "Alice".to_string(),
2250 age: 30,
2251 };
2252
2253 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2255 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2256
2257 let name_pkp = PKp::new(name_kp);
2259 let age_pkp = PKp::new(age_kp);
2260
2261 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2263 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2264
2265 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2267 assert_eq!(age_pkp.get_as::<String>(&user), None);
2268
2269 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2271 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2272 }
2273
2274 #[test]
2275 fn test_pkp_collection() {
2276 #[derive(Debug)]
2277 struct User {
2278 name: String,
2279 age: i32,
2280 }
2281
2282 let user = User {
2283 name: "Bob".to_string(),
2284 age: 25,
2285 };
2286
2287 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2289 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2290
2291 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2292
2293 let name_value = keypaths[0].get_as::<String>(&user);
2295 let age_value = keypaths[1].get_as::<i32>(&user);
2296
2297 assert_eq!(name_value, Some(&"Bob".to_string()));
2298 assert_eq!(age_value, Some(&25));
2299 }
2300
2301 #[test]
2302 fn test_pkp_for_arc() {
2303 #[derive(Debug)]
2304 struct User {
2305 name: String,
2306 }
2307
2308 let user = Arc::new(User {
2309 name: "Charlie".to_string(),
2310 });
2311
2312 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2313 let name_pkp = PKp::new(name_kp);
2314
2315 let arc_pkp = name_pkp.for_arc();
2317
2318 assert_eq!(
2319 arc_pkp.get_as::<String>(&user),
2320 Some(&"Charlie".to_string())
2321 );
2322 }
2323
2324 #[test]
2325 fn test_pkp_for_option() {
2326 #[derive(Debug)]
2327 struct User {
2328 name: String,
2329 }
2330
2331 let some_user = Some(User {
2332 name: "Diana".to_string(),
2333 });
2334 let none_user: Option<User> = None;
2335
2336 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2337 let name_pkp = PKp::new(name_kp);
2338
2339 let opt_pkp = name_pkp.for_option();
2341
2342 assert_eq!(
2343 opt_pkp.get_as::<String>(&some_user),
2344 Some(&"Diana".to_string())
2345 );
2346 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2347 }
2348
2349 #[test]
2350 fn test_akp_basic() {
2351 #[derive(Debug)]
2352 struct User {
2353 name: String,
2354 age: i32,
2355 }
2356
2357 #[derive(Debug)]
2358 struct Product {
2359 title: String,
2360 price: f64,
2361 }
2362
2363 let user = User {
2364 name: "Eve".to_string(),
2365 age: 28,
2366 };
2367
2368 let product = Product {
2369 title: "Book".to_string(),
2370 price: 19.99,
2371 };
2372
2373 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2375 let user_name_akp = AKp::new(user_name_kp);
2376
2377 let product_title_kp = KpType::new(
2378 |p: &Product| Some(&p.title),
2379 |p: &mut Product| Some(&mut p.title),
2380 );
2381 let product_title_akp = AKp::new(product_title_kp);
2382
2383 assert_eq!(
2385 user_name_akp.get_as::<User, String>(&user),
2386 Some(Some(&"Eve".to_string()))
2387 );
2388 assert_eq!(
2389 product_title_akp.get_as::<Product, String>(&product),
2390 Some(Some(&"Book".to_string()))
2391 );
2392
2393 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2395 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2396
2397 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2399 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2400 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2401 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2402 }
2403
2404 #[test]
2405 fn test_akp_heterogeneous_collection() {
2406 #[derive(Debug)]
2407 struct User {
2408 name: String,
2409 }
2410
2411 #[derive(Debug)]
2412 struct Product {
2413 title: String,
2414 }
2415
2416 let user = User {
2417 name: "Frank".to_string(),
2418 };
2419 let product = Product {
2420 title: "Laptop".to_string(),
2421 };
2422
2423 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2425 let product_title_kp = KpType::new(
2426 |p: &Product| Some(&p.title),
2427 |p: &mut Product| Some(&mut p.title),
2428 );
2429
2430 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2431
2432 let user_any: &dyn Any = &user;
2434 let product_any: &dyn Any = &product;
2435
2436 let user_value = keypaths[0].get(user_any);
2437 let product_value = keypaths[1].get(product_any);
2438
2439 assert!(user_value.is_some());
2440 assert!(product_value.is_some());
2441
2442 assert_eq!(
2444 user_value.and_then(|v| v.downcast_ref::<String>()),
2445 Some(&"Frank".to_string())
2446 );
2447 assert_eq!(
2448 product_value.and_then(|v| v.downcast_ref::<String>()),
2449 Some(&"Laptop".to_string())
2450 );
2451 }
2452
2453 #[test]
2454 fn test_akp_for_option() {
2455 #[derive(Debug)]
2456 struct User {
2457 name: String,
2458 }
2459
2460 let some_user = Some(User {
2461 name: "Grace".to_string(),
2462 });
2463 let none_user: Option<User> = None;
2464
2465 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2466 let name_akp = AKp::new(name_kp);
2467
2468 let opt_akp = name_akp.for_option::<User>();
2470
2471 assert_eq!(
2472 opt_akp.get_as::<Option<User>, String>(&some_user),
2473 Some(Some(&"Grace".to_string()))
2474 );
2475 assert_eq!(
2476 opt_akp.get_as::<Option<User>, String>(&none_user),
2477 Some(None)
2478 );
2479 }
2480
2481 #[test]
2482 fn test_akp_for_result() {
2483 #[derive(Debug)]
2484 struct User {
2485 name: String,
2486 }
2487
2488 let ok_user: Result<User, String> = Ok(User {
2489 name: "Henry".to_string(),
2490 });
2491 let err_user: Result<User, String> = Err("Not found".to_string());
2492
2493 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2494 let name_akp = AKp::new(name_kp);
2495
2496 let result_akp = name_akp.for_result::<User, String>();
2498
2499 assert_eq!(
2500 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2501 Some(Some(&"Henry".to_string()))
2502 );
2503 assert_eq!(
2504 result_akp.get_as::<Result<User, String>, String>(&err_user),
2505 Some(None)
2506 );
2507 }
2508
2509 #[test]
2512 fn test_kp_map() {
2513 #[derive(Debug)]
2514 struct User {
2515 name: String,
2516 age: i32,
2517 }
2518
2519 let user = User {
2520 name: "Alice".to_string(),
2521 age: 30,
2522 };
2523
2524 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2526 let len_kp = name_kp.map(|name: &String| name.len());
2527
2528 assert_eq!(len_kp.get(&user), Some(5));
2529
2530 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2532 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2533
2534 assert_eq!(double_age_kp.get(&user), Some(60));
2535
2536 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2538 assert_eq!(is_adult_kp.get(&user), Some(true));
2539 }
2540
2541 #[test]
2542 fn test_kp_filter() {
2543 #[derive(Debug)]
2544 struct User {
2545 name: String,
2546 age: i32,
2547 }
2548
2549 let adult = User {
2550 name: "Alice".to_string(),
2551 age: 30,
2552 };
2553
2554 let minor = User {
2555 name: "Bob".to_string(),
2556 age: 15,
2557 };
2558
2559 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2560 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2561
2562 assert_eq!(adult_age_kp.get(&adult), Some(&30));
2563 assert_eq!(adult_age_kp.get(&minor), None);
2564
2565 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2567 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2568
2569 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2570 assert_eq!(short_name_kp.get(&adult), None);
2571 }
2572
2573 #[test]
2574 fn test_kp_map_and_filter() {
2575 #[derive(Debug)]
2576 struct User {
2577 scores: Vec<i32>,
2578 }
2579
2580 let user = User {
2581 scores: vec![85, 92, 78, 95],
2582 };
2583
2584 let scores_kp = KpType::new(
2585 |u: &User| Some(&u.scores),
2586 |u: &mut User| Some(&mut u.scores),
2587 );
2588
2589 let avg_kp =
2591 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2592
2593 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2595
2596 assert_eq!(high_avg_kp.get(&user), Some(87)); }
2598
2599 #[test]
2600 fn test_enum_kp_map() {
2601 let ok_result: Result<String, i32> = Ok("hello".to_string());
2602 let err_result: Result<String, i32> = Err(42);
2603
2604 let ok_kp = enum_ok::<String, i32>();
2605 let len_kp = ok_kp.map(|s: &String| s.len());
2606
2607 assert_eq!(len_kp.get(&ok_result), Some(5));
2608 assert_eq!(len_kp.get(&err_result), None);
2609
2610 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2612 let none_opt: Option<Vec<i32>> = None;
2613
2614 let some_kp = enum_some::<Vec<i32>>();
2615 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2616
2617 assert_eq!(count_kp.get(&some_opt), Some(5));
2618 assert_eq!(count_kp.get(&none_opt), None);
2619 }
2620
2621 #[test]
2622 fn test_enum_kp_filter() {
2623 let ok_result1: Result<i32, String> = Ok(42);
2624 let ok_result2: Result<i32, String> = Ok(-5);
2625 let err_result: Result<i32, String> = Err("error".to_string());
2626
2627 let ok_kp = enum_ok::<i32, String>();
2628 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2629
2630 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2631 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2636 let short_str = Some("hi".to_string());
2637
2638 let some_kp = enum_some::<String>();
2639 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2640
2641 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2642 assert_eq!(long_kp.get(&short_str), None);
2643 }
2644
2645 #[test]
2646 fn test_pkp_filter() {
2647 #[derive(Debug)]
2648 struct User {
2649 name: String,
2650 age: i32,
2651 }
2652
2653 let adult = User {
2654 name: "Alice".to_string(),
2655 age: 30,
2656 };
2657
2658 let minor = User {
2659 name: "Bob".to_string(),
2660 age: 15,
2661 };
2662
2663 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2664 let age_pkp = PKp::new(age_kp);
2665
2666 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2668
2669 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2670 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2671
2672 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2674 let name_pkp = PKp::new(name_kp);
2675 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2676
2677 assert_eq!(
2678 short_name_pkp.get_as::<String>(&minor),
2679 Some(&"Bob".to_string())
2680 );
2681 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2682 }
2683
2684 #[test]
2685 fn test_akp_filter() {
2686 #[derive(Debug)]
2687 struct User {
2688 age: i32,
2689 }
2690
2691 #[derive(Debug)]
2692 struct Product {
2693 price: f64,
2694 }
2695
2696 let adult = User { age: 30 };
2697 let minor = User { age: 15 };
2698 let expensive = Product { price: 99.99 };
2699 let cheap = Product { price: 5.0 };
2700
2701 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2703 let age_akp = AKp::new(age_kp);
2704 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2705
2706 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2707 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2708
2709 let price_kp = KpType::new(
2711 |p: &Product| Some(&p.price),
2712 |p: &mut Product| Some(&mut p.price),
2713 );
2714 let price_akp = AKp::new(price_kp);
2715 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2716
2717 assert_eq!(
2718 expensive_akp.get_as::<Product, f64>(&expensive),
2719 Some(Some(&99.99))
2720 );
2721 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2722 }
2723
2724 #[test]
2727 fn test_kp_filter_map() {
2728 #[derive(Debug)]
2729 struct User {
2730 middle_name: Option<String>,
2731 }
2732
2733 let user_with = User {
2734 middle_name: Some("Marie".to_string()),
2735 };
2736 let user_without = User { middle_name: None };
2737
2738 let middle_kp = KpType::new(
2739 |u: &User| Some(&u.middle_name),
2740 |u: &mut User| Some(&mut u.middle_name),
2741 );
2742
2743 let first_char_kp = middle_kp
2744 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
2745
2746 assert_eq!(first_char_kp.get(&user_with), Some('M'));
2747 assert_eq!(first_char_kp.get(&user_without), None);
2748 }
2749
2750 #[test]
2751 fn test_kp_inspect() {
2752 #[derive(Debug)]
2753 struct User {
2754 name: String,
2755 }
2756
2757 let user = User {
2758 name: "Alice".to_string(),
2759 };
2760
2761 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2765
2766 let result = name_kp.get(&user);
2769 assert_eq!(result, Some(&"Alice".to_string()));
2770
2771 }
2774
2775 #[test]
2776 fn test_kp_fold_value() {
2777 #[derive(Debug)]
2778 struct User {
2779 scores: Vec<i32>,
2780 }
2781
2782 let user = User {
2783 scores: vec![85, 92, 78, 95],
2784 };
2785
2786 let scores_kp = KpType::new(
2787 |u: &User| Some(&u.scores),
2788 |u: &mut User| Some(&mut u.scores),
2789 );
2790
2791 let sum_fn =
2793 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
2794
2795 assert_eq!(sum_fn(&user), 350);
2796 }
2797
2798 #[test]
2799 fn test_kp_any_all() {
2800 #[derive(Debug)]
2801 struct User {
2802 scores: Vec<i32>,
2803 }
2804
2805 let user_high = User {
2806 scores: vec![85, 92, 88],
2807 };
2808 let user_mixed = User {
2809 scores: vec![65, 92, 78],
2810 };
2811
2812 let scores_kp = KpType::new(
2813 |u: &User| Some(&u.scores),
2814 |u: &mut User| Some(&mut u.scores),
2815 );
2816
2817 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
2819 assert!(has_high_fn(&user_high));
2820 assert!(has_high_fn(&user_mixed));
2821
2822 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
2824 assert!(all_passing_fn(&user_high));
2825 assert!(!all_passing_fn(&user_mixed));
2826 }
2827
2828 #[test]
2829 fn test_kp_count_items() {
2830 #[derive(Debug)]
2831 struct User {
2832 tags: Vec<String>,
2833 }
2834
2835 let user = User {
2836 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
2837 };
2838
2839 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2840 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
2841
2842 assert_eq!(count_fn(&user), Some(3));
2843 }
2844
2845 #[test]
2846 fn test_kp_find_in() {
2847 #[derive(Debug)]
2848 struct User {
2849 scores: Vec<i32>,
2850 }
2851
2852 let user = User {
2853 scores: vec![85, 92, 78, 95, 88],
2854 };
2855
2856 let scores_kp = KpType::new(
2857 |u: &User| Some(&u.scores),
2858 |u: &mut User| Some(&mut u.scores),
2859 );
2860
2861 let first_high_fn =
2863 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
2864
2865 assert_eq!(first_high_fn(&user), Some(92));
2866
2867 let perfect_fn =
2869 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
2870
2871 assert_eq!(perfect_fn(&user), None);
2872 }
2873
2874 #[test]
2875 fn test_kp_take_skip() {
2876 #[derive(Debug)]
2877 struct User {
2878 tags: Vec<String>,
2879 }
2880
2881 let user = User {
2882 tags: vec![
2883 "a".to_string(),
2884 "b".to_string(),
2885 "c".to_string(),
2886 "d".to_string(),
2887 ],
2888 };
2889
2890 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2891
2892 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
2894 tags.iter().take(n).cloned().collect::<Vec<_>>()
2895 });
2896
2897 let taken = take_fn(&user).unwrap();
2898 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
2899
2900 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
2902 tags.iter().skip(n).cloned().collect::<Vec<_>>()
2903 });
2904
2905 let skipped = skip_fn(&user).unwrap();
2906 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
2907 }
2908
2909 #[test]
2910 fn test_kp_partition() {
2911 #[derive(Debug)]
2912 struct User {
2913 scores: Vec<i32>,
2914 }
2915
2916 let user = User {
2917 scores: vec![85, 92, 65, 95, 72, 58],
2918 };
2919
2920 let scores_kp = KpType::new(
2921 |u: &User| Some(&u.scores),
2922 |u: &mut User| Some(&mut u.scores),
2923 );
2924
2925 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
2926 scores.iter().copied().partition(|&s| s >= 70)
2927 });
2928
2929 let (passing, failing) = partition_fn(&user).unwrap();
2930 assert_eq!(passing, vec![85, 92, 95, 72]);
2931 assert_eq!(failing, vec![65, 58]);
2932 }
2933
2934 #[test]
2935 fn test_kp_min_max() {
2936 #[derive(Debug)]
2937 struct User {
2938 scores: Vec<i32>,
2939 }
2940
2941 let user = User {
2942 scores: vec![85, 92, 78, 95, 88],
2943 };
2944
2945 let scores_kp = KpType::new(
2946 |u: &User| Some(&u.scores),
2947 |u: &mut User| Some(&mut u.scores),
2948 );
2949
2950 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
2952 assert_eq!(min_fn(&user), Some(78));
2953
2954 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
2956 assert_eq!(max_fn(&user), Some(95));
2957 }
2958
2959 #[test]
2960 fn test_kp_sum() {
2961 #[derive(Debug)]
2962 struct User {
2963 scores: Vec<i32>,
2964 }
2965
2966 let user = User {
2967 scores: vec![85, 92, 78],
2968 };
2969
2970 let scores_kp = KpType::new(
2971 |u: &User| Some(&u.scores),
2972 |u: &mut User| Some(&mut u.scores),
2973 );
2974
2975 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
2976 assert_eq!(sum_fn(&user), Some(255));
2977
2978 let avg_fn =
2980 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2981 assert_eq!(avg_fn.get(&user), Some(85));
2982 }
2983
2984 #[test]
2985 fn test_kp_chain() {
2986 #[derive(Debug)]
2987 struct User {
2988 profile: Profile,
2989 }
2990
2991 #[derive(Debug)]
2992 struct Profile {
2993 settings: Settings,
2994 }
2995
2996 #[derive(Debug)]
2997 struct Settings {
2998 theme: String,
2999 }
3000
3001 let user = User {
3002 profile: Profile {
3003 settings: Settings {
3004 theme: "dark".to_string(),
3005 },
3006 },
3007 };
3008
3009 let profile_kp = KpType::new(
3010 |u: &User| Some(&u.profile),
3011 |u: &mut User| Some(&mut u.profile),
3012 );
3013 let settings_kp = KpType::new(
3014 |p: &Profile| Some(&p.settings),
3015 |p: &mut Profile| Some(&mut p.settings),
3016 );
3017 let theme_kp = KpType::new(
3018 |s: &Settings| Some(&s.theme),
3019 |s: &mut Settings| Some(&mut s.theme),
3020 );
3021
3022 let profile_settings = profile_kp.chain(settings_kp);
3024 let theme_path = profile_settings.chain(theme_kp);
3025 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3026 }
3027
3028 #[test]
3029 fn test_kp_zip() {
3030 #[derive(Debug)]
3031 struct User {
3032 name: String,
3033 age: i32,
3034 }
3035
3036 let user = User {
3037 name: "Alice".to_string(),
3038 age: 30,
3039 };
3040
3041 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3042 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3043
3044 let zipped_fn = zip_kps(&name_kp, &age_kp);
3045 let result = zipped_fn(&user);
3046
3047 assert_eq!(result, Some((&"Alice".to_string(), &30)));
3048 }
3049
3050 #[test]
3051 fn test_kp_complex_pipeline() {
3052 #[derive(Debug)]
3053 struct User {
3054 transactions: Vec<Transaction>,
3055 }
3056
3057 #[derive(Debug)]
3058 struct Transaction {
3059 amount: f64,
3060 category: String,
3061 }
3062
3063 let user = User {
3064 transactions: vec![
3065 Transaction {
3066 amount: 50.0,
3067 category: "food".to_string(),
3068 },
3069 Transaction {
3070 amount: 100.0,
3071 category: "transport".to_string(),
3072 },
3073 Transaction {
3074 amount: 25.0,
3075 category: "food".to_string(),
3076 },
3077 Transaction {
3078 amount: 200.0,
3079 category: "shopping".to_string(),
3080 },
3081 ],
3082 };
3083
3084 let txns_kp = KpType::new(
3085 |u: &User| Some(&u.transactions),
3086 |u: &mut User| Some(&mut u.transactions),
3087 );
3088
3089 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3091 txns.iter()
3092 .filter(|t| t.category == "food")
3093 .map(|t| t.amount)
3094 .sum::<f64>()
3095 });
3096
3097 assert_eq!(food_total.get(&user), Some(75.0));
3098
3099 let has_large =
3101 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3102
3103 assert!(has_large(&user));
3104
3105 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3107 assert_eq!(count(&user), Some(4));
3108 }
3109
3110 #[test]
3114 fn test_no_clone_required_for_root() {
3115 use std::sync::Arc;
3116 use std::sync::atomic::{AtomicUsize, Ordering};
3117
3118 struct NonCloneableRoot {
3121 data: Arc<AtomicUsize>,
3122 cached_value: usize,
3123 }
3124
3125 impl NonCloneableRoot {
3126 fn new() -> Self {
3127 Self {
3128 data: Arc::new(AtomicUsize::new(42)),
3129 cached_value: 42,
3130 }
3131 }
3132
3133 fn increment(&mut self) {
3134 self.data.fetch_add(1, Ordering::SeqCst);
3135 self.cached_value = self.data.load(Ordering::SeqCst);
3136 }
3137
3138 fn get_value(&self) -> &usize {
3139 &self.cached_value
3140 }
3141
3142 fn get_value_mut(&mut self) -> &mut usize {
3143 &mut self.cached_value
3144 }
3145 }
3146
3147 let mut root = NonCloneableRoot::new();
3148
3149 let data_kp = KpType::new(
3151 |r: &NonCloneableRoot| Some(r.get_value()),
3152 |r: &mut NonCloneableRoot| {
3153 r.increment();
3154 Some(r.get_value_mut())
3155 },
3156 );
3157
3158 assert_eq!(data_kp.get(&root), Some(&42));
3160
3161 {
3162 let doubled = data_kp.map(|val: &usize| val * 2);
3164 assert_eq!(doubled.get(&root), Some(84));
3165
3166 let filtered = data_kp.filter(|val: &usize| *val > 0);
3168 assert_eq!(filtered.get(&root), Some(&42));
3169 } let value_ref = data_kp.get_mut(&mut root);
3173 assert!(value_ref.is_some());
3174 }
3175
3176 #[test]
3177 fn test_no_clone_required_for_value() {
3178 use std::sync::Arc;
3179 use std::sync::atomic::{AtomicUsize, Ordering};
3180
3181 struct NonCloneableValue {
3183 counter: Arc<AtomicUsize>,
3184 }
3185
3186 impl NonCloneableValue {
3187 fn new(val: usize) -> Self {
3188 Self {
3189 counter: Arc::new(AtomicUsize::new(val)),
3190 }
3191 }
3192
3193 fn get(&self) -> usize {
3194 self.counter.load(Ordering::SeqCst)
3195 }
3196 }
3197
3198 struct Root {
3199 value: NonCloneableValue,
3200 }
3201
3202 let root = Root {
3203 value: NonCloneableValue::new(100),
3204 };
3205
3206 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3208
3209 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3211 assert_eq!(counter_kp.get(&root), Some(100));
3212
3213 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3215 assert!(filtered.get(&root).is_some());
3216 }
3217
3218 #[test]
3219 fn test_static_does_not_leak_memory() {
3220 use std::sync::Arc;
3221 use std::sync::atomic::{AtomicUsize, Ordering};
3222
3223 static CREATED: AtomicUsize = AtomicUsize::new(0);
3225 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3226
3227 struct Tracked {
3228 id: usize,
3229 }
3230
3231 impl Tracked {
3232 fn new() -> Self {
3233 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3234 Self { id }
3235 }
3236 }
3237
3238 impl Drop for Tracked {
3239 fn drop(&mut self) {
3240 DROPPED.fetch_add(1, Ordering::SeqCst);
3241 }
3242 }
3243
3244 struct Root {
3245 data: Tracked,
3246 }
3247
3248 CREATED.store(0, Ordering::SeqCst);
3250 DROPPED.store(0, Ordering::SeqCst);
3251
3252 {
3253 let root = Root {
3254 data: Tracked::new(),
3255 };
3256
3257 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3258
3259 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3261 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3262 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3263
3264 assert_eq!(mapped1.get(&root), Some(0));
3265 assert_eq!(mapped2.get(&root), Some(1));
3266 assert_eq!(mapped3.get(&root), Some(2));
3267
3268 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3270 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3271 }
3272
3273 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3275 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3276
3277 }
3279
3280 #[test]
3281 fn test_references_not_cloned() {
3282 use std::sync::Arc;
3283
3284 struct ExpensiveData {
3286 large_vec: Vec<u8>,
3287 }
3288
3289 impl ExpensiveData {
3290 fn new(size: usize) -> Self {
3291 Self {
3292 large_vec: vec![0u8; size],
3293 }
3294 }
3295
3296 fn size(&self) -> usize {
3297 self.large_vec.len()
3298 }
3299 }
3300
3301 struct Root {
3302 expensive: ExpensiveData,
3303 }
3304
3305 let root = Root {
3306 expensive: ExpensiveData::new(1_000_000), };
3308
3309 let expensive_kp = KpType::new(
3310 |r: &Root| Some(&r.expensive),
3311 |r: &mut Root| Some(&mut r.expensive),
3312 );
3313
3314 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3316 assert_eq!(size_kp.get(&root), Some(1_000_000));
3317
3318 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3320 assert!(large_filter.get(&root).is_some());
3321
3322 }
3324
3325 #[test]
3326 fn test_hof_with_arc_no_extra_clones() {
3327 use std::sync::Arc;
3328
3329 #[derive(Debug)]
3330 struct SharedData {
3331 value: String,
3332 }
3333
3334 struct Root {
3335 shared: Arc<SharedData>,
3336 }
3337
3338 let shared = Arc::new(SharedData {
3339 value: "shared".to_string(),
3340 });
3341
3342 assert_eq!(Arc::strong_count(&shared), 1);
3344
3345 {
3346 let root = Root {
3347 shared: Arc::clone(&shared),
3348 };
3349
3350 assert_eq!(Arc::strong_count(&shared), 2);
3352
3353 let shared_kp = KpType::new(
3354 |r: &Root| Some(&r.shared),
3355 |r: &mut Root| Some(&mut r.shared),
3356 );
3357
3358 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3360
3361 assert_eq!(value_kp.get(&root), Some(6));
3363 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3367 assert!(filtered.get(&root).is_some());
3368 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3373
3374 #[test]
3375 fn test_closure_captures_not_root_values() {
3376 use std::sync::Arc;
3377 use std::sync::atomic::{AtomicUsize, Ordering};
3378
3379 let call_count = Arc::new(AtomicUsize::new(0));
3381 let call_count_clone = Arc::clone(&call_count);
3382
3383 struct Root {
3384 value: i32,
3385 }
3386
3387 let root = Root { value: 42 };
3388
3389 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3390
3391 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3394 call_count_clone.fetch_add(1, Ordering::SeqCst);
3395 v * 2
3396 });
3397
3398 assert_eq!(doubled(&root), 84);
3400 assert_eq!(doubled(&root), 84);
3401 assert_eq!(doubled(&root), 84);
3402
3403 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3405
3406 }
3408
3409 #[test]
3410 fn test_static_with_borrowed_data() {
3411 struct Root {
3415 data: String,
3416 }
3417
3418 {
3419 let root = Root {
3420 data: "temporary".to_string(),
3421 };
3422
3423 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3424
3425 let len_kp = data_kp.map(|s: &String| s.len());
3427 assert_eq!(len_kp.get(&root), Some(9));
3428
3429 } }
3434
3435 #[test]
3436 fn test_multiple_hof_operations_no_accumulation() {
3437 use std::sync::Arc;
3438 use std::sync::atomic::{AtomicUsize, Ordering};
3439
3440 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3441
3442 struct Tracked {
3443 id: usize,
3444 }
3445
3446 impl Drop for Tracked {
3447 fn drop(&mut self) {
3448 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3449 }
3450 }
3451
3452 struct Root {
3453 values: Vec<Tracked>,
3454 }
3455
3456 DROP_COUNT.store(0, Ordering::SeqCst);
3457
3458 {
3459 let root = Root {
3460 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3461 };
3462
3463 let values_kp = KpType::new(
3464 |r: &Root| Some(&r.values),
3465 |r: &mut Root| Some(&mut r.values),
3466 );
3467
3468 let count = values_kp.count_items(|v| v.len());
3470 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3471 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3472 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3473
3474 assert_eq!(count(&root), Some(3));
3475 assert_eq!(sum(&root), Some(6));
3476 assert!(has_2(&root));
3477 assert!(all_positive(&root));
3478
3479 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3481 }
3482
3483 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3485 }
3486
3487 #[test]
3488 fn test_copy_bound_only_for_function_not_data() {
3489 #[derive(Debug)]
3493 struct NonCopyData {
3494 value: String,
3495 }
3496
3497 struct Root {
3498 data: NonCopyData,
3499 }
3500
3501 let root = Root {
3502 data: NonCopyData {
3503 value: "test".to_string(),
3504 },
3505 };
3506
3507 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3508
3509 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3512 assert_eq!(len_kp.get(&root), Some(4));
3513
3514 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3516 assert!(filtered.get(&root).is_some());
3517 }
3518
3519 #[test]
3520 fn test_no_memory_leak_with_cyclic_references() {
3521 use std::sync::atomic::{AtomicUsize, Ordering};
3522 use std::sync::{Arc, Weak};
3523
3524 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3525
3526 struct Node {
3527 id: usize,
3528 parent: Option<Weak<Node>>,
3529 }
3530
3531 impl Drop for Node {
3532 fn drop(&mut self) {
3533 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3534 }
3535 }
3536
3537 struct Root {
3538 node: Arc<Node>,
3539 }
3540
3541 DROP_COUNT.store(0, Ordering::SeqCst);
3542
3543 {
3544 let root = Root {
3545 node: Arc::new(Node {
3546 id: 1,
3547 parent: None,
3548 }),
3549 };
3550
3551 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3552
3553 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3555 assert_eq!(id_kp.get(&root), Some(1));
3556
3557 assert_eq!(Arc::strong_count(&root.node), 1);
3559
3560 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3562 }
3563
3564 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3566 }
3567
3568 #[test]
3569 fn test_hof_operations_are_zero_cost_abstractions() {
3570 struct Root {
3574 value: i32,
3575 }
3576
3577 let root = Root { value: 10 };
3578
3579 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3580
3581 let direct_result = value_kp.get(&root).map(|v| v * 2);
3583 assert_eq!(direct_result, Some(20));
3584
3585 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3587 let hof_result = mapped_kp.get(&root);
3588 assert_eq!(hof_result, Some(20));
3589
3590 assert_eq!(direct_result, hof_result);
3592 }
3593
3594 #[test]
3595 fn test_complex_closure_captures_allowed() {
3596 use std::sync::Arc;
3597
3598 struct Root {
3600 scores: Vec<i32>,
3601 }
3602
3603 let root = Root {
3604 scores: vec![85, 92, 78, 95, 88],
3605 };
3606
3607 let scores_kp = KpType::new(
3608 |r: &Root| Some(&r.scores),
3609 |r: &mut Root| Some(&mut r.scores),
3610 );
3611
3612 let threshold = 90;
3614 let multiplier = Arc::new(2);
3615
3616 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3618 let high: i32 = scores
3619 .iter()
3620 .filter(|&&s| s >= threshold)
3621 .map(|&s| s * *multiplier)
3622 .sum();
3623 acc + high
3624 });
3625
3626 assert_eq!(high_scores_doubled(&root), 374);
3628 }
3629
3630 #[test]
3634 fn test_pkp_filter_by_value_type() {
3635 use std::any::TypeId;
3636
3637 #[derive(Debug)]
3638 struct User {
3639 name: String,
3640 age: i32,
3641 score: f64,
3642 active: bool,
3643 }
3644
3645 let user = User {
3646 name: "Alice".to_string(),
3647 age: 30,
3648 score: 95.5,
3649 active: true,
3650 };
3651
3652 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3654 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3655 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3656 let active_kp = KpType::new(
3657 |u: &User| Some(&u.active),
3658 |u: &mut User| Some(&mut u.active),
3659 );
3660
3661 let all_keypaths: Vec<PKp<User>> = vec![
3663 PKp::new(name_kp),
3664 PKp::new(age_kp),
3665 PKp::new(score_kp),
3666 PKp::new(active_kp),
3667 ];
3668
3669 let string_kps: Vec<_> = all_keypaths
3671 .iter()
3672 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3673 .collect();
3674
3675 assert_eq!(string_kps.len(), 1);
3676 assert_eq!(
3677 string_kps[0].get_as::<String>(&user),
3678 Some(&"Alice".to_string())
3679 );
3680
3681 let i32_kps: Vec<_> = all_keypaths
3683 .iter()
3684 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3685 .collect();
3686
3687 assert_eq!(i32_kps.len(), 1);
3688 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3689
3690 let f64_kps: Vec<_> = all_keypaths
3692 .iter()
3693 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3694 .collect();
3695
3696 assert_eq!(f64_kps.len(), 1);
3697 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3698
3699 let bool_kps: Vec<_> = all_keypaths
3701 .iter()
3702 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3703 .collect();
3704
3705 assert_eq!(bool_kps.len(), 1);
3706 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3707 }
3708
3709 #[test]
3710 fn test_pkp_filter_by_struct_type() {
3711 use std::any::TypeId;
3712
3713 #[derive(Debug, PartialEq)]
3714 struct Address {
3715 street: String,
3716 city: String,
3717 }
3718
3719 #[derive(Debug)]
3720 struct User {
3721 name: String,
3722 age: i32,
3723 address: Address,
3724 }
3725
3726 let user = User {
3727 name: "Bob".to_string(),
3728 age: 25,
3729 address: Address {
3730 street: "123 Main St".to_string(),
3731 city: "NYC".to_string(),
3732 },
3733 };
3734
3735 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3737 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3738 let address_kp = KpType::new(
3739 |u: &User| Some(&u.address),
3740 |u: &mut User| Some(&mut u.address),
3741 );
3742
3743 let all_keypaths: Vec<PKp<User>> =
3744 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
3745
3746 let struct_kps: Vec<_> = all_keypaths
3748 .iter()
3749 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
3750 .collect();
3751
3752 assert_eq!(struct_kps.len(), 1);
3753 assert_eq!(
3754 struct_kps[0].get_as::<Address>(&user),
3755 Some(&Address {
3756 street: "123 Main St".to_string(),
3757 city: "NYC".to_string(),
3758 })
3759 );
3760
3761 let primitive_kps: Vec<_> = all_keypaths
3763 .iter()
3764 .filter(|pkp| {
3765 pkp.value_type_id() == TypeId::of::<String>()
3766 || pkp.value_type_id() == TypeId::of::<i32>()
3767 })
3768 .collect();
3769
3770 assert_eq!(primitive_kps.len(), 2);
3771 }
3772
3773 #[test]
3774 fn test_pkp_filter_by_arc_type() {
3775 use std::any::TypeId;
3776 use std::sync::Arc;
3777
3778 #[derive(Debug)]
3779 struct User {
3780 name: String,
3781 shared_data: Arc<String>,
3782 shared_number: Arc<i32>,
3783 }
3784
3785 let user = User {
3786 name: "Charlie".to_string(),
3787 shared_data: Arc::new("shared".to_string()),
3788 shared_number: Arc::new(42),
3789 };
3790
3791 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3793 let shared_data_kp = KpType::new(
3794 |u: &User| Some(&u.shared_data),
3795 |u: &mut User| Some(&mut u.shared_data),
3796 );
3797 let shared_number_kp = KpType::new(
3798 |u: &User| Some(&u.shared_number),
3799 |u: &mut User| Some(&mut u.shared_number),
3800 );
3801
3802 let all_keypaths: Vec<PKp<User>> = vec![
3803 PKp::new(name_kp),
3804 PKp::new(shared_data_kp),
3805 PKp::new(shared_number_kp),
3806 ];
3807
3808 let arc_string_kps: Vec<_> = all_keypaths
3810 .iter()
3811 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
3812 .collect();
3813
3814 assert_eq!(arc_string_kps.len(), 1);
3815 assert_eq!(
3816 arc_string_kps[0]
3817 .get_as::<Arc<String>>(&user)
3818 .map(|arc| arc.as_str()),
3819 Some("shared")
3820 );
3821
3822 let arc_i32_kps: Vec<_> = all_keypaths
3824 .iter()
3825 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
3826 .collect();
3827
3828 assert_eq!(arc_i32_kps.len(), 1);
3829 assert_eq!(
3830 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
3831 Some(42)
3832 );
3833
3834 let all_arc_kps: Vec<_> = all_keypaths
3836 .iter()
3837 .filter(|pkp| {
3838 pkp.value_type_id() == TypeId::of::<Arc<String>>()
3839 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
3840 })
3841 .collect();
3842
3843 assert_eq!(all_arc_kps.len(), 2);
3844 }
3845
3846 #[test]
3847 fn test_pkp_filter_by_box_type() {
3848 use std::any::TypeId;
3849
3850 #[derive(Debug)]
3851 struct User {
3852 name: String,
3853 boxed_value: Box<i32>,
3854 boxed_string: Box<String>,
3855 }
3856
3857 let user = User {
3858 name: "Diana".to_string(),
3859 boxed_value: Box::new(100),
3860 boxed_string: Box::new("boxed".to_string()),
3861 };
3862
3863 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3865 let boxed_value_kp = KpType::new(
3866 |u: &User| Some(&u.boxed_value),
3867 |u: &mut User| Some(&mut u.boxed_value),
3868 );
3869 let boxed_string_kp = KpType::new(
3870 |u: &User| Some(&u.boxed_string),
3871 |u: &mut User| Some(&mut u.boxed_string),
3872 );
3873
3874 let all_keypaths: Vec<PKp<User>> = vec![
3875 PKp::new(name_kp),
3876 PKp::new(boxed_value_kp),
3877 PKp::new(boxed_string_kp),
3878 ];
3879
3880 let box_i32_kps: Vec<_> = all_keypaths
3882 .iter()
3883 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
3884 .collect();
3885
3886 assert_eq!(box_i32_kps.len(), 1);
3887 assert_eq!(
3888 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
3889 Some(100)
3890 );
3891
3892 let box_string_kps: Vec<_> = all_keypaths
3894 .iter()
3895 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
3896 .collect();
3897
3898 assert_eq!(box_string_kps.len(), 1);
3899 assert_eq!(
3900 box_string_kps[0]
3901 .get_as::<Box<String>>(&user)
3902 .map(|b| b.as_str()),
3903 Some("boxed")
3904 );
3905 }
3906
3907 #[test]
3908 fn test_akp_filter_by_root_and_value_type() {
3909 use std::any::TypeId;
3910
3911 #[derive(Debug)]
3912 struct User {
3913 name: String,
3914 age: i32,
3915 }
3916
3917 #[derive(Debug)]
3918 struct Product {
3919 title: String,
3920 price: f64,
3921 }
3922
3923 let user = User {
3924 name: "Eve".to_string(),
3925 age: 28,
3926 };
3927
3928 let product = Product {
3929 title: "Book".to_string(),
3930 price: 19.99,
3931 };
3932
3933 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3935 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3936 let product_title_kp = KpType::new(
3937 |p: &Product| Some(&p.title),
3938 |p: &mut Product| Some(&mut p.title),
3939 );
3940 let product_price_kp = KpType::new(
3941 |p: &Product| Some(&p.price),
3942 |p: &mut Product| Some(&mut p.price),
3943 );
3944
3945 let all_keypaths: Vec<AKp> = vec![
3946 AKp::new(user_name_kp),
3947 AKp::new(user_age_kp),
3948 AKp::new(product_title_kp),
3949 AKp::new(product_price_kp),
3950 ];
3951
3952 let user_kps: Vec<_> = all_keypaths
3954 .iter()
3955 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
3956 .collect();
3957
3958 assert_eq!(user_kps.len(), 2);
3959
3960 let product_kps: Vec<_> = all_keypaths
3962 .iter()
3963 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
3964 .collect();
3965
3966 assert_eq!(product_kps.len(), 2);
3967
3968 let string_value_kps: Vec<_> = all_keypaths
3970 .iter()
3971 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
3972 .collect();
3973
3974 assert_eq!(string_value_kps.len(), 2);
3975
3976 let user_string_kps: Vec<_> = all_keypaths
3978 .iter()
3979 .filter(|akp| {
3980 akp.root_type_id() == TypeId::of::<User>()
3981 && akp.value_type_id() == TypeId::of::<String>()
3982 })
3983 .collect();
3984
3985 assert_eq!(user_string_kps.len(), 1);
3986 assert_eq!(
3987 user_string_kps[0].get_as::<User, String>(&user),
3988 Some(Some(&"Eve".to_string()))
3989 );
3990
3991 let product_f64_kps: Vec<_> = all_keypaths
3993 .iter()
3994 .filter(|akp| {
3995 akp.root_type_id() == TypeId::of::<Product>()
3996 && akp.value_type_id() == TypeId::of::<f64>()
3997 })
3998 .collect();
3999
4000 assert_eq!(product_f64_kps.len(), 1);
4001 assert_eq!(
4002 product_f64_kps[0].get_as::<Product, f64>(&product),
4003 Some(Some(&19.99))
4004 );
4005 }
4006
4007 #[test]
4008 fn test_akp_filter_by_arc_root_type() {
4009 use std::any::TypeId;
4010 use std::sync::Arc;
4011
4012 #[derive(Debug)]
4013 struct User {
4014 name: String,
4015 }
4016
4017 #[derive(Debug)]
4018 struct Product {
4019 title: String,
4020 }
4021
4022 let user = User {
4023 name: "Frank".to_string(),
4024 };
4025 let product = Product {
4026 title: "Laptop".to_string(),
4027 };
4028
4029 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4031 let product_title_kp = KpType::new(
4032 |p: &Product| Some(&p.title),
4033 |p: &mut Product| Some(&mut p.title),
4034 );
4035
4036 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4038 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4039
4040 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4041
4042 let arc_user_kps: Vec<_> = all_keypaths
4044 .iter()
4045 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4046 .collect();
4047
4048 assert_eq!(arc_user_kps.len(), 1);
4049
4050 let arc_user = Arc::new(user);
4052 assert_eq!(
4053 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4054 Some(Some(&"Frank".to_string()))
4055 );
4056
4057 let arc_product_kps: Vec<_> = all_keypaths
4059 .iter()
4060 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4061 .collect();
4062
4063 assert_eq!(arc_product_kps.len(), 1);
4064
4065 let arc_product = Arc::new(product);
4067 assert_eq!(
4068 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4069 Some(Some(&"Laptop".to_string()))
4070 );
4071 }
4072
4073 #[test]
4074 fn test_akp_filter_by_box_root_type() {
4075 use std::any::TypeId;
4076
4077 #[derive(Debug)]
4078 struct Config {
4079 setting: String,
4080 }
4081
4082 let config = Config {
4083 setting: "enabled".to_string(),
4084 };
4085
4086 let config_kp1 = KpType::new(
4088 |c: &Config| Some(&c.setting),
4089 |c: &mut Config| Some(&mut c.setting),
4090 );
4091 let config_kp2 = KpType::new(
4092 |c: &Config| Some(&c.setting),
4093 |c: &mut Config| Some(&mut c.setting),
4094 );
4095
4096 let regular_akp = AKp::new(config_kp1);
4098 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4099
4100 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4101
4102 let config_kps: Vec<_> = all_keypaths
4104 .iter()
4105 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4106 .collect();
4107
4108 assert_eq!(config_kps.len(), 1);
4109 assert_eq!(
4110 config_kps[0].get_as::<Config, String>(&config),
4111 Some(Some(&"enabled".to_string()))
4112 );
4113
4114 let box_config_kps: Vec<_> = all_keypaths
4116 .iter()
4117 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4118 .collect();
4119
4120 assert_eq!(box_config_kps.len(), 1);
4121
4122 let box_config = Box::new(Config {
4124 setting: "enabled".to_string(),
4125 });
4126 assert_eq!(
4127 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4128 Some(Some(&"enabled".to_string()))
4129 );
4130 }
4131
4132 #[test]
4133 fn test_mixed_collection_type_filtering() {
4134 use std::any::TypeId;
4135 use std::sync::Arc;
4136
4137 #[derive(Debug)]
4138 struct User {
4139 name: String,
4140 email: String,
4141 }
4142
4143 #[derive(Debug)]
4144 struct Product {
4145 title: String,
4146 sku: String,
4147 }
4148
4149 let user = User {
4150 name: "Grace".to_string(),
4151 email: "grace@example.com".to_string(),
4152 };
4153
4154 let product = Product {
4155 title: "Widget".to_string(),
4156 sku: "WID-001".to_string(),
4157 };
4158
4159 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4161 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4162 let user_email_kp1 =
4163 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4164 let user_email_kp2 =
4165 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4166 let product_title_kp = KpType::new(
4167 |p: &Product| Some(&p.title),
4168 |p: &mut Product| Some(&mut p.title),
4169 );
4170 let product_sku_kp = KpType::new(
4171 |p: &Product| Some(&p.sku),
4172 |p: &mut Product| Some(&mut p.sku),
4173 );
4174
4175 let all_keypaths: Vec<AKp> = vec![
4176 AKp::new(user_name_kp1),
4177 AKp::new(user_email_kp1),
4178 AKp::new(product_title_kp),
4179 AKp::new(product_sku_kp),
4180 AKp::new(user_name_kp2).for_arc::<User>(),
4181 AKp::new(user_email_kp2).for_box::<User>(),
4182 ];
4183
4184 let string_value_kps: Vec<_> = all_keypaths
4186 .iter()
4187 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4188 .collect();
4189
4190 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4194 .iter()
4195 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4196 .collect();
4197
4198 assert_eq!(user_root_kps.len(), 2);
4199
4200 let arc_user_kps: Vec<_> = all_keypaths
4202 .iter()
4203 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4204 .collect();
4205
4206 assert_eq!(arc_user_kps.len(), 1);
4207
4208 let box_user_kps: Vec<_> = all_keypaths
4210 .iter()
4211 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4212 .collect();
4213
4214 assert_eq!(box_user_kps.len(), 1);
4215
4216 let product_kps: Vec<_> = all_keypaths
4218 .iter()
4219 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4220 .collect();
4221
4222 assert_eq!(product_kps.len(), 2);
4223
4224 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4226 assert!(user_value.is_some());
4227 assert!(user_value.unwrap().is_some());
4228 }
4229
4230 #[test]
4235 fn test_kp_with_pin() {
4236 use std::pin::Pin;
4237
4238 #[derive(Debug)]
4242 struct SelfReferential {
4243 value: String,
4244 ptr_to_value: *const String, }
4246
4247 impl SelfReferential {
4248 fn new(s: String) -> Self {
4249 let mut sr = Self {
4250 value: s,
4251 ptr_to_value: std::ptr::null(),
4252 };
4253 sr.ptr_to_value = &sr.value as *const String;
4255 sr
4256 }
4257
4258 fn get_value(&self) -> &str {
4259 &self.value
4260 }
4261 }
4262
4263 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4265 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4266
4267 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4269 |p: &Pin<Box<SelfReferential>>| {
4270 Some(&p.as_ref().get_ref().value)
4272 },
4273 |p: &mut Pin<Box<SelfReferential>>| {
4274 unsafe {
4277 let sr = Pin::get_unchecked_mut(p.as_mut());
4278 Some(&mut sr.value)
4279 }
4280 },
4281 );
4282
4283 let result = kp.get(&pinned);
4285 assert_eq!(result, Some(&"pinned_data".to_string()));
4286
4287 assert_eq!(pinned.get_value(), "pinned_data");
4289 }
4290
4291 #[test]
4292 fn test_kp_with_pin_arc() {
4293 use std::pin::Pin;
4294 use std::sync::Arc;
4295
4296 struct AsyncState {
4297 status: String,
4298 data: Vec<i32>,
4299 }
4300
4301 let state = AsyncState {
4303 status: "ready".to_string(),
4304 data: vec![1, 2, 3, 4, 5],
4305 };
4306
4307 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4308
4309 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4311 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4312 |_: &mut Pin<Arc<AsyncState>>| {
4313 None::<&mut String>
4315 },
4316 );
4317
4318 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4320 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4321 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4322 );
4323
4324 let status = status_kp.get(&pinned_arc);
4325 assert_eq!(status, Some(&"ready".to_string()));
4326
4327 let data = data_kp.get(&pinned_arc);
4328 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4329 }
4330
4331 #[test]
4332 fn test_kp_with_maybe_uninit() {
4333 use std::mem::MaybeUninit;
4334
4335 struct Config {
4339 name: MaybeUninit<String>,
4340 value: MaybeUninit<i32>,
4341 initialized: bool,
4342 }
4343
4344 impl Config {
4345 fn new_uninit() -> Self {
4346 Self {
4347 name: MaybeUninit::uninit(),
4348 value: MaybeUninit::uninit(),
4349 initialized: false,
4350 }
4351 }
4352
4353 fn init(&mut self, name: String, value: i32) {
4354 self.name.write(name);
4355 self.value.write(value);
4356 self.initialized = true;
4357 }
4358
4359 fn get_name(&self) -> Option<&String> {
4360 if self.initialized {
4361 unsafe { Some(self.name.assume_init_ref()) }
4362 } else {
4363 None
4364 }
4365 }
4366
4367 fn get_value(&self) -> Option<&i32> {
4368 if self.initialized {
4369 unsafe { Some(self.value.assume_init_ref()) }
4370 } else {
4371 None
4372 }
4373 }
4374 }
4375
4376 let name_kp: KpType<Config, String> = Kp::new(
4378 |c: &Config| c.get_name(),
4379 |c: &mut Config| {
4380 if c.initialized {
4381 unsafe { Some(c.name.assume_init_mut()) }
4382 } else {
4383 None
4384 }
4385 },
4386 );
4387
4388 let value_kp: KpType<Config, i32> = Kp::new(
4389 |c: &Config| c.get_value(),
4390 |c: &mut Config| {
4391 if c.initialized {
4392 unsafe { Some(c.value.assume_init_mut()) }
4393 } else {
4394 None
4395 }
4396 },
4397 );
4398
4399 let uninit_config = Config::new_uninit();
4401 assert_eq!(name_kp.get(&uninit_config), None);
4402 assert_eq!(value_kp.get(&uninit_config), None);
4403
4404 let mut init_config = Config::new_uninit();
4406 init_config.init("test_config".to_string(), 42);
4407
4408 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4409 assert_eq!(value_kp.get(&init_config), Some(&42));
4410
4411 if let Some(val) = value_kp.get_mut(&mut init_config) {
4413 *val = 100;
4414 }
4415
4416 assert_eq!(value_kp.get(&init_config), Some(&100));
4417 }
4418
4419 #[test]
4420 fn test_kp_with_weak() {
4421 use std::sync::{Arc, Weak};
4422
4423 #[derive(Debug, Clone)]
4427 struct Node {
4428 value: i32,
4429 }
4430
4431 struct NodeWithParent {
4432 value: i32,
4433 parent: Option<Arc<Node>>, }
4435
4436 let parent = Arc::new(Node { value: 100 });
4437
4438 let child = NodeWithParent {
4439 value: 42,
4440 parent: Some(parent.clone()),
4441 };
4442
4443 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4445 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4446 |_: &mut NodeWithParent| None::<&mut i32>,
4447 );
4448
4449 let parent_val = parent_value_kp.get(&child);
4451 assert_eq!(parent_val, Some(&100));
4452 }
4453
4454 #[test]
4455 fn test_kp_with_rc_weak() {
4456 use std::rc::Rc;
4457
4458 struct TreeNode {
4461 value: String,
4462 parent: Option<Rc<TreeNode>>, }
4464
4465 let root = Rc::new(TreeNode {
4466 value: "root".to_string(),
4467 parent: None,
4468 });
4469
4470 let child1 = TreeNode {
4471 value: "child1".to_string(),
4472 parent: Some(root.clone()),
4473 };
4474
4475 let child2 = TreeNode {
4476 value: "child2".to_string(),
4477 parent: Some(root.clone()),
4478 };
4479
4480 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4482 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4483 |_: &mut TreeNode| None::<&mut String>,
4484 );
4485
4486 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4488 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4489
4490 assert_eq!(parent_name_kp.get(&root), None);
4492 }
4493
4494 #[test]
4495 fn test_kp_with_complex_weak_structure() {
4496 use std::sync::Arc;
4497
4498 struct Cache {
4501 data: String,
4502 backup: Option<Arc<Cache>>, }
4504
4505 let primary = Arc::new(Cache {
4506 data: "primary_data".to_string(),
4507 backup: None,
4508 });
4509
4510 let backup = Arc::new(Cache {
4511 data: "backup_data".to_string(),
4512 backup: Some(primary.clone()),
4513 });
4514
4515 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4517 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4518 |_: &mut Arc<Cache>| None::<&mut String>,
4519 );
4520
4521 let data = backup_data_kp.get(&backup);
4523 assert_eq!(data, Some(&"primary_data".to_string()));
4524
4525 let no_backup = backup_data_kp.get(&primary);
4527 assert_eq!(no_backup, None);
4528 }
4529
4530 #[test]
4531 fn test_kp_chain_with_pin_and_arc() {
4532 use std::pin::Pin;
4533 use std::sync::Arc;
4534
4535 struct Outer {
4538 inner: Arc<Inner>,
4539 }
4540
4541 struct Inner {
4542 value: String,
4543 }
4544
4545 let outer = Outer {
4546 inner: Arc::new(Inner {
4547 value: "nested_value".to_string(),
4548 }),
4549 };
4550
4551 let pinned_outer = Box::pin(outer);
4552
4553 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4555 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4556 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4557 );
4558
4559 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4561 |a: &Arc<Inner>| Some(&a.value),
4562 |_: &mut Arc<Inner>| None::<&mut String>,
4563 );
4564
4565 let chained = to_inner.then(to_value);
4567
4568 let result = chained.get(&pinned_outer);
4569 assert_eq!(result, Some(&"nested_value".to_string()));
4570 }
4571
4572 #[test]
4573 fn test_kp_with_maybe_uninit_array() {
4574 use std::mem::MaybeUninit;
4575
4576 struct Buffer {
4580 data: [MaybeUninit<u8>; 10],
4581 len: usize,
4582 }
4583
4584 impl Buffer {
4585 fn new() -> Self {
4586 Self {
4587 data: unsafe { MaybeUninit::uninit().assume_init() },
4588 len: 0,
4589 }
4590 }
4591
4592 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4593 if self.len >= self.data.len() {
4594 return Err("Buffer full");
4595 }
4596 self.data[self.len].write(byte);
4597 self.len += 1;
4598 Ok(())
4599 }
4600
4601 fn get(&self, idx: usize) -> Option<&u8> {
4602 if idx < self.len {
4603 unsafe { Some(self.data[idx].assume_init_ref()) }
4604 } else {
4605 None
4606 }
4607 }
4608
4609 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4610 if idx < self.len {
4611 unsafe { Some(self.data[idx].assume_init_mut()) }
4612 } else {
4613 None
4614 }
4615 }
4616 }
4617
4618 let len_kp: KpType<Buffer, usize> =
4620 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4621
4622 let mut buffer = Buffer::new();
4623
4624 assert_eq!(len_kp.get(&buffer), Some(&0));
4626
4627 buffer.push(1).unwrap();
4629 buffer.push(2).unwrap();
4630 buffer.push(3).unwrap();
4631
4632 assert_eq!(len_kp.get(&buffer), Some(&3));
4634
4635 assert_eq!(buffer.get(0), Some(&1));
4637 assert_eq!(buffer.get(1), Some(&2));
4638 assert_eq!(buffer.get(2), Some(&3));
4639 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4643 *elem = 20;
4644 }
4645 assert_eq!(buffer.get(1), Some(&20));
4646 }
4647
4648 #[test]
4649 fn test_kp_then_lock_deep_structs() {
4650 use std::sync::{Arc, Mutex};
4651
4652 #[derive(Clone)]
4653 struct Root {
4654 guard: Arc<Mutex<Level1>>,
4655 }
4656 #[derive(Clone)]
4657 struct Level1 {
4658 name: String,
4659 nested: Level2,
4660 }
4661 #[derive(Clone)]
4662 struct Level2 {
4663 count: i32,
4664 }
4665
4666 let root = Root {
4667 guard: Arc::new(Mutex::new(Level1 {
4668 name: "deep".to_string(),
4669 nested: Level2 { count: 42 },
4670 })),
4671 };
4672
4673 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4674 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4675
4676 let lock_kp = {
4677 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
4678 Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
4679 let next: KpType<Level1, Level1> =
4680 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4681 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4682 };
4683
4684 let chained = kp_to_guard.then_lock(lock_kp);
4685 let level1 = chained.get(&root);
4686 assert!(level1.is_some());
4687 assert_eq!(level1.unwrap().name, "deep");
4688 assert_eq!(level1.unwrap().nested.count, 42);
4689
4690 let mut_root = &mut root.clone();
4691 let mut_level1 = chained.get_mut(mut_root);
4692 assert!(mut_level1.is_some());
4693 mut_level1.unwrap().nested.count = 99;
4694 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4695 }
4696
4697 #[test]
4698 fn test_kp_then_lock_with_enum() {
4699 use std::sync::{Arc, Mutex};
4700
4701 #[derive(Clone)]
4702 enum Message {
4703 Request(LevelA),
4704 Response(i32),
4705 }
4706 #[derive(Clone)]
4707 struct LevelA {
4708 data: Arc<Mutex<i32>>,
4709 }
4710
4711 struct RootWithEnum {
4712 msg: Arc<Mutex<Message>>,
4713 }
4714
4715 let root = RootWithEnum {
4716 msg: Arc::new(Mutex::new(Message::Request(LevelA {
4717 data: Arc::new(Mutex::new(100)),
4718 }))),
4719 };
4720
4721 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
4722 Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
4723
4724 let lock_kp_msg = {
4725 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
4726 Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
4727 let next: KpType<Message, Message> =
4728 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4729 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4730 };
4731
4732 let chained = kp_msg.then_lock(lock_kp_msg);
4733 let msg = chained.get(&root);
4734 assert!(msg.is_some());
4735 match msg.unwrap() {
4736 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
4737 Message::Response(_) => panic!("expected Request"),
4738 }
4739 }
4740
4741 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4742 #[tokio::test]
4743 async fn test_kp_then_async_deep_chain() {
4744 use std::sync::Arc;
4745 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4746
4747 #[derive(Clone)]
4748 struct Root {
4749 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
4750 }
4751 #[derive(Clone)]
4752 struct Level1 {
4753 value: i32,
4754 }
4755
4756 let root = Root {
4757 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
4758 };
4759
4760 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
4761 |r: &Root| Some(&r.tokio_guard),
4762 |r: &mut Root| Some(&mut r.tokio_guard),
4763 );
4764
4765 let async_kp = {
4766 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
4767 Kp::new(
4768 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
4769 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
4770 );
4771 let next: KpType<Level1, Level1> =
4772 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4773 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4774 };
4775
4776 let chained = kp_to_guard.then_async(async_kp);
4777 let level1 = chained.get(&root).await;
4778 assert!(level1.is_some());
4779 assert_eq!(level1.unwrap().value, 7);
4780 }
4781
4782 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4785 #[tokio::test]
4786 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
4787 use std::sync::{Arc, Mutex};
4788 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4789 use crate::lock::{LockKp, ArcMutexAccess};
4790
4791 #[derive(Clone)]
4793 struct Root {
4794 sync_mutex: Arc<Mutex<Level1>>,
4795 }
4796 #[derive(Clone)]
4798 struct Level1 {
4799 inner: Level2,
4800 }
4801 #[derive(Clone)]
4803 struct Level2 {
4804 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
4805 }
4806 #[derive(Clone)]
4808 struct Level3 {
4809 leaf: i32,
4810 }
4811
4812 let mut root = Root {
4813 sync_mutex: Arc::new(Mutex::new(Level1 {
4814 inner: Level2 {
4815 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
4816 },
4817 })),
4818 };
4819
4820 let identity_l1: KpType<Level1, Level1> =
4822 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4823 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
4824 Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
4825 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
4826
4827 let kp_l1_inner: KpType<Level1, Level2> =
4829 Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
4830
4831 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
4833 |l: &Level2| Some(&l.tokio_mutex),
4834 |l: &mut Level2| Some(&mut l.tokio_mutex),
4835 );
4836
4837 let async_l3 = {
4839 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
4840 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
4841 let next: KpType<Level3, Level3> =
4842 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
4843 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4844 };
4845
4846 let kp_l3_leaf: KpType<Level3, i32> =
4848 Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
4849
4850 let step1 = lock_root_to_l1.then(kp_l1_inner);
4852 let step2 = step1.then(kp_l2_tokio);
4853 let step3 = step2.then_async(async_l3);
4854 let deep_chain = step3.then(kp_l3_leaf);
4855
4856 let leaf = deep_chain.get(&root).await;
4858 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
4859 assert_eq!(leaf, Some(&100));
4860
4861 let mut root_mut = root.clone();
4863 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
4864 assert!(leaf_mut.is_some());
4865 *leaf_mut.unwrap() = 99;
4866
4867 let leaf_after = deep_chain.get(&root_mut).await;
4869 assert_eq!(leaf_after, Some(&99));
4870 }
4871}