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 kp_f = TestKP::f();
2012 let wres = kp_f.then(TestKP2::a()).get_mut(&mut instance).unwrap();
2013 *wres = String::from("a3 changed successfully");
2014 let res = kp_f.then(TestKP2::a()).get(&instance);
2015 println!("{:?}", res);
2016 let res = kp_f.then(TestKP2::identity()).get(&instance);
2017 println!("{:?}", res);
2018 let res = kp.get(&instance);
2019 println!("{:?}", res);
2020
2021 let hash_kp = TestKP::g(0);
2022 let new_kp_from_hashmap = hash_kp.then(TestKP2::a());
2023 println!("{:?}", new_kp_from_hashmap.get(&instance));
2024 }
2025
2026 #[test]
2062 fn test_enum_kp_result_ok() {
2063 let ok_result: Result<String, i32> = Ok("success".to_string());
2064 let mut err_result: Result<String, i32> = Err(42);
2065
2066 let ok_kp = enum_ok();
2067
2068 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2070 assert_eq!(ok_kp.get(&err_result), None);
2071
2072 let embedded = ok_kp.embed("embedded".to_string());
2074 assert_eq!(embedded, Ok("embedded".to_string()));
2075
2076 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2078 *val = "modified".to_string();
2079 }
2080 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2083 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2084 *val = "modified".to_string();
2085 }
2086 assert_eq!(ok_result2, Ok("modified".to_string()));
2087 }
2088
2089 #[test]
2090 fn test_enum_kp_result_err() {
2091 let ok_result: Result<String, i32> = Ok("success".to_string());
2092 let mut err_result: Result<String, i32> = Err(42);
2093
2094 let err_kp = enum_err();
2095
2096 assert_eq!(err_kp.get(&err_result), Some(&42));
2098 assert_eq!(err_kp.get(&ok_result), None);
2099
2100 let embedded = err_kp.embed(99);
2102 assert_eq!(embedded, Err(99));
2103
2104 if let Some(val) = err_kp.get_mut(&mut err_result) {
2106 *val = 100;
2107 }
2108 assert_eq!(err_result, Err(100));
2109 }
2110
2111 #[test]
2112 fn test_enum_kp_option_some() {
2113 let some_opt = Some("value".to_string());
2114 let mut none_opt: Option<String> = None;
2115
2116 let some_kp = enum_some();
2117
2118 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2120 assert_eq!(some_kp.get(&none_opt), None);
2121
2122 let embedded = some_kp.embed("embedded".to_string());
2124 assert_eq!(embedded, Some("embedded".to_string()));
2125
2126 let mut some_opt2 = Some("original".to_string());
2128 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2129 *val = "modified".to_string();
2130 }
2131 assert_eq!(some_opt2, Some("modified".to_string()));
2132 }
2133
2134 #[test]
2135 fn test_enum_kp_custom_enum() {
2136 #[derive(Debug, PartialEq)]
2137 enum MyEnum {
2138 A(String),
2139 B(i32),
2140 C,
2141 }
2142
2143 let mut enum_a = MyEnum::A("hello".to_string());
2144 let enum_b = MyEnum::B(42);
2145 let enum_c = MyEnum::C;
2146
2147 let kp_a = enum_variant(
2149 |e: &MyEnum| match e {
2150 MyEnum::A(s) => Some(s),
2151 _ => None,
2152 },
2153 |e: &mut MyEnum| match e {
2154 MyEnum::A(s) => Some(s),
2155 _ => None,
2156 },
2157 |s: String| MyEnum::A(s),
2158 );
2159
2160 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2162 assert_eq!(kp_a.get(&enum_b), None);
2163 assert_eq!(kp_a.get(&enum_c), None);
2164
2165 let embedded = kp_a.embed("world".to_string());
2167 assert_eq!(embedded, MyEnum::A("world".to_string()));
2168
2169 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2171 *val = "modified".to_string();
2172 }
2173 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2174 }
2175
2176 #[test]
2177 fn test_container_kp_box() {
2178 let boxed = Box::new("value".to_string());
2179 let mut boxed_mut = Box::new("original".to_string());
2180
2181 let box_kp = kp_box();
2182
2183 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2185
2186 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2188 *val = "modified".to_string();
2189 }
2190 assert_eq!(*boxed_mut, "modified".to_string());
2191 }
2192
2193 #[test]
2194 fn test_container_kp_arc() {
2195 let arc = Arc::new("value".to_string());
2196 let mut arc_mut = Arc::new("original".to_string());
2197
2198 let arc_kp = kp_arc();
2199
2200 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2202
2203 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2205 *val = "modified".to_string();
2206 }
2207 assert_eq!(*arc_mut, "modified".to_string());
2208
2209 let arc_shared = Arc::new("shared".to_string());
2211 let arc_shared2 = Arc::clone(&arc_shared);
2212 let mut arc_shared_mut = arc_shared;
2213 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2214 }
2215
2216 #[test]
2217 fn test_enum_kp_composition() {
2218 #[derive(Debug, PartialEq)]
2220 struct Inner {
2221 value: String,
2222 }
2223
2224 let result: Result<Inner, i32> = Ok(Inner {
2225 value: "nested".to_string(),
2226 });
2227
2228 let inner_kp = KpType::new(
2230 |i: &Inner| Some(&i.value),
2231 |i: &mut Inner| Some(&mut i.value),
2232 );
2233
2234 let ok_kp = enum_ok::<Inner, i32>();
2236 let ok_kp_base = ok_kp.into_kp();
2237 let composed = ok_kp_base.then(inner_kp);
2238
2239 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2240 }
2241
2242 #[test]
2243 fn test_pkp_basic() {
2244 #[derive(Debug)]
2245 struct User {
2246 name: String,
2247 age: i32,
2248 }
2249
2250 let user = User {
2251 name: "Alice".to_string(),
2252 age: 30,
2253 };
2254
2255 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2257 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2258
2259 let name_pkp = PKp::new(name_kp);
2261 let age_pkp = PKp::new(age_kp);
2262
2263 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2265 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2266
2267 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2269 assert_eq!(age_pkp.get_as::<String>(&user), None);
2270
2271 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2273 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2274 }
2275
2276 #[test]
2277 fn test_pkp_collection() {
2278 #[derive(Debug)]
2279 struct User {
2280 name: String,
2281 age: i32,
2282 }
2283
2284 let user = User {
2285 name: "Bob".to_string(),
2286 age: 25,
2287 };
2288
2289 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2291 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2292
2293 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2294
2295 let name_value = keypaths[0].get_as::<String>(&user);
2297 let age_value = keypaths[1].get_as::<i32>(&user);
2298
2299 assert_eq!(name_value, Some(&"Bob".to_string()));
2300 assert_eq!(age_value, Some(&25));
2301 }
2302
2303 #[test]
2304 fn test_pkp_for_arc() {
2305 #[derive(Debug)]
2306 struct User {
2307 name: String,
2308 }
2309
2310 let user = Arc::new(User {
2311 name: "Charlie".to_string(),
2312 });
2313
2314 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2315 let name_pkp = PKp::new(name_kp);
2316
2317 let arc_pkp = name_pkp.for_arc();
2319
2320 assert_eq!(
2321 arc_pkp.get_as::<String>(&user),
2322 Some(&"Charlie".to_string())
2323 );
2324 }
2325
2326 #[test]
2327 fn test_pkp_for_option() {
2328 #[derive(Debug)]
2329 struct User {
2330 name: String,
2331 }
2332
2333 let some_user = Some(User {
2334 name: "Diana".to_string(),
2335 });
2336 let none_user: Option<User> = None;
2337
2338 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2339 let name_pkp = PKp::new(name_kp);
2340
2341 let opt_pkp = name_pkp.for_option();
2343
2344 assert_eq!(
2345 opt_pkp.get_as::<String>(&some_user),
2346 Some(&"Diana".to_string())
2347 );
2348 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2349 }
2350
2351 #[test]
2352 fn test_akp_basic() {
2353 #[derive(Debug)]
2354 struct User {
2355 name: String,
2356 age: i32,
2357 }
2358
2359 #[derive(Debug)]
2360 struct Product {
2361 title: String,
2362 price: f64,
2363 }
2364
2365 let user = User {
2366 name: "Eve".to_string(),
2367 age: 28,
2368 };
2369
2370 let product = Product {
2371 title: "Book".to_string(),
2372 price: 19.99,
2373 };
2374
2375 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2377 let user_name_akp = AKp::new(user_name_kp);
2378
2379 let product_title_kp = KpType::new(
2380 |p: &Product| Some(&p.title),
2381 |p: &mut Product| Some(&mut p.title),
2382 );
2383 let product_title_akp = AKp::new(product_title_kp);
2384
2385 assert_eq!(
2387 user_name_akp.get_as::<User, String>(&user),
2388 Some(Some(&"Eve".to_string()))
2389 );
2390 assert_eq!(
2391 product_title_akp.get_as::<Product, String>(&product),
2392 Some(Some(&"Book".to_string()))
2393 );
2394
2395 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2397 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2398
2399 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2401 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2402 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2403 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2404 }
2405
2406 #[test]
2407 fn test_akp_heterogeneous_collection() {
2408 #[derive(Debug)]
2409 struct User {
2410 name: String,
2411 }
2412
2413 #[derive(Debug)]
2414 struct Product {
2415 title: String,
2416 }
2417
2418 let user = User {
2419 name: "Frank".to_string(),
2420 };
2421 let product = Product {
2422 title: "Laptop".to_string(),
2423 };
2424
2425 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2427 let product_title_kp = KpType::new(
2428 |p: &Product| Some(&p.title),
2429 |p: &mut Product| Some(&mut p.title),
2430 );
2431
2432 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2433
2434 let user_any: &dyn Any = &user;
2436 let product_any: &dyn Any = &product;
2437
2438 let user_value = keypaths[0].get(user_any);
2439 let product_value = keypaths[1].get(product_any);
2440
2441 assert!(user_value.is_some());
2442 assert!(product_value.is_some());
2443
2444 assert_eq!(
2446 user_value.and_then(|v| v.downcast_ref::<String>()),
2447 Some(&"Frank".to_string())
2448 );
2449 assert_eq!(
2450 product_value.and_then(|v| v.downcast_ref::<String>()),
2451 Some(&"Laptop".to_string())
2452 );
2453 }
2454
2455 #[test]
2456 fn test_akp_for_option() {
2457 #[derive(Debug)]
2458 struct User {
2459 name: String,
2460 }
2461
2462 let some_user = Some(User {
2463 name: "Grace".to_string(),
2464 });
2465 let none_user: Option<User> = None;
2466
2467 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2468 let name_akp = AKp::new(name_kp);
2469
2470 let opt_akp = name_akp.for_option::<User>();
2472
2473 assert_eq!(
2474 opt_akp.get_as::<Option<User>, String>(&some_user),
2475 Some(Some(&"Grace".to_string()))
2476 );
2477 assert_eq!(
2478 opt_akp.get_as::<Option<User>, String>(&none_user),
2479 Some(None)
2480 );
2481 }
2482
2483 #[test]
2484 fn test_akp_for_result() {
2485 #[derive(Debug)]
2486 struct User {
2487 name: String,
2488 }
2489
2490 let ok_user: Result<User, String> = Ok(User {
2491 name: "Henry".to_string(),
2492 });
2493 let err_user: Result<User, String> = Err("Not found".to_string());
2494
2495 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2496 let name_akp = AKp::new(name_kp);
2497
2498 let result_akp = name_akp.for_result::<User, String>();
2500
2501 assert_eq!(
2502 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2503 Some(Some(&"Henry".to_string()))
2504 );
2505 assert_eq!(
2506 result_akp.get_as::<Result<User, String>, String>(&err_user),
2507 Some(None)
2508 );
2509 }
2510
2511 #[test]
2514 fn test_kp_map() {
2515 #[derive(Debug)]
2516 struct User {
2517 name: String,
2518 age: i32,
2519 }
2520
2521 let user = User {
2522 name: "Alice".to_string(),
2523 age: 30,
2524 };
2525
2526 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2528 let len_kp = name_kp.map(|name: &String| name.len());
2529
2530 assert_eq!(len_kp.get(&user), Some(5));
2531
2532 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2534 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2535
2536 assert_eq!(double_age_kp.get(&user), Some(60));
2537
2538 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2540 assert_eq!(is_adult_kp.get(&user), Some(true));
2541 }
2542
2543 #[test]
2544 fn test_kp_filter() {
2545 #[derive(Debug)]
2546 struct User {
2547 name: String,
2548 age: i32,
2549 }
2550
2551 let adult = User {
2552 name: "Alice".to_string(),
2553 age: 30,
2554 };
2555
2556 let minor = User {
2557 name: "Bob".to_string(),
2558 age: 15,
2559 };
2560
2561 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2562 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2563
2564 assert_eq!(adult_age_kp.get(&adult), Some(&30));
2565 assert_eq!(adult_age_kp.get(&minor), None);
2566
2567 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2569 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2570
2571 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2572 assert_eq!(short_name_kp.get(&adult), None);
2573 }
2574
2575 #[test]
2576 fn test_kp_map_and_filter() {
2577 #[derive(Debug)]
2578 struct User {
2579 scores: Vec<i32>,
2580 }
2581
2582 let user = User {
2583 scores: vec![85, 92, 78, 95],
2584 };
2585
2586 let scores_kp = KpType::new(
2587 |u: &User| Some(&u.scores),
2588 |u: &mut User| Some(&mut u.scores),
2589 );
2590
2591 let avg_kp =
2593 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2594
2595 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2597
2598 assert_eq!(high_avg_kp.get(&user), Some(87)); }
2600
2601 #[test]
2602 fn test_enum_kp_map() {
2603 let ok_result: Result<String, i32> = Ok("hello".to_string());
2604 let err_result: Result<String, i32> = Err(42);
2605
2606 let ok_kp = enum_ok::<String, i32>();
2607 let len_kp = ok_kp.map(|s: &String| s.len());
2608
2609 assert_eq!(len_kp.get(&ok_result), Some(5));
2610 assert_eq!(len_kp.get(&err_result), None);
2611
2612 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2614 let none_opt: Option<Vec<i32>> = None;
2615
2616 let some_kp = enum_some::<Vec<i32>>();
2617 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2618
2619 assert_eq!(count_kp.get(&some_opt), Some(5));
2620 assert_eq!(count_kp.get(&none_opt), None);
2621 }
2622
2623 #[test]
2624 fn test_enum_kp_filter() {
2625 let ok_result1: Result<i32, String> = Ok(42);
2626 let ok_result2: Result<i32, String> = Ok(-5);
2627 let err_result: Result<i32, String> = Err("error".to_string());
2628
2629 let ok_kp = enum_ok::<i32, String>();
2630 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2631
2632 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2633 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2638 let short_str = Some("hi".to_string());
2639
2640 let some_kp = enum_some::<String>();
2641 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2642
2643 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2644 assert_eq!(long_kp.get(&short_str), None);
2645 }
2646
2647 #[test]
2648 fn test_pkp_filter() {
2649 #[derive(Debug)]
2650 struct User {
2651 name: String,
2652 age: i32,
2653 }
2654
2655 let adult = User {
2656 name: "Alice".to_string(),
2657 age: 30,
2658 };
2659
2660 let minor = User {
2661 name: "Bob".to_string(),
2662 age: 15,
2663 };
2664
2665 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2666 let age_pkp = PKp::new(age_kp);
2667
2668 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2670
2671 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2672 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2673
2674 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2676 let name_pkp = PKp::new(name_kp);
2677 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2678
2679 assert_eq!(
2680 short_name_pkp.get_as::<String>(&minor),
2681 Some(&"Bob".to_string())
2682 );
2683 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2684 }
2685
2686 #[test]
2687 fn test_akp_filter() {
2688 #[derive(Debug)]
2689 struct User {
2690 age: i32,
2691 }
2692
2693 #[derive(Debug)]
2694 struct Product {
2695 price: f64,
2696 }
2697
2698 let adult = User { age: 30 };
2699 let minor = User { age: 15 };
2700 let expensive = Product { price: 99.99 };
2701 let cheap = Product { price: 5.0 };
2702
2703 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2705 let age_akp = AKp::new(age_kp);
2706 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2707
2708 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2709 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2710
2711 let price_kp = KpType::new(
2713 |p: &Product| Some(&p.price),
2714 |p: &mut Product| Some(&mut p.price),
2715 );
2716 let price_akp = AKp::new(price_kp);
2717 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2718
2719 assert_eq!(
2720 expensive_akp.get_as::<Product, f64>(&expensive),
2721 Some(Some(&99.99))
2722 );
2723 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2724 }
2725
2726 #[test]
2729 fn test_kp_filter_map() {
2730 #[derive(Debug)]
2731 struct User {
2732 middle_name: Option<String>,
2733 }
2734
2735 let user_with = User {
2736 middle_name: Some("Marie".to_string()),
2737 };
2738 let user_without = User { middle_name: None };
2739
2740 let middle_kp = KpType::new(
2741 |u: &User| Some(&u.middle_name),
2742 |u: &mut User| Some(&mut u.middle_name),
2743 );
2744
2745 let first_char_kp = middle_kp
2746 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
2747
2748 assert_eq!(first_char_kp.get(&user_with), Some('M'));
2749 assert_eq!(first_char_kp.get(&user_without), None);
2750 }
2751
2752 #[test]
2753 fn test_kp_inspect() {
2754 #[derive(Debug)]
2755 struct User {
2756 name: String,
2757 }
2758
2759 let user = User {
2760 name: "Alice".to_string(),
2761 };
2762
2763 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2767
2768 let result = name_kp.get(&user);
2771 assert_eq!(result, Some(&"Alice".to_string()));
2772
2773 }
2776
2777 #[test]
2778 fn test_kp_fold_value() {
2779 #[derive(Debug)]
2780 struct User {
2781 scores: Vec<i32>,
2782 }
2783
2784 let user = User {
2785 scores: vec![85, 92, 78, 95],
2786 };
2787
2788 let scores_kp = KpType::new(
2789 |u: &User| Some(&u.scores),
2790 |u: &mut User| Some(&mut u.scores),
2791 );
2792
2793 let sum_fn =
2795 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
2796
2797 assert_eq!(sum_fn(&user), 350);
2798 }
2799
2800 #[test]
2801 fn test_kp_any_all() {
2802 #[derive(Debug)]
2803 struct User {
2804 scores: Vec<i32>,
2805 }
2806
2807 let user_high = User {
2808 scores: vec![85, 92, 88],
2809 };
2810 let user_mixed = User {
2811 scores: vec![65, 92, 78],
2812 };
2813
2814 let scores_kp = KpType::new(
2815 |u: &User| Some(&u.scores),
2816 |u: &mut User| Some(&mut u.scores),
2817 );
2818
2819 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
2821 assert!(has_high_fn(&user_high));
2822 assert!(has_high_fn(&user_mixed));
2823
2824 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
2826 assert!(all_passing_fn(&user_high));
2827 assert!(!all_passing_fn(&user_mixed));
2828 }
2829
2830 #[test]
2831 fn test_kp_count_items() {
2832 #[derive(Debug)]
2833 struct User {
2834 tags: Vec<String>,
2835 }
2836
2837 let user = User {
2838 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
2839 };
2840
2841 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2842 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
2843
2844 assert_eq!(count_fn(&user), Some(3));
2845 }
2846
2847 #[test]
2848 fn test_kp_find_in() {
2849 #[derive(Debug)]
2850 struct User {
2851 scores: Vec<i32>,
2852 }
2853
2854 let user = User {
2855 scores: vec![85, 92, 78, 95, 88],
2856 };
2857
2858 let scores_kp = KpType::new(
2859 |u: &User| Some(&u.scores),
2860 |u: &mut User| Some(&mut u.scores),
2861 );
2862
2863 let first_high_fn =
2865 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
2866
2867 assert_eq!(first_high_fn(&user), Some(92));
2868
2869 let perfect_fn =
2871 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
2872
2873 assert_eq!(perfect_fn(&user), None);
2874 }
2875
2876 #[test]
2877 fn test_kp_take_skip() {
2878 #[derive(Debug)]
2879 struct User {
2880 tags: Vec<String>,
2881 }
2882
2883 let user = User {
2884 tags: vec![
2885 "a".to_string(),
2886 "b".to_string(),
2887 "c".to_string(),
2888 "d".to_string(),
2889 ],
2890 };
2891
2892 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2893
2894 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
2896 tags.iter().take(n).cloned().collect::<Vec<_>>()
2897 });
2898
2899 let taken = take_fn(&user).unwrap();
2900 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
2901
2902 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
2904 tags.iter().skip(n).cloned().collect::<Vec<_>>()
2905 });
2906
2907 let skipped = skip_fn(&user).unwrap();
2908 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
2909 }
2910
2911 #[test]
2912 fn test_kp_partition() {
2913 #[derive(Debug)]
2914 struct User {
2915 scores: Vec<i32>,
2916 }
2917
2918 let user = User {
2919 scores: vec![85, 92, 65, 95, 72, 58],
2920 };
2921
2922 let scores_kp = KpType::new(
2923 |u: &User| Some(&u.scores),
2924 |u: &mut User| Some(&mut u.scores),
2925 );
2926
2927 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
2928 scores.iter().copied().partition(|&s| s >= 70)
2929 });
2930
2931 let (passing, failing) = partition_fn(&user).unwrap();
2932 assert_eq!(passing, vec![85, 92, 95, 72]);
2933 assert_eq!(failing, vec![65, 58]);
2934 }
2935
2936 #[test]
2937 fn test_kp_min_max() {
2938 #[derive(Debug)]
2939 struct User {
2940 scores: Vec<i32>,
2941 }
2942
2943 let user = User {
2944 scores: vec![85, 92, 78, 95, 88],
2945 };
2946
2947 let scores_kp = KpType::new(
2948 |u: &User| Some(&u.scores),
2949 |u: &mut User| Some(&mut u.scores),
2950 );
2951
2952 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
2954 assert_eq!(min_fn(&user), Some(78));
2955
2956 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
2958 assert_eq!(max_fn(&user), Some(95));
2959 }
2960
2961 #[test]
2962 fn test_kp_sum() {
2963 #[derive(Debug)]
2964 struct User {
2965 scores: Vec<i32>,
2966 }
2967
2968 let user = User {
2969 scores: vec![85, 92, 78],
2970 };
2971
2972 let scores_kp = KpType::new(
2973 |u: &User| Some(&u.scores),
2974 |u: &mut User| Some(&mut u.scores),
2975 );
2976
2977 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
2978 assert_eq!(sum_fn(&user), Some(255));
2979
2980 let avg_fn =
2982 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2983 assert_eq!(avg_fn.get(&user), Some(85));
2984 }
2985
2986 #[test]
2987 fn test_kp_chain() {
2988 #[derive(Debug)]
2989 struct User {
2990 profile: Profile,
2991 }
2992
2993 #[derive(Debug)]
2994 struct Profile {
2995 settings: Settings,
2996 }
2997
2998 #[derive(Debug)]
2999 struct Settings {
3000 theme: String,
3001 }
3002
3003 let user = User {
3004 profile: Profile {
3005 settings: Settings {
3006 theme: "dark".to_string(),
3007 },
3008 },
3009 };
3010
3011 let profile_kp = KpType::new(
3012 |u: &User| Some(&u.profile),
3013 |u: &mut User| Some(&mut u.profile),
3014 );
3015 let settings_kp = KpType::new(
3016 |p: &Profile| Some(&p.settings),
3017 |p: &mut Profile| Some(&mut p.settings),
3018 );
3019 let theme_kp = KpType::new(
3020 |s: &Settings| Some(&s.theme),
3021 |s: &mut Settings| Some(&mut s.theme),
3022 );
3023
3024 let profile_settings = profile_kp.chain(settings_kp);
3026 let theme_path = profile_settings.chain(theme_kp);
3027 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3028 }
3029
3030 #[test]
3031 fn test_kp_zip() {
3032 #[derive(Debug)]
3033 struct User {
3034 name: String,
3035 age: i32,
3036 }
3037
3038 let user = User {
3039 name: "Alice".to_string(),
3040 age: 30,
3041 };
3042
3043 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3044 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3045
3046 let zipped_fn = zip_kps(&name_kp, &age_kp);
3047 let result = zipped_fn(&user);
3048
3049 assert_eq!(result, Some((&"Alice".to_string(), &30)));
3050 }
3051
3052 #[test]
3053 fn test_kp_complex_pipeline() {
3054 #[derive(Debug)]
3055 struct User {
3056 transactions: Vec<Transaction>,
3057 }
3058
3059 #[derive(Debug)]
3060 struct Transaction {
3061 amount: f64,
3062 category: String,
3063 }
3064
3065 let user = User {
3066 transactions: vec![
3067 Transaction {
3068 amount: 50.0,
3069 category: "food".to_string(),
3070 },
3071 Transaction {
3072 amount: 100.0,
3073 category: "transport".to_string(),
3074 },
3075 Transaction {
3076 amount: 25.0,
3077 category: "food".to_string(),
3078 },
3079 Transaction {
3080 amount: 200.0,
3081 category: "shopping".to_string(),
3082 },
3083 ],
3084 };
3085
3086 let txns_kp = KpType::new(
3087 |u: &User| Some(&u.transactions),
3088 |u: &mut User| Some(&mut u.transactions),
3089 );
3090
3091 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3093 txns.iter()
3094 .filter(|t| t.category == "food")
3095 .map(|t| t.amount)
3096 .sum::<f64>()
3097 });
3098
3099 assert_eq!(food_total.get(&user), Some(75.0));
3100
3101 let has_large =
3103 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3104
3105 assert!(has_large(&user));
3106
3107 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3109 assert_eq!(count(&user), Some(4));
3110 }
3111
3112 #[test]
3116 fn test_no_clone_required_for_root() {
3117 use std::sync::Arc;
3118 use std::sync::atomic::{AtomicUsize, Ordering};
3119
3120 struct NonCloneableRoot {
3123 data: Arc<AtomicUsize>,
3124 cached_value: usize,
3125 }
3126
3127 impl NonCloneableRoot {
3128 fn new() -> Self {
3129 Self {
3130 data: Arc::new(AtomicUsize::new(42)),
3131 cached_value: 42,
3132 }
3133 }
3134
3135 fn increment(&mut self) {
3136 self.data.fetch_add(1, Ordering::SeqCst);
3137 self.cached_value = self.data.load(Ordering::SeqCst);
3138 }
3139
3140 fn get_value(&self) -> &usize {
3141 &self.cached_value
3142 }
3143
3144 fn get_value_mut(&mut self) -> &mut usize {
3145 &mut self.cached_value
3146 }
3147 }
3148
3149 let mut root = NonCloneableRoot::new();
3150
3151 let data_kp = KpType::new(
3153 |r: &NonCloneableRoot| Some(r.get_value()),
3154 |r: &mut NonCloneableRoot| {
3155 r.increment();
3156 Some(r.get_value_mut())
3157 },
3158 );
3159
3160 assert_eq!(data_kp.get(&root), Some(&42));
3162
3163 {
3164 let doubled = data_kp.map(|val: &usize| val * 2);
3166 assert_eq!(doubled.get(&root), Some(84));
3167
3168 let filtered = data_kp.filter(|val: &usize| *val > 0);
3170 assert_eq!(filtered.get(&root), Some(&42));
3171 } let value_ref = data_kp.get_mut(&mut root);
3175 assert!(value_ref.is_some());
3176 }
3177
3178 #[test]
3179 fn test_no_clone_required_for_value() {
3180 use std::sync::Arc;
3181 use std::sync::atomic::{AtomicUsize, Ordering};
3182
3183 struct NonCloneableValue {
3185 counter: Arc<AtomicUsize>,
3186 }
3187
3188 impl NonCloneableValue {
3189 fn new(val: usize) -> Self {
3190 Self {
3191 counter: Arc::new(AtomicUsize::new(val)),
3192 }
3193 }
3194
3195 fn get(&self) -> usize {
3196 self.counter.load(Ordering::SeqCst)
3197 }
3198 }
3199
3200 struct Root {
3201 value: NonCloneableValue,
3202 }
3203
3204 let root = Root {
3205 value: NonCloneableValue::new(100),
3206 };
3207
3208 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3210
3211 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3213 assert_eq!(counter_kp.get(&root), Some(100));
3214
3215 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3217 assert!(filtered.get(&root).is_some());
3218 }
3219
3220 #[test]
3221 fn test_static_does_not_leak_memory() {
3222 use std::sync::Arc;
3223 use std::sync::atomic::{AtomicUsize, Ordering};
3224
3225 static CREATED: AtomicUsize = AtomicUsize::new(0);
3227 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3228
3229 struct Tracked {
3230 id: usize,
3231 }
3232
3233 impl Tracked {
3234 fn new() -> Self {
3235 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3236 Self { id }
3237 }
3238 }
3239
3240 impl Drop for Tracked {
3241 fn drop(&mut self) {
3242 DROPPED.fetch_add(1, Ordering::SeqCst);
3243 }
3244 }
3245
3246 struct Root {
3247 data: Tracked,
3248 }
3249
3250 CREATED.store(0, Ordering::SeqCst);
3252 DROPPED.store(0, Ordering::SeqCst);
3253
3254 {
3255 let root = Root {
3256 data: Tracked::new(),
3257 };
3258
3259 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3260
3261 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3263 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3264 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3265
3266 assert_eq!(mapped1.get(&root), Some(0));
3267 assert_eq!(mapped2.get(&root), Some(1));
3268 assert_eq!(mapped3.get(&root), Some(2));
3269
3270 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3272 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3273 }
3274
3275 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3277 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3278
3279 }
3281
3282 #[test]
3283 fn test_references_not_cloned() {
3284 use std::sync::Arc;
3285
3286 struct ExpensiveData {
3288 large_vec: Vec<u8>,
3289 }
3290
3291 impl ExpensiveData {
3292 fn new(size: usize) -> Self {
3293 Self {
3294 large_vec: vec![0u8; size],
3295 }
3296 }
3297
3298 fn size(&self) -> usize {
3299 self.large_vec.len()
3300 }
3301 }
3302
3303 struct Root {
3304 expensive: ExpensiveData,
3305 }
3306
3307 let root = Root {
3308 expensive: ExpensiveData::new(1_000_000), };
3310
3311 let expensive_kp = KpType::new(
3312 |r: &Root| Some(&r.expensive),
3313 |r: &mut Root| Some(&mut r.expensive),
3314 );
3315
3316 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3318 assert_eq!(size_kp.get(&root), Some(1_000_000));
3319
3320 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3322 assert!(large_filter.get(&root).is_some());
3323
3324 }
3326
3327 #[test]
3328 fn test_hof_with_arc_no_extra_clones() {
3329 use std::sync::Arc;
3330
3331 #[derive(Debug)]
3332 struct SharedData {
3333 value: String,
3334 }
3335
3336 struct Root {
3337 shared: Arc<SharedData>,
3338 }
3339
3340 let shared = Arc::new(SharedData {
3341 value: "shared".to_string(),
3342 });
3343
3344 assert_eq!(Arc::strong_count(&shared), 1);
3346
3347 {
3348 let root = Root {
3349 shared: Arc::clone(&shared),
3350 };
3351
3352 assert_eq!(Arc::strong_count(&shared), 2);
3354
3355 let shared_kp = KpType::new(
3356 |r: &Root| Some(&r.shared),
3357 |r: &mut Root| Some(&mut r.shared),
3358 );
3359
3360 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3362
3363 assert_eq!(value_kp.get(&root), Some(6));
3365 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3369 assert!(filtered.get(&root).is_some());
3370 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3375
3376 #[test]
3377 fn test_closure_captures_not_root_values() {
3378 use std::sync::Arc;
3379 use std::sync::atomic::{AtomicUsize, Ordering};
3380
3381 let call_count = Arc::new(AtomicUsize::new(0));
3383 let call_count_clone = Arc::clone(&call_count);
3384
3385 struct Root {
3386 value: i32,
3387 }
3388
3389 let root = Root { value: 42 };
3390
3391 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3392
3393 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3396 call_count_clone.fetch_add(1, Ordering::SeqCst);
3397 v * 2
3398 });
3399
3400 assert_eq!(doubled(&root), 84);
3402 assert_eq!(doubled(&root), 84);
3403 assert_eq!(doubled(&root), 84);
3404
3405 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3407
3408 }
3410
3411 #[test]
3412 fn test_static_with_borrowed_data() {
3413 struct Root {
3417 data: String,
3418 }
3419
3420 {
3421 let root = Root {
3422 data: "temporary".to_string(),
3423 };
3424
3425 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3426
3427 let len_kp = data_kp.map(|s: &String| s.len());
3429 assert_eq!(len_kp.get(&root), Some(9));
3430
3431 } }
3436
3437 #[test]
3438 fn test_multiple_hof_operations_no_accumulation() {
3439 use std::sync::Arc;
3440 use std::sync::atomic::{AtomicUsize, Ordering};
3441
3442 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3443
3444 struct Tracked {
3445 id: usize,
3446 }
3447
3448 impl Drop for Tracked {
3449 fn drop(&mut self) {
3450 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3451 }
3452 }
3453
3454 struct Root {
3455 values: Vec<Tracked>,
3456 }
3457
3458 DROP_COUNT.store(0, Ordering::SeqCst);
3459
3460 {
3461 let root = Root {
3462 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3463 };
3464
3465 let values_kp = KpType::new(
3466 |r: &Root| Some(&r.values),
3467 |r: &mut Root| Some(&mut r.values),
3468 );
3469
3470 let count = values_kp.count_items(|v| v.len());
3472 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3473 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3474 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3475
3476 assert_eq!(count(&root), Some(3));
3477 assert_eq!(sum(&root), Some(6));
3478 assert!(has_2(&root));
3479 assert!(all_positive(&root));
3480
3481 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3483 }
3484
3485 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3487 }
3488
3489 #[test]
3490 fn test_copy_bound_only_for_function_not_data() {
3491 #[derive(Debug)]
3495 struct NonCopyData {
3496 value: String,
3497 }
3498
3499 struct Root {
3500 data: NonCopyData,
3501 }
3502
3503 let root = Root {
3504 data: NonCopyData {
3505 value: "test".to_string(),
3506 },
3507 };
3508
3509 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3510
3511 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3514 assert_eq!(len_kp.get(&root), Some(4));
3515
3516 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3518 assert!(filtered.get(&root).is_some());
3519 }
3520
3521 #[test]
3522 fn test_no_memory_leak_with_cyclic_references() {
3523 use std::sync::atomic::{AtomicUsize, Ordering};
3524 use std::sync::{Arc, Weak};
3525
3526 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3527
3528 struct Node {
3529 id: usize,
3530 parent: Option<Weak<Node>>,
3531 }
3532
3533 impl Drop for Node {
3534 fn drop(&mut self) {
3535 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3536 }
3537 }
3538
3539 struct Root {
3540 node: Arc<Node>,
3541 }
3542
3543 DROP_COUNT.store(0, Ordering::SeqCst);
3544
3545 {
3546 let root = Root {
3547 node: Arc::new(Node {
3548 id: 1,
3549 parent: None,
3550 }),
3551 };
3552
3553 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3554
3555 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3557 assert_eq!(id_kp.get(&root), Some(1));
3558
3559 assert_eq!(Arc::strong_count(&root.node), 1);
3561
3562 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3564 }
3565
3566 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3568 }
3569
3570 #[test]
3571 fn test_hof_operations_are_zero_cost_abstractions() {
3572 struct Root {
3576 value: i32,
3577 }
3578
3579 let root = Root { value: 10 };
3580
3581 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3582
3583 let direct_result = value_kp.get(&root).map(|v| v * 2);
3585 assert_eq!(direct_result, Some(20));
3586
3587 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3589 let hof_result = mapped_kp.get(&root);
3590 assert_eq!(hof_result, Some(20));
3591
3592 assert_eq!(direct_result, hof_result);
3594 }
3595
3596 #[test]
3597 fn test_complex_closure_captures_allowed() {
3598 use std::sync::Arc;
3599
3600 struct Root {
3602 scores: Vec<i32>,
3603 }
3604
3605 let root = Root {
3606 scores: vec![85, 92, 78, 95, 88],
3607 };
3608
3609 let scores_kp = KpType::new(
3610 |r: &Root| Some(&r.scores),
3611 |r: &mut Root| Some(&mut r.scores),
3612 );
3613
3614 let threshold = 90;
3616 let multiplier = Arc::new(2);
3617
3618 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3620 let high: i32 = scores
3621 .iter()
3622 .filter(|&&s| s >= threshold)
3623 .map(|&s| s * *multiplier)
3624 .sum();
3625 acc + high
3626 });
3627
3628 assert_eq!(high_scores_doubled(&root), 374);
3630 }
3631
3632 #[test]
3636 fn test_pkp_filter_by_value_type() {
3637 use std::any::TypeId;
3638
3639 #[derive(Debug)]
3640 struct User {
3641 name: String,
3642 age: i32,
3643 score: f64,
3644 active: bool,
3645 }
3646
3647 let user = User {
3648 name: "Alice".to_string(),
3649 age: 30,
3650 score: 95.5,
3651 active: true,
3652 };
3653
3654 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3656 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3657 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3658 let active_kp = KpType::new(
3659 |u: &User| Some(&u.active),
3660 |u: &mut User| Some(&mut u.active),
3661 );
3662
3663 let all_keypaths: Vec<PKp<User>> = vec![
3665 PKp::new(name_kp),
3666 PKp::new(age_kp),
3667 PKp::new(score_kp),
3668 PKp::new(active_kp),
3669 ];
3670
3671 let string_kps: Vec<_> = all_keypaths
3673 .iter()
3674 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3675 .collect();
3676
3677 assert_eq!(string_kps.len(), 1);
3678 assert_eq!(
3679 string_kps[0].get_as::<String>(&user),
3680 Some(&"Alice".to_string())
3681 );
3682
3683 let i32_kps: Vec<_> = all_keypaths
3685 .iter()
3686 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3687 .collect();
3688
3689 assert_eq!(i32_kps.len(), 1);
3690 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3691
3692 let f64_kps: Vec<_> = all_keypaths
3694 .iter()
3695 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3696 .collect();
3697
3698 assert_eq!(f64_kps.len(), 1);
3699 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3700
3701 let bool_kps: Vec<_> = all_keypaths
3703 .iter()
3704 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3705 .collect();
3706
3707 assert_eq!(bool_kps.len(), 1);
3708 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3709 }
3710
3711 #[test]
3712 fn test_pkp_filter_by_struct_type() {
3713 use std::any::TypeId;
3714
3715 #[derive(Debug, PartialEq)]
3716 struct Address {
3717 street: String,
3718 city: String,
3719 }
3720
3721 #[derive(Debug)]
3722 struct User {
3723 name: String,
3724 age: i32,
3725 address: Address,
3726 }
3727
3728 let user = User {
3729 name: "Bob".to_string(),
3730 age: 25,
3731 address: Address {
3732 street: "123 Main St".to_string(),
3733 city: "NYC".to_string(),
3734 },
3735 };
3736
3737 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3739 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3740 let address_kp = KpType::new(
3741 |u: &User| Some(&u.address),
3742 |u: &mut User| Some(&mut u.address),
3743 );
3744
3745 let all_keypaths: Vec<PKp<User>> =
3746 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
3747
3748 let struct_kps: Vec<_> = all_keypaths
3750 .iter()
3751 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
3752 .collect();
3753
3754 assert_eq!(struct_kps.len(), 1);
3755 assert_eq!(
3756 struct_kps[0].get_as::<Address>(&user),
3757 Some(&Address {
3758 street: "123 Main St".to_string(),
3759 city: "NYC".to_string(),
3760 })
3761 );
3762
3763 let primitive_kps: Vec<_> = all_keypaths
3765 .iter()
3766 .filter(|pkp| {
3767 pkp.value_type_id() == TypeId::of::<String>()
3768 || pkp.value_type_id() == TypeId::of::<i32>()
3769 })
3770 .collect();
3771
3772 assert_eq!(primitive_kps.len(), 2);
3773 }
3774
3775 #[test]
3776 fn test_pkp_filter_by_arc_type() {
3777 use std::any::TypeId;
3778 use std::sync::Arc;
3779
3780 #[derive(Debug)]
3781 struct User {
3782 name: String,
3783 shared_data: Arc<String>,
3784 shared_number: Arc<i32>,
3785 }
3786
3787 let user = User {
3788 name: "Charlie".to_string(),
3789 shared_data: Arc::new("shared".to_string()),
3790 shared_number: Arc::new(42),
3791 };
3792
3793 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3795 let shared_data_kp = KpType::new(
3796 |u: &User| Some(&u.shared_data),
3797 |u: &mut User| Some(&mut u.shared_data),
3798 );
3799 let shared_number_kp = KpType::new(
3800 |u: &User| Some(&u.shared_number),
3801 |u: &mut User| Some(&mut u.shared_number),
3802 );
3803
3804 let all_keypaths: Vec<PKp<User>> = vec![
3805 PKp::new(name_kp),
3806 PKp::new(shared_data_kp),
3807 PKp::new(shared_number_kp),
3808 ];
3809
3810 let arc_string_kps: Vec<_> = all_keypaths
3812 .iter()
3813 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
3814 .collect();
3815
3816 assert_eq!(arc_string_kps.len(), 1);
3817 assert_eq!(
3818 arc_string_kps[0]
3819 .get_as::<Arc<String>>(&user)
3820 .map(|arc| arc.as_str()),
3821 Some("shared")
3822 );
3823
3824 let arc_i32_kps: Vec<_> = all_keypaths
3826 .iter()
3827 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
3828 .collect();
3829
3830 assert_eq!(arc_i32_kps.len(), 1);
3831 assert_eq!(
3832 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
3833 Some(42)
3834 );
3835
3836 let all_arc_kps: Vec<_> = all_keypaths
3838 .iter()
3839 .filter(|pkp| {
3840 pkp.value_type_id() == TypeId::of::<Arc<String>>()
3841 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
3842 })
3843 .collect();
3844
3845 assert_eq!(all_arc_kps.len(), 2);
3846 }
3847
3848 #[test]
3849 fn test_pkp_filter_by_box_type() {
3850 use std::any::TypeId;
3851
3852 #[derive(Debug)]
3853 struct User {
3854 name: String,
3855 boxed_value: Box<i32>,
3856 boxed_string: Box<String>,
3857 }
3858
3859 let user = User {
3860 name: "Diana".to_string(),
3861 boxed_value: Box::new(100),
3862 boxed_string: Box::new("boxed".to_string()),
3863 };
3864
3865 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3867 let boxed_value_kp = KpType::new(
3868 |u: &User| Some(&u.boxed_value),
3869 |u: &mut User| Some(&mut u.boxed_value),
3870 );
3871 let boxed_string_kp = KpType::new(
3872 |u: &User| Some(&u.boxed_string),
3873 |u: &mut User| Some(&mut u.boxed_string),
3874 );
3875
3876 let all_keypaths: Vec<PKp<User>> = vec![
3877 PKp::new(name_kp),
3878 PKp::new(boxed_value_kp),
3879 PKp::new(boxed_string_kp),
3880 ];
3881
3882 let box_i32_kps: Vec<_> = all_keypaths
3884 .iter()
3885 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
3886 .collect();
3887
3888 assert_eq!(box_i32_kps.len(), 1);
3889 assert_eq!(
3890 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
3891 Some(100)
3892 );
3893
3894 let box_string_kps: Vec<_> = all_keypaths
3896 .iter()
3897 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
3898 .collect();
3899
3900 assert_eq!(box_string_kps.len(), 1);
3901 assert_eq!(
3902 box_string_kps[0]
3903 .get_as::<Box<String>>(&user)
3904 .map(|b| b.as_str()),
3905 Some("boxed")
3906 );
3907 }
3908
3909 #[test]
3910 fn test_akp_filter_by_root_and_value_type() {
3911 use std::any::TypeId;
3912
3913 #[derive(Debug)]
3914 struct User {
3915 name: String,
3916 age: i32,
3917 }
3918
3919 #[derive(Debug)]
3920 struct Product {
3921 title: String,
3922 price: f64,
3923 }
3924
3925 let user = User {
3926 name: "Eve".to_string(),
3927 age: 28,
3928 };
3929
3930 let product = Product {
3931 title: "Book".to_string(),
3932 price: 19.99,
3933 };
3934
3935 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3937 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3938 let product_title_kp = KpType::new(
3939 |p: &Product| Some(&p.title),
3940 |p: &mut Product| Some(&mut p.title),
3941 );
3942 let product_price_kp = KpType::new(
3943 |p: &Product| Some(&p.price),
3944 |p: &mut Product| Some(&mut p.price),
3945 );
3946
3947 let all_keypaths: Vec<AKp> = vec![
3948 AKp::new(user_name_kp),
3949 AKp::new(user_age_kp),
3950 AKp::new(product_title_kp),
3951 AKp::new(product_price_kp),
3952 ];
3953
3954 let user_kps: Vec<_> = all_keypaths
3956 .iter()
3957 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
3958 .collect();
3959
3960 assert_eq!(user_kps.len(), 2);
3961
3962 let product_kps: Vec<_> = all_keypaths
3964 .iter()
3965 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
3966 .collect();
3967
3968 assert_eq!(product_kps.len(), 2);
3969
3970 let string_value_kps: Vec<_> = all_keypaths
3972 .iter()
3973 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
3974 .collect();
3975
3976 assert_eq!(string_value_kps.len(), 2);
3977
3978 let user_string_kps: Vec<_> = all_keypaths
3980 .iter()
3981 .filter(|akp| {
3982 akp.root_type_id() == TypeId::of::<User>()
3983 && akp.value_type_id() == TypeId::of::<String>()
3984 })
3985 .collect();
3986
3987 assert_eq!(user_string_kps.len(), 1);
3988 assert_eq!(
3989 user_string_kps[0].get_as::<User, String>(&user),
3990 Some(Some(&"Eve".to_string()))
3991 );
3992
3993 let product_f64_kps: Vec<_> = all_keypaths
3995 .iter()
3996 .filter(|akp| {
3997 akp.root_type_id() == TypeId::of::<Product>()
3998 && akp.value_type_id() == TypeId::of::<f64>()
3999 })
4000 .collect();
4001
4002 assert_eq!(product_f64_kps.len(), 1);
4003 assert_eq!(
4004 product_f64_kps[0].get_as::<Product, f64>(&product),
4005 Some(Some(&19.99))
4006 );
4007 }
4008
4009 #[test]
4010 fn test_akp_filter_by_arc_root_type() {
4011 use std::any::TypeId;
4012 use std::sync::Arc;
4013
4014 #[derive(Debug)]
4015 struct User {
4016 name: String,
4017 }
4018
4019 #[derive(Debug)]
4020 struct Product {
4021 title: String,
4022 }
4023
4024 let user = User {
4025 name: "Frank".to_string(),
4026 };
4027 let product = Product {
4028 title: "Laptop".to_string(),
4029 };
4030
4031 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4033 let product_title_kp = KpType::new(
4034 |p: &Product| Some(&p.title),
4035 |p: &mut Product| Some(&mut p.title),
4036 );
4037
4038 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4040 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4041
4042 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4043
4044 let arc_user_kps: Vec<_> = all_keypaths
4046 .iter()
4047 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4048 .collect();
4049
4050 assert_eq!(arc_user_kps.len(), 1);
4051
4052 let arc_user = Arc::new(user);
4054 assert_eq!(
4055 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4056 Some(Some(&"Frank".to_string()))
4057 );
4058
4059 let arc_product_kps: Vec<_> = all_keypaths
4061 .iter()
4062 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4063 .collect();
4064
4065 assert_eq!(arc_product_kps.len(), 1);
4066
4067 let arc_product = Arc::new(product);
4069 assert_eq!(
4070 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4071 Some(Some(&"Laptop".to_string()))
4072 );
4073 }
4074
4075 #[test]
4076 fn test_akp_filter_by_box_root_type() {
4077 use std::any::TypeId;
4078
4079 #[derive(Debug)]
4080 struct Config {
4081 setting: String,
4082 }
4083
4084 let config = Config {
4085 setting: "enabled".to_string(),
4086 };
4087
4088 let config_kp1 = KpType::new(
4090 |c: &Config| Some(&c.setting),
4091 |c: &mut Config| Some(&mut c.setting),
4092 );
4093 let config_kp2 = KpType::new(
4094 |c: &Config| Some(&c.setting),
4095 |c: &mut Config| Some(&mut c.setting),
4096 );
4097
4098 let regular_akp = AKp::new(config_kp1);
4100 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4101
4102 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4103
4104 let config_kps: Vec<_> = all_keypaths
4106 .iter()
4107 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4108 .collect();
4109
4110 assert_eq!(config_kps.len(), 1);
4111 assert_eq!(
4112 config_kps[0].get_as::<Config, String>(&config),
4113 Some(Some(&"enabled".to_string()))
4114 );
4115
4116 let box_config_kps: Vec<_> = all_keypaths
4118 .iter()
4119 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4120 .collect();
4121
4122 assert_eq!(box_config_kps.len(), 1);
4123
4124 let box_config = Box::new(Config {
4126 setting: "enabled".to_string(),
4127 });
4128 assert_eq!(
4129 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4130 Some(Some(&"enabled".to_string()))
4131 );
4132 }
4133
4134 #[test]
4135 fn test_mixed_collection_type_filtering() {
4136 use std::any::TypeId;
4137 use std::sync::Arc;
4138
4139 #[derive(Debug)]
4140 struct User {
4141 name: String,
4142 email: String,
4143 }
4144
4145 #[derive(Debug)]
4146 struct Product {
4147 title: String,
4148 sku: String,
4149 }
4150
4151 let user = User {
4152 name: "Grace".to_string(),
4153 email: "grace@example.com".to_string(),
4154 };
4155
4156 let product = Product {
4157 title: "Widget".to_string(),
4158 sku: "WID-001".to_string(),
4159 };
4160
4161 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4163 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4164 let user_email_kp1 =
4165 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4166 let user_email_kp2 =
4167 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4168 let product_title_kp = KpType::new(
4169 |p: &Product| Some(&p.title),
4170 |p: &mut Product| Some(&mut p.title),
4171 );
4172 let product_sku_kp = KpType::new(
4173 |p: &Product| Some(&p.sku),
4174 |p: &mut Product| Some(&mut p.sku),
4175 );
4176
4177 let all_keypaths: Vec<AKp> = vec![
4178 AKp::new(user_name_kp1),
4179 AKp::new(user_email_kp1),
4180 AKp::new(product_title_kp),
4181 AKp::new(product_sku_kp),
4182 AKp::new(user_name_kp2).for_arc::<User>(),
4183 AKp::new(user_email_kp2).for_box::<User>(),
4184 ];
4185
4186 let string_value_kps: Vec<_> = all_keypaths
4188 .iter()
4189 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4190 .collect();
4191
4192 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4196 .iter()
4197 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4198 .collect();
4199
4200 assert_eq!(user_root_kps.len(), 2);
4201
4202 let arc_user_kps: Vec<_> = all_keypaths
4204 .iter()
4205 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4206 .collect();
4207
4208 assert_eq!(arc_user_kps.len(), 1);
4209
4210 let box_user_kps: Vec<_> = all_keypaths
4212 .iter()
4213 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4214 .collect();
4215
4216 assert_eq!(box_user_kps.len(), 1);
4217
4218 let product_kps: Vec<_> = all_keypaths
4220 .iter()
4221 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4222 .collect();
4223
4224 assert_eq!(product_kps.len(), 2);
4225
4226 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4228 assert!(user_value.is_some());
4229 assert!(user_value.unwrap().is_some());
4230 }
4231
4232 #[test]
4237 fn test_kp_with_pin() {
4238 use std::pin::Pin;
4239
4240 #[derive(Debug)]
4244 struct SelfReferential {
4245 value: String,
4246 ptr_to_value: *const String, }
4248
4249 impl SelfReferential {
4250 fn new(s: String) -> Self {
4251 let mut sr = Self {
4252 value: s,
4253 ptr_to_value: std::ptr::null(),
4254 };
4255 sr.ptr_to_value = &sr.value as *const String;
4257 sr
4258 }
4259
4260 fn get_value(&self) -> &str {
4261 &self.value
4262 }
4263 }
4264
4265 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4267 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4268
4269 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4271 |p: &Pin<Box<SelfReferential>>| {
4272 Some(&p.as_ref().get_ref().value)
4274 },
4275 |p: &mut Pin<Box<SelfReferential>>| {
4276 unsafe {
4279 let sr = Pin::get_unchecked_mut(p.as_mut());
4280 Some(&mut sr.value)
4281 }
4282 },
4283 );
4284
4285 let result = kp.get(&pinned);
4287 assert_eq!(result, Some(&"pinned_data".to_string()));
4288
4289 assert_eq!(pinned.get_value(), "pinned_data");
4291 }
4292
4293 #[test]
4294 fn test_kp_with_pin_arc() {
4295 use std::pin::Pin;
4296 use std::sync::Arc;
4297
4298 struct AsyncState {
4299 status: String,
4300 data: Vec<i32>,
4301 }
4302
4303 let state = AsyncState {
4305 status: "ready".to_string(),
4306 data: vec![1, 2, 3, 4, 5],
4307 };
4308
4309 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4310
4311 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4313 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4314 |_: &mut Pin<Arc<AsyncState>>| {
4315 None::<&mut String>
4317 },
4318 );
4319
4320 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4322 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4323 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4324 );
4325
4326 let status = status_kp.get(&pinned_arc);
4327 assert_eq!(status, Some(&"ready".to_string()));
4328
4329 let data = data_kp.get(&pinned_arc);
4330 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4331 }
4332
4333 #[test]
4334 fn test_kp_with_maybe_uninit() {
4335 use std::mem::MaybeUninit;
4336
4337 struct Config {
4341 name: MaybeUninit<String>,
4342 value: MaybeUninit<i32>,
4343 initialized: bool,
4344 }
4345
4346 impl Config {
4347 fn new_uninit() -> Self {
4348 Self {
4349 name: MaybeUninit::uninit(),
4350 value: MaybeUninit::uninit(),
4351 initialized: false,
4352 }
4353 }
4354
4355 fn init(&mut self, name: String, value: i32) {
4356 self.name.write(name);
4357 self.value.write(value);
4358 self.initialized = true;
4359 }
4360
4361 fn get_name(&self) -> Option<&String> {
4362 if self.initialized {
4363 unsafe { Some(self.name.assume_init_ref()) }
4364 } else {
4365 None
4366 }
4367 }
4368
4369 fn get_value(&self) -> Option<&i32> {
4370 if self.initialized {
4371 unsafe { Some(self.value.assume_init_ref()) }
4372 } else {
4373 None
4374 }
4375 }
4376 }
4377
4378 let name_kp: KpType<Config, String> = Kp::new(
4380 |c: &Config| c.get_name(),
4381 |c: &mut Config| {
4382 if c.initialized {
4383 unsafe { Some(c.name.assume_init_mut()) }
4384 } else {
4385 None
4386 }
4387 },
4388 );
4389
4390 let value_kp: KpType<Config, i32> = Kp::new(
4391 |c: &Config| c.get_value(),
4392 |c: &mut Config| {
4393 if c.initialized {
4394 unsafe { Some(c.value.assume_init_mut()) }
4395 } else {
4396 None
4397 }
4398 },
4399 );
4400
4401 let uninit_config = Config::new_uninit();
4403 assert_eq!(name_kp.get(&uninit_config), None);
4404 assert_eq!(value_kp.get(&uninit_config), None);
4405
4406 let mut init_config = Config::new_uninit();
4408 init_config.init("test_config".to_string(), 42);
4409
4410 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4411 assert_eq!(value_kp.get(&init_config), Some(&42));
4412
4413 if let Some(val) = value_kp.get_mut(&mut init_config) {
4415 *val = 100;
4416 }
4417
4418 assert_eq!(value_kp.get(&init_config), Some(&100));
4419 }
4420
4421 #[test]
4422 fn test_kp_with_weak() {
4423 use std::sync::{Arc, Weak};
4424
4425 #[derive(Debug, Clone)]
4429 struct Node {
4430 value: i32,
4431 }
4432
4433 struct NodeWithParent {
4434 value: i32,
4435 parent: Option<Arc<Node>>, }
4437
4438 let parent = Arc::new(Node { value: 100 });
4439
4440 let child = NodeWithParent {
4441 value: 42,
4442 parent: Some(parent.clone()),
4443 };
4444
4445 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4447 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4448 |_: &mut NodeWithParent| None::<&mut i32>,
4449 );
4450
4451 let parent_val = parent_value_kp.get(&child);
4453 assert_eq!(parent_val, Some(&100));
4454 }
4455
4456 #[test]
4457 fn test_kp_with_rc_weak() {
4458 use std::rc::Rc;
4459
4460 struct TreeNode {
4463 value: String,
4464 parent: Option<Rc<TreeNode>>, }
4466
4467 let root = Rc::new(TreeNode {
4468 value: "root".to_string(),
4469 parent: None,
4470 });
4471
4472 let child1 = TreeNode {
4473 value: "child1".to_string(),
4474 parent: Some(root.clone()),
4475 };
4476
4477 let child2 = TreeNode {
4478 value: "child2".to_string(),
4479 parent: Some(root.clone()),
4480 };
4481
4482 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4484 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4485 |_: &mut TreeNode| None::<&mut String>,
4486 );
4487
4488 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4490 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4491
4492 assert_eq!(parent_name_kp.get(&root), None);
4494 }
4495
4496 #[test]
4497 fn test_kp_with_complex_weak_structure() {
4498 use std::sync::Arc;
4499
4500 struct Cache {
4503 data: String,
4504 backup: Option<Arc<Cache>>, }
4506
4507 let primary = Arc::new(Cache {
4508 data: "primary_data".to_string(),
4509 backup: None,
4510 });
4511
4512 let backup = Arc::new(Cache {
4513 data: "backup_data".to_string(),
4514 backup: Some(primary.clone()),
4515 });
4516
4517 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4519 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4520 |_: &mut Arc<Cache>| None::<&mut String>,
4521 );
4522
4523 let data = backup_data_kp.get(&backup);
4525 assert_eq!(data, Some(&"primary_data".to_string()));
4526
4527 let no_backup = backup_data_kp.get(&primary);
4529 assert_eq!(no_backup, None);
4530 }
4531
4532 #[test]
4533 fn test_kp_chain_with_pin_and_arc() {
4534 use std::pin::Pin;
4535 use std::sync::Arc;
4536
4537 struct Outer {
4540 inner: Arc<Inner>,
4541 }
4542
4543 struct Inner {
4544 value: String,
4545 }
4546
4547 let outer = Outer {
4548 inner: Arc::new(Inner {
4549 value: "nested_value".to_string(),
4550 }),
4551 };
4552
4553 let pinned_outer = Box::pin(outer);
4554
4555 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4557 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4558 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4559 );
4560
4561 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4563 |a: &Arc<Inner>| Some(&a.value),
4564 |_: &mut Arc<Inner>| None::<&mut String>,
4565 );
4566
4567 let chained = to_inner.then(to_value);
4569
4570 let result = chained.get(&pinned_outer);
4571 assert_eq!(result, Some(&"nested_value".to_string()));
4572 }
4573
4574 #[test]
4575 fn test_kp_with_maybe_uninit_array() {
4576 use std::mem::MaybeUninit;
4577
4578 struct Buffer {
4582 data: [MaybeUninit<u8>; 10],
4583 len: usize,
4584 }
4585
4586 impl Buffer {
4587 fn new() -> Self {
4588 Self {
4589 data: unsafe { MaybeUninit::uninit().assume_init() },
4590 len: 0,
4591 }
4592 }
4593
4594 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4595 if self.len >= self.data.len() {
4596 return Err("Buffer full");
4597 }
4598 self.data[self.len].write(byte);
4599 self.len += 1;
4600 Ok(())
4601 }
4602
4603 fn get(&self, idx: usize) -> Option<&u8> {
4604 if idx < self.len {
4605 unsafe { Some(self.data[idx].assume_init_ref()) }
4606 } else {
4607 None
4608 }
4609 }
4610
4611 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4612 if idx < self.len {
4613 unsafe { Some(self.data[idx].assume_init_mut()) }
4614 } else {
4615 None
4616 }
4617 }
4618 }
4619
4620 let len_kp: KpType<Buffer, usize> =
4622 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4623
4624 let mut buffer = Buffer::new();
4625
4626 assert_eq!(len_kp.get(&buffer), Some(&0));
4628
4629 buffer.push(1).unwrap();
4631 buffer.push(2).unwrap();
4632 buffer.push(3).unwrap();
4633
4634 assert_eq!(len_kp.get(&buffer), Some(&3));
4636
4637 assert_eq!(buffer.get(0), Some(&1));
4639 assert_eq!(buffer.get(1), Some(&2));
4640 assert_eq!(buffer.get(2), Some(&3));
4641 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4645 *elem = 20;
4646 }
4647 assert_eq!(buffer.get(1), Some(&20));
4648 }
4649
4650 #[test]
4651 fn test_kp_then_lock_deep_structs() {
4652 use std::sync::{Arc, Mutex};
4653
4654 #[derive(Clone)]
4655 struct Root {
4656 guard: Arc<Mutex<Level1>>,
4657 }
4658 #[derive(Clone)]
4659 struct Level1 {
4660 name: String,
4661 nested: Level2,
4662 }
4663 #[derive(Clone)]
4664 struct Level2 {
4665 count: i32,
4666 }
4667
4668 let root = Root {
4669 guard: Arc::new(Mutex::new(Level1 {
4670 name: "deep".to_string(),
4671 nested: Level2 { count: 42 },
4672 })),
4673 };
4674
4675 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4676 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4677
4678 let lock_kp = {
4679 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
4680 Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
4681 let next: KpType<Level1, Level1> =
4682 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4683 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4684 };
4685
4686 let chained = kp_to_guard.then_lock(lock_kp);
4687 let level1 = chained.get(&root);
4688 assert!(level1.is_some());
4689 assert_eq!(level1.unwrap().name, "deep");
4690 assert_eq!(level1.unwrap().nested.count, 42);
4691
4692 let mut_root = &mut root.clone();
4693 let mut_level1 = chained.get_mut(mut_root);
4694 assert!(mut_level1.is_some());
4695 mut_level1.unwrap().nested.count = 99;
4696 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4697 }
4698
4699 #[test]
4700 fn test_kp_then_lock_with_enum() {
4701 use std::sync::{Arc, Mutex};
4702
4703 #[derive(Clone)]
4704 enum Message {
4705 Request(LevelA),
4706 Response(i32),
4707 }
4708 #[derive(Clone)]
4709 struct LevelA {
4710 data: Arc<Mutex<i32>>,
4711 }
4712
4713 struct RootWithEnum {
4714 msg: Arc<Mutex<Message>>,
4715 }
4716
4717 let root = RootWithEnum {
4718 msg: Arc::new(Mutex::new(Message::Request(LevelA {
4719 data: Arc::new(Mutex::new(100)),
4720 }))),
4721 };
4722
4723 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
4724 Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
4725
4726 let lock_kp_msg = {
4727 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
4728 Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
4729 let next: KpType<Message, Message> =
4730 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4731 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4732 };
4733
4734 let chained = kp_msg.then_lock(lock_kp_msg);
4735 let msg = chained.get(&root);
4736 assert!(msg.is_some());
4737 match msg.unwrap() {
4738 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
4739 Message::Response(_) => panic!("expected Request"),
4740 }
4741 }
4742
4743 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4744 #[tokio::test]
4745 async fn test_kp_then_async_deep_chain() {
4746 use std::sync::Arc;
4747 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4748
4749 #[derive(Clone)]
4750 struct Root {
4751 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
4752 }
4753 #[derive(Clone)]
4754 struct Level1 {
4755 value: i32,
4756 }
4757
4758 let root = Root {
4759 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
4760 };
4761
4762 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
4763 |r: &Root| Some(&r.tokio_guard),
4764 |r: &mut Root| Some(&mut r.tokio_guard),
4765 );
4766
4767 let async_kp = {
4768 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
4769 Kp::new(
4770 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
4771 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
4772 );
4773 let next: KpType<Level1, Level1> =
4774 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4775 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4776 };
4777
4778 let chained = kp_to_guard.then_async(async_kp);
4779 let level1 = chained.get(&root).await;
4780 assert!(level1.is_some());
4781 assert_eq!(level1.unwrap().value, 7);
4782 }
4783
4784 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4787 #[tokio::test]
4788 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
4789 use std::sync::{Arc, Mutex};
4790 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4791 use crate::lock::{LockKp, ArcMutexAccess};
4792
4793 #[derive(Clone)]
4795 struct Root {
4796 sync_mutex: Arc<Mutex<Level1>>,
4797 }
4798 #[derive(Clone)]
4800 struct Level1 {
4801 inner: Level2,
4802 }
4803 #[derive(Clone)]
4805 struct Level2 {
4806 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
4807 }
4808 #[derive(Clone)]
4810 struct Level3 {
4811 leaf: i32,
4812 }
4813
4814 let mut root = Root {
4815 sync_mutex: Arc::new(Mutex::new(Level1 {
4816 inner: Level2 {
4817 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
4818 },
4819 })),
4820 };
4821
4822 let identity_l1: KpType<Level1, Level1> =
4824 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4825 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
4826 Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
4827 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
4828
4829 let kp_l1_inner: KpType<Level1, Level2> =
4831 Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
4832
4833 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
4835 |l: &Level2| Some(&l.tokio_mutex),
4836 |l: &mut Level2| Some(&mut l.tokio_mutex),
4837 );
4838
4839 let async_l3 = {
4841 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
4842 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
4843 let next: KpType<Level3, Level3> =
4844 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
4845 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4846 };
4847
4848 let kp_l3_leaf: KpType<Level3, i32> =
4850 Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
4851
4852 let step1 = lock_root_to_l1.then(kp_l1_inner);
4854 let step2 = step1.then(kp_l2_tokio);
4855 let step3 = step2.then_async(async_l3);
4856 let deep_chain = step3.then(kp_l3_leaf);
4857
4858 let leaf = deep_chain.get(&root).await;
4860 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
4861 assert_eq!(leaf, Some(&100));
4862
4863 let mut root_mut = root.clone();
4865 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
4866 assert!(leaf_mut.is_some());
4867 *leaf_mut.unwrap() = 99;
4868
4869 let leaf_after = deep_chain.get(&root_mut).await;
4871 assert_eq!(leaf_after, Some(&99));
4872 }
4873}