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
31
32
33#[cfg(feature = "pin_project")]
78pub mod pin;
79
80pub trait KeyPathValueTarget {
84 type Target: Sized;
85}
86impl<T> KeyPathValueTarget for &T {
87 type Target = T;
88}
89impl<T> KeyPathValueTarget for &mut T {
90 type Target = T;
91}
92
93#[macro_export]
95macro_rules! keypath {
96 { $root:ident . $field:ident } => { $root::$field() };
97 { $root:ident . $field:ident . $($ty:ident . $f:ident).+ } => {
98 $root::$field() $(.then($ty::$f()))+
99 };
100 ($root:ident . $field:ident) => { $root::$field() };
101 ($root:ident . $field:ident . $($ty:ident . $f:ident).+) => {
102 $root::$field() $(.then($ty::$f()))+
103 };
104}
105
106#[macro_export]
110macro_rules! get_or {
111 ($kp:expr, $root:expr, $default:expr) => {
112 $kp.get($root).unwrap_or($default)
113 };
114 ($root:expr => $($path:tt)*, $default:expr) => {
115 $crate::get_or!($crate::keypath!($($path)*), $root, $default)
116 };
117}
118
119#[macro_export]
124macro_rules! get_or_else {
125 ($kp:expr, $root:expr, $closure:expr) => {
126 $kp.get($root).map(|r| r.clone()).unwrap_or_else($closure)
127 };
128 ($root:expr => ($($path:tt)*), $closure:expr) => {
129 $crate::get_or_else!($crate::keypath!($($path)*), $root, $closure)
130 };
131}
132pub type KpValue<'a, R, V> = Kp<
133 R,
134 V,
135 &'a R,
136 V, &'a mut R,
138 V, for<'b> fn(&'b R) -> Option<V>,
140 for<'b> fn(&'b mut R) -> Option<V>,
141>;
142
143pub type KpDynamic<R, V> = Kp<
144 R,
145 V,
146 &'static R,
147 &'static V,
148 &'static mut R,
149 &'static mut V,
150 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
151 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
152>;
153
154pub type KpBox<'a, R, V> = Kp<
155R, V,
156&'a R, &'a V,
157&'a mut R, &'a mut V,
158Box<dyn Fn(&'a R) -> Option<&'a V> + 'a>,
159Box<dyn Fn(&'a mut R) -> Option<&'a mut V> + 'a>,
160>;
161
162pub type KpArc<'a, R, V> = Kp<
163 R, V,
164 &'a R, &'a V,
165 &'a mut R, &'a mut V,
166 Arc<dyn Fn(&'a R) -> Option<&'a V> + Send + Sync + 'a>,
167 Arc<dyn Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync + 'a>,
168>;
169
170
171pub type KpType<'a, R, V> = Kp<
172 R,
173 V,
174 &'a R,
175 &'a V,
176 &'a mut R,
177 &'a mut V,
178 for<'b> fn(&'b R) -> Option<&'b V>,
179 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
180>;
181
182pub type KpOptionRefCellType<'a, R, V> = Kp<
185 R,
186 V,
187 &'a R,
188 std::cell::Ref<'a, V>,
189 &'a mut R,
190 std::cell::RefMut<'a, V>,
191 for<'b> fn(&'b R) -> Option<std::cell::Ref<'b, V>>,
192 for<'b> fn(&'b mut R) -> Option<std::cell::RefMut<'b, V>>,
193>;
194
195impl<'a, R, V> KpType<'a, R, V>
196where
197 'a: 'static,
198{
199 #[inline]
202 pub fn to_dynamic(self) -> KpDynamic<R, V> {
203 self.into()
204 }
205}
206
207impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V>
208where
209 'a: 'static,
210 R: 'static,
211 V: 'static,
212{
213 #[inline]
214 fn from(kp: KpType<'a, R, V>) -> Self {
215 let get_fn = kp.get;
216 let set_fn = kp.set;
217 Kp::new(
218 Box::new(move |t: &R| get_fn(t)),
219 Box::new(move |t: &mut R| set_fn(t)),
220 )
221 }
222}
223
224pub type KpComposed<R, V> = Kp<
260 R,
261 V,
262 &'static R,
263 &'static V,
264 &'static mut R,
265 &'static mut V,
266 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
267 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
268>;
269
270impl<R, V> Kp<
271 R,
272 V,
273 &'static R,
274 &'static V,
275 &'static mut R,
276 &'static mut V,
277 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
278 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
279> {
280 pub fn from_closures<G, S>(get: G, set: S) -> Self
283 where
284 G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
285 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
286 {
287 Self::new(Box::new(get), Box::new(set))
288 }
289}
290
291pub struct AKp {
292 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
293 root_type_id: TypeId,
294 value_type_id: TypeId,
295}
296
297impl AKp {
298 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
300 where
301 R: Any + 'static,
302 V: Any + 'static,
303 {
304 let root_type_id = TypeId::of::<R>();
305 let value_type_id = TypeId::of::<V>();
306 let getter_fn = keypath.get;
307
308 Self {
309 getter: Rc::new(move |any: &dyn Any| {
310 if let Some(root) = any.downcast_ref::<R>() {
311 getter_fn(root).map(|value: &V| value as &dyn Any)
312 } else {
313 None
314 }
315 }),
316 root_type_id,
317 value_type_id,
318 }
319 }
320
321 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
323 where
324 R: Any + 'static,
325 V: Any + 'static,
326 {
327 Self::new(keypath)
328 }
329
330 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
332 (self.getter)(root)
333 }
334
335 pub fn root_type_id(&self) -> TypeId {
337 self.root_type_id
338 }
339
340 pub fn value_type_id(&self) -> TypeId {
342 self.value_type_id
343 }
344
345 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
347 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
348 {
349 Some(
350 self.get(root as &dyn Any)
351 .and_then(|any| any.downcast_ref::<Value>()),
352 )
353 } else {
354 None
355 }
356 }
357
358 pub fn kind_name(&self) -> String {
360 format!("{:?}", self.value_type_id)
361 }
362
363 pub fn root_kind_name(&self) -> String {
365 format!("{:?}", self.root_type_id)
366 }
367
368 pub fn for_arc<Root>(&self) -> AKp
370 where
371 Root: Any + 'static,
372 {
373 let value_type_id = self.value_type_id;
374 let getter = self.getter.clone();
375
376 AKp {
377 getter: Rc::new(move |any: &dyn Any| {
378 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
379 getter(arc.as_ref() as &dyn Any)
380 } else {
381 None
382 }
383 }),
384 root_type_id: TypeId::of::<Arc<Root>>(),
385 value_type_id,
386 }
387 }
388
389 pub fn for_box<Root>(&self) -> AKp
391 where
392 Root: Any + 'static,
393 {
394 let value_type_id = self.value_type_id;
395 let getter = self.getter.clone();
396
397 AKp {
398 getter: Rc::new(move |any: &dyn Any| {
399 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
400 getter(boxed.as_ref() as &dyn Any)
401 } else {
402 None
403 }
404 }),
405 root_type_id: TypeId::of::<Box<Root>>(),
406 value_type_id,
407 }
408 }
409
410 pub fn for_rc<Root>(&self) -> AKp
412 where
413 Root: Any + 'static,
414 {
415 let value_type_id = self.value_type_id;
416 let getter = self.getter.clone();
417
418 AKp {
419 getter: Rc::new(move |any: &dyn Any| {
420 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
421 getter(rc.as_ref() as &dyn Any)
422 } else {
423 None
424 }
425 }),
426 root_type_id: TypeId::of::<Rc<Root>>(),
427 value_type_id,
428 }
429 }
430
431 pub fn for_option<Root>(&self) -> AKp
433 where
434 Root: Any + 'static,
435 {
436 let value_type_id = self.value_type_id;
437 let getter = self.getter.clone();
438
439 AKp {
440 getter: Rc::new(move |any: &dyn Any| {
441 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
442 opt.as_ref().and_then(|root| getter(root as &dyn Any))
443 } else {
444 None
445 }
446 }),
447 root_type_id: TypeId::of::<Option<Root>>(),
448 value_type_id,
449 }
450 }
451
452 pub fn for_result<Root, E>(&self) -> AKp
454 where
455 Root: Any + 'static,
456 E: Any + 'static,
457 {
458 let value_type_id = self.value_type_id;
459 let getter = self.getter.clone();
460
461 AKp {
462 getter: Rc::new(move |any: &dyn Any| {
463 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
464 result
465 .as_ref()
466 .ok()
467 .and_then(|root| getter(root as &dyn Any))
468 } else {
469 None
470 }
471 }),
472 root_type_id: TypeId::of::<Result<Root, E>>(),
473 value_type_id,
474 }
475 }
476
477 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
490 where
491 Root: Any + 'static,
492 OrigValue: Any + 'static,
493 MappedValue: Any + 'static,
494 F: Fn(&OrigValue) -> MappedValue + 'static,
495 {
496 let orig_root_type_id = self.root_type_id;
497 let orig_value_type_id = self.value_type_id;
498 let getter = self.getter.clone();
499 let mapped_type_id = TypeId::of::<MappedValue>();
500
501 AKp {
502 getter: Rc::new(move |any_root: &dyn Any| {
503 if any_root.type_id() == orig_root_type_id {
505 getter(any_root).and_then(|any_value| {
506 if orig_value_type_id == TypeId::of::<OrigValue>() {
508 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
509 let mapped = mapper(orig_val);
510 Box::leak(Box::new(mapped)) as &dyn Any
512 })
513 } else {
514 None
515 }
516 })
517 } else {
518 None
519 }
520 }),
521 root_type_id: orig_root_type_id,
522 value_type_id: mapped_type_id,
523 }
524 }
525
526 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
539 where
540 Root: Any + 'static,
541 Value: Any + 'static,
542 F: Fn(&Value) -> bool + 'static,
543 {
544 let orig_root_type_id = self.root_type_id;
545 let orig_value_type_id = self.value_type_id;
546 let getter = self.getter.clone();
547
548 AKp {
549 getter: Rc::new(move |any_root: &dyn Any| {
550 if any_root.type_id() == orig_root_type_id {
552 getter(any_root).filter(|any_value| {
553 if orig_value_type_id == TypeId::of::<Value>() {
555 any_value
556 .downcast_ref::<Value>()
557 .map(|val| predicate(val))
558 .unwrap_or(false)
559 } else {
560 false
561 }
562 })
563 } else {
564 None
565 }
566 }),
567 root_type_id: orig_root_type_id,
568 value_type_id: orig_value_type_id,
569 }
570 }
571}
572pub struct PKp<Root> {
573 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
574 value_type_id: TypeId,
575 _phantom: std::marker::PhantomData<Root>,
576}
577
578impl<Root> PKp<Root>
579where
580 Root: 'static,
581{
582 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
584 where
585 V: Any + 'static,
586 {
587 let value_type_id = TypeId::of::<V>();
588 let getter_fn = keypath.get;
589
590 Self {
591 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
592 value_type_id,
593 _phantom: std::marker::PhantomData,
594 }
595 }
596
597 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
599 where
600 V: Any + 'static,
601 {
602 Self::new(keypath)
603 }
604
605 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
607 (self.getter)(root)
608 }
609
610 pub fn value_type_id(&self) -> TypeId {
612 self.value_type_id
613 }
614
615 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
617 if self.value_type_id == TypeId::of::<Value>() {
618 self.get(root).and_then(|any| any.downcast_ref::<Value>())
619 } else {
620 None
621 }
622 }
623
624 pub fn kind_name(&self) -> String {
626 format!("{:?}", self.value_type_id)
627 }
628
629 pub fn for_arc(&self) -> PKp<Arc<Root>> {
631 let getter = self.getter.clone();
632 let value_type_id = self.value_type_id;
633
634 PKp {
635 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
636 value_type_id,
637 _phantom: std::marker::PhantomData,
638 }
639 }
640
641 pub fn for_box(&self) -> PKp<Box<Root>> {
643 let getter = self.getter.clone();
644 let value_type_id = self.value_type_id;
645
646 PKp {
647 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
648 value_type_id,
649 _phantom: std::marker::PhantomData,
650 }
651 }
652
653 pub fn for_rc(&self) -> PKp<Rc<Root>> {
655 let getter = self.getter.clone();
656 let value_type_id = self.value_type_id;
657
658 PKp {
659 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
660 value_type_id,
661 _phantom: std::marker::PhantomData,
662 }
663 }
664
665 pub fn for_option(&self) -> PKp<Option<Root>> {
667 let getter = self.getter.clone();
668 let value_type_id = self.value_type_id;
669
670 PKp {
671 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
672 value_type_id,
673 _phantom: std::marker::PhantomData,
674 }
675 }
676
677 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
679 where
680 E: 'static,
681 {
682 let getter = self.getter.clone();
683 let value_type_id = self.value_type_id;
684
685 PKp {
686 getter: Rc::new(move |result: &Result<Root, E>| {
687 result.as_ref().ok().and_then(|root| getter(root))
688 }),
689 value_type_id,
690 _phantom: std::marker::PhantomData,
691 }
692 }
693
694 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
708 where
709 OrigValue: Any + 'static,
710 MappedValue: Any + 'static,
711 F: Fn(&OrigValue) -> MappedValue + 'static,
712 {
713 let orig_type_id = self.value_type_id;
714 let getter = self.getter.clone();
715 let mapped_type_id = TypeId::of::<MappedValue>();
716
717 PKp {
718 getter: Rc::new(move |root: &Root| {
719 getter(root).and_then(|any_value| {
720 if orig_type_id == TypeId::of::<OrigValue>() {
722 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
723 let mapped = mapper(orig_val);
724 Box::leak(Box::new(mapped)) as &dyn Any
727 })
728 } else {
729 None
730 }
731 })
732 }),
733 value_type_id: mapped_type_id,
734 _phantom: std::marker::PhantomData,
735 }
736 }
737
738 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
752 where
753 Value: Any + 'static,
754 F: Fn(&Value) -> bool + 'static,
755 {
756 let orig_type_id = self.value_type_id;
757 let getter = self.getter.clone();
758
759 PKp {
760 getter: Rc::new(move |root: &Root| {
761 getter(root).filter(|any_value| {
762 if orig_type_id == TypeId::of::<Value>() {
764 any_value
765 .downcast_ref::<Value>()
766 .map(|val| predicate(val))
767 .unwrap_or(false)
768 } else {
769 false
770 }
771 })
772 }),
773 value_type_id: orig_type_id,
774 _phantom: std::marker::PhantomData,
775 }
776 }
777}
778
779#[derive(Clone)]
793pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
794where
795 Root: std::borrow::Borrow<R>,
796 MutRoot: std::borrow::BorrowMut<R>,
797 MutValue: std::borrow::BorrowMut<V>,
798 G: Fn(Root) -> Option<Value>,
799 S: Fn(MutRoot) -> Option<MutValue>,
800{
801 pub(crate) get: G,
803 pub(crate) set: S,
805 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
806}
807
808unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Send for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
810where
811 Root: std::borrow::Borrow<R>,
812 MutRoot: std::borrow::BorrowMut<R>,
813 MutValue: std::borrow::BorrowMut<V>,
814 G: Fn(Root) -> Option<Value> + Send,
815 S: Fn(MutRoot) -> Option<MutValue> + Send,
816{
817}
818unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Sync for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
819where
820 Root: std::borrow::Borrow<R>,
821 MutRoot: std::borrow::BorrowMut<R>,
822 MutValue: std::borrow::BorrowMut<V>,
823 G: Fn(Root) -> Option<Value> + Sync,
824 S: Fn(MutRoot) -> Option<MutValue> + Sync,
825{
826}
827
828impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
829where
830 Root: std::borrow::Borrow<R>,
831 Value: std::borrow::Borrow<V>,
832 MutRoot: std::borrow::BorrowMut<R>,
833 MutValue: std::borrow::BorrowMut<V>,
834 G: Fn(Root) -> Option<Value>,
835 S: Fn(MutRoot) -> Option<MutValue>,
836{
837 pub fn new(get: G, set: S) -> Self {
838 Self {
839 get: get,
840 set: set,
841 _p: std::marker::PhantomData,
842 }
843 }
844
845 pub const fn new_const(get: G, set: S) -> Self {
846 Self {
847 get: get,
848 set: set,
849 _p: std::marker::PhantomData,
850 }
851 }
852
853
854 #[inline]
855 pub fn get(&self, root: Root) -> Option<Value> {
856 (self.get)(root)
857 }
858 #[inline]
859 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
860 (self.set)(root)
861 }
862
863 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
864 self,
865 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
866 ) -> Kp<
867 R,
868 SV,
869 Root,
870 SubValue,
871 MutRoot,
872 MutSubValue,
873 impl Fn(Root) -> Option<SubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
874 impl Fn(MutRoot) -> Option<MutSubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
875 >
876 where
877 SubValue: std::borrow::Borrow<SV>,
878 MutSubValue: std::borrow::BorrowMut<SV>,
879 G2: Fn(Value) -> Option<SubValue>,
880 S2: Fn(MutValue) -> Option<MutSubValue>,
881 V: 'static,
882 {
883 Kp::new(
884 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
885 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
886 )
887 }
888
889 pub fn then_lock<
891 Lock,
892 Mid,
893 V2,
894 LockValue,
895 MidValue,
896 Value2,
897 MutLock,
898 MutMid,
899 MutValue2,
900 G1,
901 S1,
902 L,
903 G2,
904 S2,
905 >(
906 self,
907 lock_kp: crate::lock::LockKp<
908 V,
909 Lock,
910 Mid,
911 V2,
912 Value,
913 LockValue,
914 MidValue,
915 Value2,
916 MutValue,
917 MutLock,
918 MutMid,
919 MutValue2,
920 G1,
921 S1,
922 L,
923 G2,
924 S2,
925 >,
926 ) -> 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>>
927 where
928 V: 'static + Clone,
929 V2: 'static,
930 Value: std::borrow::Borrow<V>,
931 Value2: std::borrow::Borrow<V2>,
932 MutValue: std::borrow::BorrowMut<V>,
933 MutValue2: std::borrow::BorrowMut<V2>,
934 LockValue: std::borrow::Borrow<Lock>,
935 MidValue: std::borrow::Borrow<Mid>,
936 MutLock: std::borrow::BorrowMut<Lock>,
937 MutMid: std::borrow::BorrowMut<Mid>,
938 G1: Fn(Value) -> Option<LockValue>,
939 S1: Fn(MutValue) -> Option<MutLock>,
940 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
941 G2: Fn(MidValue) -> Option<Value2>,
942 S2: Fn(MutMid) -> Option<MutValue2>,
943 {
944 crate::lock::KpThenLockKp {
945 first: self,
946 second: lock_kp,
947 _p: std::marker::PhantomData,
948 }
949 }
950
951 #[cfg(feature = "pin_project")]
954 pub fn then_pin_future<Struct, Output, L>(
955 self,
956 pin_fut: L,
957 ) -> crate::pin::KpThenPinFuture<
958 R,
959 Struct,
960 Output,
961 Root,
962 MutRoot,
963 Value,
964 MutValue,
965 Self,
966 L,
967 >
968 where
969 V: 'static,
970 Struct: Unpin + 'static,
971 Output: 'static,
972 Value: std::borrow::Borrow<Struct>,
973 MutValue: std::borrow::BorrowMut<Struct>,
974 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
975 {
976 crate::pin::KpThenPinFuture {
977 first: self,
978 second: pin_fut,
979 _p: std::marker::PhantomData,
980 }
981 }
982
983 pub fn then_async<AsyncKp>(
986 self,
987 async_kp: AsyncKp,
988 ) -> crate::async_lock::KpThenAsyncKeyPath<
989 R,
990 V,
991 <AsyncKp::Value as KeyPathValueTarget>::Target,
992 Root,
993 Value,
994 AsyncKp::Value,
995 MutRoot,
996 MutValue,
997 AsyncKp::MutValue,
998 Self,
999 AsyncKp,
1000 >
1001 where
1002 V: 'static,
1003 Value: std::borrow::Borrow<V>,
1004 MutValue: std::borrow::BorrowMut<V>,
1005 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
1006 AsyncKp::Value: KeyPathValueTarget
1007 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1008 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1009 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
1010 {
1011 crate::async_lock::KpThenAsyncKeyPath {
1012 first: self,
1013 second: async_kp,
1014 _p: std::marker::PhantomData,
1015 }
1016 }
1017
1018 pub fn map<MappedValue, F>(
1031 &self,
1032 mapper: F,
1033 ) -> Kp<
1034 R,
1035 MappedValue,
1036 Root,
1037 MappedValue,
1038 MutRoot,
1039 MappedValue,
1040 impl Fn(Root) -> Option<MappedValue>,
1041 impl Fn(MutRoot) -> Option<MappedValue>,
1042 >
1043 where
1044 F: Fn(&V) -> MappedValue + Copy + 'static,
1047 V: 'static,
1048 MappedValue: 'static,
1049 {
1050 Kp::new(
1051 move |root: Root| {
1052 (&self.get)(root).map(|value| {
1053 let v: &V = value.borrow();
1054 mapper(v)
1055 })
1056 },
1057 move |root: MutRoot| {
1058 (&self.set)(root).map(|value| {
1059 let v: &V = value.borrow();
1060 mapper(v)
1061 })
1062 },
1063 )
1064 }
1065
1066 pub fn filter<F>(
1079 &self,
1080 predicate: F,
1081 ) -> Kp<
1082 R,
1083 V,
1084 Root,
1085 Value,
1086 MutRoot,
1087 MutValue,
1088 impl Fn(Root) -> Option<Value>,
1089 impl Fn(MutRoot) -> Option<MutValue>,
1090 >
1091 where
1092 F: Fn(&V) -> bool + Copy + 'static,
1095 V: 'static,
1096 {
1097 Kp::new(
1098 move |root: Root| {
1099 (&self.get)(root).filter(|value| {
1100 let v: &V = value.borrow();
1101 predicate(v)
1102 })
1103 },
1104 move |root: MutRoot| {
1105 (&self.set)(root).filter(|value| {
1106 let v: &V = value.borrow();
1107 predicate(v)
1108 })
1109 },
1110 )
1111 }
1112
1113 pub fn filter_map<MappedValue, F>(
1126 &self,
1127 mapper: F,
1128 ) -> Kp<
1129 R,
1130 MappedValue,
1131 Root,
1132 MappedValue,
1133 MutRoot,
1134 MappedValue,
1135 impl Fn(Root) -> Option<MappedValue>,
1136 impl Fn(MutRoot) -> Option<MappedValue>,
1137 >
1138 where
1139 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1142 V: 'static,
1143 MappedValue: 'static,
1144 {
1145 Kp::new(
1146 move |root: Root| {
1147 (&self.get)(root).and_then(|value| {
1148 let v: &V = value.borrow();
1149 mapper(v)
1150 })
1151 },
1152 move |root: MutRoot| {
1153 (&self.set)(root).and_then(|value| {
1154 let v: &V = value.borrow();
1155 mapper(v)
1156 })
1157 },
1158 )
1159 }
1160
1161 pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
1173 where
1174 F: Fn(&V) -> I + 'static,
1177 V: 'static,
1178 I: IntoIterator<Item = Item>,
1179 Item: 'static,
1180 {
1181 move |root: Root| {
1182 (&self.get)(root)
1183 .map(|value| {
1184 let v: &V = value.borrow();
1185 mapper(v).into_iter().collect()
1186 })
1187 .unwrap_or_else(Vec::new)
1188 }
1189 }
1190
1191 pub fn inspect<F>(
1202 &self,
1203 inspector: F,
1204 ) -> Kp<
1205 R,
1206 V,
1207 Root,
1208 Value,
1209 MutRoot,
1210 MutValue,
1211 impl Fn(Root) -> Option<Value>,
1212 impl Fn(MutRoot) -> Option<MutValue>,
1213 >
1214 where
1215 F: Fn(&V) + Copy + 'static,
1218 V: 'static,
1219 {
1220 Kp::new(
1221 move |root: Root| {
1222 (&self.get)(root).map(|value| {
1223 let v: &V = value.borrow();
1224 inspector(v);
1225 value
1226 })
1227 },
1228 move |root: MutRoot| {
1229 (&self.set)(root).map(|value| {
1230 let v: &V = value.borrow();
1231 inspector(v);
1232 value
1233 })
1234 },
1235 )
1236 }
1237
1238 pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
1252 where
1253 F: Fn(Acc, &V) -> Acc + 'static,
1256 V: 'static,
1257 Acc: Copy + 'static,
1259 {
1260 move |root: Root| {
1261 (&self.get)(root)
1262 .map(|value| {
1263 let v: &V = value.borrow();
1264 folder(init, v)
1265 })
1266 .unwrap_or(init)
1267 }
1268 }
1269
1270 pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1282 where
1283 F: Fn(&V) -> bool + 'static,
1286 V: 'static,
1287 {
1288 move |root: Root| {
1289 (&self.get)(root)
1290 .map(|value| {
1291 let v: &V = value.borrow();
1292 predicate(v)
1293 })
1294 .unwrap_or(false)
1295 }
1296 }
1297
1298 pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1310 where
1311 F: Fn(&V) -> bool + 'static,
1314 V: 'static,
1315 {
1316 move |root: Root| {
1317 (&self.get)(root)
1318 .map(|value| {
1319 let v: &V = value.borrow();
1320 predicate(v)
1321 })
1322 .unwrap_or(true)
1323 }
1324 }
1325
1326 pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
1338 where
1339 F: Fn(&V) -> usize + 'static,
1342 V: 'static,
1343 {
1344 move |root: Root| {
1345 (&self.get)(root).map(|value| {
1346 let v: &V = value.borrow();
1347 counter(v)
1348 })
1349 }
1350 }
1351
1352 pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
1366 where
1367 F: Fn(&V) -> Option<Item> + 'static,
1370 V: 'static,
1371 Item: 'static,
1372 {
1373 move |root: Root| {
1374 (&self.get)(root).and_then(|value| {
1375 let v: &V = value.borrow();
1376 finder(v)
1377 })
1378 }
1379 }
1380
1381 pub fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output>
1392 where
1393 F: Fn(&V, usize) -> Output + 'static,
1396 V: 'static,
1397 Output: 'static,
1398 {
1399 move |root: Root| {
1400 (&self.get)(root).map(|value| {
1401 let v: &V = value.borrow();
1402 taker(v, n)
1403 })
1404 }
1405 }
1406
1407 pub fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output>
1418 where
1419 F: Fn(&V, usize) -> Output + 'static,
1422 V: 'static,
1423 Output: 'static,
1424 {
1425 move |root: Root| {
1426 (&self.get)(root).map(|value| {
1427 let v: &V = value.borrow();
1428 skipper(v, n)
1429 })
1430 }
1431 }
1432
1433 pub fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output>
1446 where
1447 F: Fn(&V) -> Output + 'static,
1450 V: 'static,
1451 Output: 'static,
1452 {
1453 move |root: Root| {
1454 (&self.get)(root).map(|value| {
1455 let v: &V = value.borrow();
1456 partitioner(v)
1457 })
1458 }
1459 }
1460
1461 pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
1473 where
1474 F: Fn(&V) -> Option<Item> + 'static,
1477 V: 'static,
1478 Item: 'static,
1479 {
1480 move |root: Root| {
1481 (&self.get)(root).and_then(|value| {
1482 let v: &V = value.borrow();
1483 min_fn(v)
1484 })
1485 }
1486 }
1487
1488 pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
1500 where
1501 F: Fn(&V) -> Option<Item> + 'static,
1504 V: 'static,
1505 Item: 'static,
1506 {
1507 move |root: Root| {
1508 (&self.get)(root).and_then(|value| {
1509 let v: &V = value.borrow();
1510 max_fn(v)
1511 })
1512 }
1513 }
1514
1515 pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
1527 where
1528 F: Fn(&V) -> Sum + 'static,
1531 V: 'static,
1532 Sum: 'static,
1533 {
1534 move |root: Root| {
1535 (&self.get)(root).map(|value| {
1536 let v: &V = value.borrow();
1537 sum_fn(v)
1538 })
1539 }
1540 }
1541
1542 pub fn chain<SV, SubValue, MutSubValue, G2, S2>(
1545 self,
1546 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1547 ) -> Kp<
1548 R,
1549 SV,
1550 Root,
1551 SubValue,
1552 MutRoot,
1553 MutSubValue,
1554 impl Fn(Root) -> Option<SubValue>,
1555 impl Fn(MutRoot) -> Option<MutSubValue>,
1556 >
1557 where
1558 SubValue: std::borrow::Borrow<SV>,
1559 MutSubValue: std::borrow::BorrowMut<SV>,
1560 G2: Fn(Value) -> Option<SubValue>,
1561 S2: Fn(MutValue) -> Option<MutSubValue>,
1562 V: 'static,
1563 {
1564 self.then(next)
1565 }
1566
1567 pub fn for_arc<'b>(
1568 &self,
1569 ) -> Kp<
1570 std::sync::Arc<R>,
1571 V,
1572 std::sync::Arc<R>,
1573 Value,
1574 std::sync::Arc<R>,
1575 MutValue,
1576 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1577 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1578 >
1579 where
1580 R: 'b,
1581 V: 'b,
1582 Root: for<'a> From<&'a R>,
1583 MutRoot: for<'a> From<&'a mut R>,
1584 {
1585 Kp::new(
1586 move |arc_root: std::sync::Arc<R>| {
1587 let r_ref: &R = &*arc_root;
1588 (&self.get)(Root::from(r_ref))
1589 },
1590 move |mut arc_root: std::sync::Arc<R>| {
1591 std::sync::Arc::get_mut(&mut arc_root)
1593 .and_then(|r_mut| (&self.set)(MutRoot::from(r_mut)))
1594 },
1595 )
1596 }
1597
1598 pub fn for_box<'a>(
1599 &self,
1600 ) -> Kp<
1601 Box<R>,
1602 V,
1603 Box<R>,
1604 Value,
1605 Box<R>,
1606 MutValue,
1607 impl Fn(Box<R>) -> Option<Value>,
1608 impl Fn(Box<R>) -> Option<MutValue>,
1609 >
1610 where
1611 R: 'a,
1612 V: 'a,
1613 Root: for<'b> From<&'b R>,
1614 MutRoot: for<'b> From<&'b mut R>,
1615 {
1616 Kp::new(
1617 move |r: Box<R>| {
1618 let r_ref: &R = r.as_ref();
1619 (&self.get)(Root::from(r_ref))
1620 },
1621 move |mut r: Box<R>| {
1622 (self.set)(MutRoot::from(r.as_mut()))
1624 },
1625 )
1626 }
1627}
1628
1629pub fn zip_kps<'a, RootType, Value1, Value2>(
1643 kp1: &'a KpType<'a, RootType, Value1>,
1644 kp2: &'a KpType<'a, RootType, Value2>,
1645) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1646where
1647 RootType: 'a,
1648 Value1: 'a,
1649 Value2: 'a,
1650{
1651 move |root: &'a RootType| {
1652 let val1 = (kp1.get)(root)?;
1653 let val2 = (kp2.get)(root)?;
1654 Some((val1, val2))
1655 }
1656}
1657
1658impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1659where
1660 Root: std::borrow::Borrow<R>,
1661 MutRoot: std::borrow::BorrowMut<R>,
1662 G: Fn(Root) -> Option<Root>,
1663 S: Fn(MutRoot) -> Option<MutRoot>,
1664{
1665 pub fn identity_typed() -> Kp<
1666 R,
1667 R,
1668 Root,
1669 Root,
1670 MutRoot,
1671 MutRoot,
1672 fn(Root) -> Option<Root>,
1673 fn(MutRoot) -> Option<MutRoot>,
1674 > {
1675 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1676 }
1677
1678 pub fn identity<'a>() -> KpType<'a, R, R> {
1679 KpType::new(|r| Some(r), |r| Some(r))
1680 }
1681}
1682
1683pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1692where
1693 Root: std::borrow::Borrow<Enum>,
1694 Value: std::borrow::Borrow<Variant>,
1695 MutRoot: std::borrow::BorrowMut<Enum>,
1696 MutValue: std::borrow::BorrowMut<Variant>,
1697 G: Fn(Root) -> Option<Value>,
1698 S: Fn(MutRoot) -> Option<MutValue>,
1699 E: Fn(Variant) -> Enum,
1700{
1701 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1702 embedder: E,
1703}
1704
1705unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1707 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1708where
1709 Root: std::borrow::Borrow<Enum>,
1710 Value: std::borrow::Borrow<Variant>,
1711 MutRoot: std::borrow::BorrowMut<Enum>,
1712 MutValue: std::borrow::BorrowMut<Variant>,
1713 G: Fn(Root) -> Option<Value> + Send,
1714 S: Fn(MutRoot) -> Option<MutValue> + Send,
1715 E: Fn(Variant) -> Enum + Send,
1716{
1717}
1718unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1719 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1720where
1721 Root: std::borrow::Borrow<Enum>,
1722 Value: std::borrow::Borrow<Variant>,
1723 MutRoot: std::borrow::BorrowMut<Enum>,
1724 MutValue: std::borrow::BorrowMut<Variant>,
1725 G: Fn(Root) -> Option<Value> + Sync,
1726 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1727 E: Fn(Variant) -> Enum + Sync,
1728{
1729}
1730
1731impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1732 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1733where
1734 Root: std::borrow::Borrow<Enum>,
1735 Value: std::borrow::Borrow<Variant>,
1736 MutRoot: std::borrow::BorrowMut<Enum>,
1737 MutValue: std::borrow::BorrowMut<Variant>,
1738 G: Fn(Root) -> Option<Value>,
1739 S: Fn(MutRoot) -> Option<MutValue>,
1740 E: Fn(Variant) -> Enum,
1741{
1742 pub fn new(
1744 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1745 embedder: E,
1746 ) -> Self {
1747 Self {
1748 extractor,
1749 embedder,
1750 }
1751 }
1752
1753 pub fn get(&self, enum_value: Root) -> Option<Value> {
1755 self.extractor.get(enum_value)
1756 }
1757
1758 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1760 self.extractor.get_mut(enum_value)
1761 }
1762
1763 pub fn embed(&self, value: Variant) -> Enum {
1765 (self.embedder)(value)
1766 }
1767
1768 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1770 &self.extractor
1771 }
1772
1773 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1775 self.extractor
1776 }
1777
1778 pub fn map<MappedValue, F>(
1789 &self,
1790 mapper: F,
1791 ) -> EnumKp<
1792 Enum,
1793 MappedValue,
1794 Root,
1795 MappedValue,
1796 MutRoot,
1797 MappedValue,
1798 impl Fn(Root) -> Option<MappedValue>,
1799 impl Fn(MutRoot) -> Option<MappedValue>,
1800 impl Fn(MappedValue) -> Enum,
1801 >
1802 where
1803 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1806 Variant: 'static,
1807 MappedValue: 'static,
1808 E: Fn(Variant) -> Enum + Copy + 'static,
1810 {
1811 let mapped_extractor = self.extractor.map(mapper);
1812
1813 let new_embedder = move |_value: MappedValue| -> Enum {
1817 panic!(
1818 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1819 )
1820 };
1821
1822 EnumKp::new(mapped_extractor, new_embedder)
1823 }
1824
1825 pub fn filter<F>(
1837 &self,
1838 predicate: F,
1839 ) -> EnumKp<
1840 Enum,
1841 Variant,
1842 Root,
1843 Value,
1844 MutRoot,
1845 MutValue,
1846 impl Fn(Root) -> Option<Value>,
1847 impl Fn(MutRoot) -> Option<MutValue>,
1848 E,
1849 >
1850 where
1851 F: Fn(&Variant) -> bool + Copy + 'static,
1854 Variant: 'static,
1855 E: Copy,
1857 {
1858 let filtered_extractor = self.extractor.filter(predicate);
1859 EnumKp::new(filtered_extractor, self.embedder)
1860 }
1861}
1862
1863pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1865 Enum,
1866 Variant,
1867 &'a Enum,
1868 &'a Variant,
1869 &'a mut Enum,
1870 &'a mut Variant,
1871 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1872 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1873 fn(Variant) -> Enum,
1874>;
1875
1876pub fn enum_variant<'a, Enum, Variant>(
1894 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1895 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1896 embedder: fn(Variant) -> Enum,
1897) -> EnumKpType<'a, Enum, Variant> {
1898 EnumKp::new(Kp::new(getter, setter), embedder)
1899}
1900
1901pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1911 EnumKp::new(
1912 Kp::new(
1913 |r: &Result<T, E>| r.as_ref().ok(),
1914 |r: &mut Result<T, E>| r.as_mut().ok(),
1915 ),
1916 |t: T| Ok(t),
1917 )
1918}
1919
1920pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1930 EnumKp::new(
1931 Kp::new(
1932 |r: &Result<T, E>| r.as_ref().err(),
1933 |r: &mut Result<T, E>| r.as_mut().err(),
1934 ),
1935 |e: E| Err(e),
1936 )
1937}
1938
1939pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1949 EnumKp::new(
1950 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1951 |t: T| Some(t),
1952 )
1953}
1954
1955pub fn variant_of<'a, Enum, Variant>(
1973 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1974 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1975 embedder: fn(Variant) -> Enum,
1976) -> EnumKpType<'a, Enum, Variant> {
1977 enum_variant(getter, setter, embedder)
1978}
1979
1980pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1993 Kp::new(
1994 |b: &Box<T>| Some(b.as_ref()),
1995 |b: &mut Box<T>| Some(b.as_mut()),
1996 )
1997}
1998
1999pub fn kp_arc<'a, T>() -> Kp<
2010 Arc<T>,
2011 T,
2012 &'a Arc<T>,
2013 &'a T,
2014 &'a mut Arc<T>,
2015 &'a mut T,
2016 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
2017 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
2018> {
2019 Kp::new(
2020 |arc: &Arc<T>| Some(arc.as_ref()),
2021 |arc: &mut Arc<T>| Arc::get_mut(arc),
2022 )
2023}
2024
2025pub fn kp_rc<'a, T>() -> Kp<
2036 std::rc::Rc<T>,
2037 T,
2038 &'a std::rc::Rc<T>,
2039 &'a T,
2040 &'a mut std::rc::Rc<T>,
2041 &'a mut T,
2042 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
2043 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
2044> {
2045 Kp::new(
2046 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
2047 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
2048 )
2049}
2050
2051use std::any::{Any, TypeId};
2054use std::rc::Rc;
2055
2056#[cfg(test)]
2071mod tests {
2072 use super::*;
2073 use std::collections::HashMap;
2074
2075 #[derive(Debug)]
2076 struct TestKP {
2077 a: String,
2078 b: String,
2079 c: std::sync::Arc<String>,
2080 d: std::sync::Mutex<String>,
2081 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
2082 f: Option<TestKP2>,
2083 g: HashMap<i32, TestKP2>,
2084 }
2085
2086 impl TestKP {
2087 fn new() -> Self {
2088 Self {
2089 a: String::from("a"),
2090 b: String::from("b"),
2091 c: std::sync::Arc::new(String::from("c")),
2092 d: std::sync::Mutex::new(String::from("d")),
2093 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2094 f: Some(TestKP2 {
2095 a: String::from("a3"),
2096 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2097 }),
2098 g: HashMap::new(),
2099 }
2100 }
2101
2102 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2103 KpComposed::from_closures(
2104 move |r: &TestKP| r.g.get(&index),
2105 move |r: &mut TestKP| r.g.get_mut(&index),
2106 )
2107 }
2108
2109 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2112 TestKP2,
2113 String,
2114 Root,
2115 Value,
2116 MutRoot,
2117 MutValue,
2118 impl Fn(Root) -> Option<Value>,
2119 impl Fn(MutRoot) -> Option<MutValue>,
2120 >
2121 where
2122 Root: std::borrow::Borrow<TestKP2>,
2123 MutRoot: std::borrow::BorrowMut<TestKP2>,
2124 Value: std::borrow::Borrow<String> + From<String>,
2125 MutValue: std::borrow::BorrowMut<String> + From<String>,
2126 {
2127 Kp::new(
2128 |r: Root| Some(Value::from(r.borrow().a.clone())),
2129 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2130 )
2131 }
2132
2133 fn c<'a>() -> KpType<'a, TestKP, String> {
2136 KpType::new(
2137 |r: &TestKP| Some(r.c.as_ref()),
2138 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2139 Some(arc_str) => Some(arc_str),
2140 None => None,
2141 },
2142 )
2143 }
2144
2145 fn a<'a>() -> KpType<'a, TestKP, String> {
2146 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2147 }
2148
2149 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2150 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2151 }
2152
2153 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2154 KpType::identity()
2155 }
2156 }
2157
2158 #[derive(Debug)]
2159 struct TestKP2 {
2160 a: String,
2161 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2162 }
2163
2164 impl TestKP2 {
2165 fn new() -> Self {
2166 TestKP2 {
2167 a: String::from("a2"),
2168 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2169 }
2170 }
2171
2172 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2173 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2180 fn(MutRoot) -> Option<MutRoot>,
2181 >
2182 where
2183 Root: std::borrow::Borrow<TestKP2>,
2184 MutRoot: std::borrow::BorrowMut<TestKP2>,
2185 G: Fn(Root) -> Option<Root>,
2186 S: Fn(MutRoot) -> Option<MutRoot>,
2187 {
2188 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2189 }
2190
2191 fn a<'a>() -> KpType<'a, TestKP2, String> {
2192 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2193 }
2194
2195 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2196 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2197 }
2198
2199 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2204 KpType::identity()
2205 }
2206 }
2207
2208 #[derive(Debug)]
2209 struct TestKP3 {
2210 a: String,
2211 b: std::sync::Arc<std::sync::Mutex<String>>,
2212 }
2213
2214 impl TestKP3 {
2215 fn new() -> Self {
2216 TestKP3 {
2217 a: String::from("a2"),
2218 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2219 }
2220 }
2221
2222 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2223 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2230 fn(MutRoot) -> Option<MutRoot>,
2231 >
2232 where
2233 Root: std::borrow::Borrow<TestKP3>,
2234 MutRoot: std::borrow::BorrowMut<TestKP3>,
2235 G: Fn(Root) -> Option<Root>,
2236 S: Fn(MutRoot) -> Option<MutRoot>,
2237 {
2238 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2239 }
2240
2241 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2242 KpType::identity()
2243 }
2244 }
2245
2246 impl TestKP3 {}
2247
2248 impl TestKP {}
2249 #[test]
2250 fn test_a() {
2251 let instance2 = TestKP2::new();
2252 let mut instance = TestKP::new();
2253 let kp = TestKP::identity();
2254 let kp_a = TestKP::a();
2255 let wres = TestKP::f().then(TestKP2::a()).get_mut(&mut instance).unwrap();
2257 *wres = String::from("a3 changed successfully");
2258 let res = TestKP::f().then(TestKP2::a()).get(&instance);
2259 println!("{:?}", res);
2260 let res = TestKP::f().then(TestKP2::identity()).get(&instance);
2261 println!("{:?}", res);
2262 let res = kp.get(&instance);
2263 println!("{:?}", res);
2264
2265 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2266 println!("{:?}", new_kp_from_hashmap.get(&instance));
2267 }
2268
2269 #[test]
2348 fn test_enum_kp_result_ok() {
2349 let ok_result: Result<String, i32> = Ok("success".to_string());
2350 let mut err_result: Result<String, i32> = Err(42);
2351
2352 let ok_kp = enum_ok();
2353
2354 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2356 assert_eq!(ok_kp.get(&err_result), None);
2357
2358 let embedded = ok_kp.embed("embedded".to_string());
2360 assert_eq!(embedded, Ok("embedded".to_string()));
2361
2362 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2364 *val = "modified".to_string();
2365 }
2366 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2369 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2370 *val = "modified".to_string();
2371 }
2372 assert_eq!(ok_result2, Ok("modified".to_string()));
2373 }
2374
2375 #[test]
2376 fn test_enum_kp_result_err() {
2377 let ok_result: Result<String, i32> = Ok("success".to_string());
2378 let mut err_result: Result<String, i32> = Err(42);
2379
2380 let err_kp = enum_err();
2381
2382 assert_eq!(err_kp.get(&err_result), Some(&42));
2384 assert_eq!(err_kp.get(&ok_result), None);
2385
2386 let embedded = err_kp.embed(99);
2388 assert_eq!(embedded, Err(99));
2389
2390 if let Some(val) = err_kp.get_mut(&mut err_result) {
2392 *val = 100;
2393 }
2394 assert_eq!(err_result, Err(100));
2395 }
2396
2397 #[test]
2398 fn test_enum_kp_option_some() {
2399 let some_opt = Some("value".to_string());
2400 let mut none_opt: Option<String> = None;
2401
2402 let some_kp = enum_some();
2403
2404 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2406 assert_eq!(some_kp.get(&none_opt), None);
2407
2408 let embedded = some_kp.embed("embedded".to_string());
2410 assert_eq!(embedded, Some("embedded".to_string()));
2411
2412 let mut some_opt2 = Some("original".to_string());
2414 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2415 *val = "modified".to_string();
2416 }
2417 assert_eq!(some_opt2, Some("modified".to_string()));
2418 }
2419
2420 #[test]
2421 fn test_enum_kp_custom_enum() {
2422 #[derive(Debug, PartialEq)]
2423 enum MyEnum {
2424 A(String),
2425 B(i32),
2426 C,
2427 }
2428
2429 let mut enum_a = MyEnum::A("hello".to_string());
2430 let enum_b = MyEnum::B(42);
2431 let enum_c = MyEnum::C;
2432
2433 let kp_a = enum_variant(
2435 |e: &MyEnum| match e {
2436 MyEnum::A(s) => Some(s),
2437 _ => None,
2438 },
2439 |e: &mut MyEnum| match e {
2440 MyEnum::A(s) => Some(s),
2441 _ => None,
2442 },
2443 |s: String| MyEnum::A(s),
2444 );
2445
2446 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2448 assert_eq!(kp_a.get(&enum_b), None);
2449 assert_eq!(kp_a.get(&enum_c), None);
2450
2451 let embedded = kp_a.embed("world".to_string());
2453 assert_eq!(embedded, MyEnum::A("world".to_string()));
2454
2455 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2457 *val = "modified".to_string();
2458 }
2459 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2460 }
2461
2462 #[test]
2463 fn test_container_kp_box() {
2464 let boxed = Box::new("value".to_string());
2465 let mut boxed_mut = Box::new("original".to_string());
2466
2467 let box_kp = kp_box();
2468
2469 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2471
2472 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2474 *val = "modified".to_string();
2475 }
2476 assert_eq!(*boxed_mut, "modified".to_string());
2477 }
2478
2479 #[test]
2480 fn test_container_kp_arc() {
2481 let arc = Arc::new("value".to_string());
2482 let mut arc_mut = Arc::new("original".to_string());
2483
2484 let arc_kp = kp_arc();
2485
2486 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2488
2489 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2491 *val = "modified".to_string();
2492 }
2493 assert_eq!(*arc_mut, "modified".to_string());
2494
2495 let arc_shared = Arc::new("shared".to_string());
2497 let arc_shared2 = Arc::clone(&arc_shared);
2498 let mut arc_shared_mut = arc_shared;
2499 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2500 }
2501
2502 #[test]
2503 fn test_enum_kp_composition() {
2504 #[derive(Debug, PartialEq)]
2506 struct Inner {
2507 value: String,
2508 }
2509
2510 let result: Result<Inner, i32> = Ok(Inner {
2511 value: "nested".to_string(),
2512 });
2513
2514 let inner_kp = KpType::new(
2516 |i: &Inner| Some(&i.value),
2517 |i: &mut Inner| Some(&mut i.value),
2518 );
2519
2520 let ok_kp = enum_ok::<Inner, i32>();
2522 let ok_kp_base = ok_kp.into_kp();
2523 let composed = ok_kp_base.then(inner_kp);
2524
2525 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2526 }
2527
2528 #[test]
2529 fn test_pkp_basic() {
2530 #[derive(Debug)]
2531 struct User {
2532 name: String,
2533 age: i32,
2534 }
2535
2536 let user = User {
2537 name: "Alice".to_string(),
2538 age: 30,
2539 };
2540
2541 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2543 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2544
2545 let name_pkp = PKp::new(name_kp);
2547 let age_pkp = PKp::new(age_kp);
2548
2549 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2551 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2552
2553 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2555 assert_eq!(age_pkp.get_as::<String>(&user), None);
2556
2557 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2559 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2560 }
2561
2562 #[test]
2563 fn test_pkp_collection() {
2564 #[derive(Debug)]
2565 struct User {
2566 name: String,
2567 age: i32,
2568 }
2569
2570 let user = User {
2571 name: "Bob".to_string(),
2572 age: 25,
2573 };
2574
2575 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2577 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2578
2579 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2580
2581 let name_value = keypaths[0].get_as::<String>(&user);
2583 let age_value = keypaths[1].get_as::<i32>(&user);
2584
2585 assert_eq!(name_value, Some(&"Bob".to_string()));
2586 assert_eq!(age_value, Some(&25));
2587 }
2588
2589 #[test]
2590 fn test_pkp_for_arc() {
2591 #[derive(Debug)]
2592 struct User {
2593 name: String,
2594 }
2595
2596 let user = Arc::new(User {
2597 name: "Charlie".to_string(),
2598 });
2599
2600 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2601 let name_pkp = PKp::new(name_kp);
2602
2603 let arc_pkp = name_pkp.for_arc();
2605
2606 assert_eq!(
2607 arc_pkp.get_as::<String>(&user),
2608 Some(&"Charlie".to_string())
2609 );
2610 }
2611
2612 #[test]
2613 fn test_pkp_for_option() {
2614 #[derive(Debug)]
2615 struct User {
2616 name: String,
2617 }
2618
2619 let some_user = Some(User {
2620 name: "Diana".to_string(),
2621 });
2622 let none_user: Option<User> = None;
2623
2624 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2625 let name_pkp = PKp::new(name_kp);
2626
2627 let opt_pkp = name_pkp.for_option();
2629
2630 assert_eq!(
2631 opt_pkp.get_as::<String>(&some_user),
2632 Some(&"Diana".to_string())
2633 );
2634 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2635 }
2636
2637 #[test]
2638 fn test_akp_basic() {
2639 #[derive(Debug)]
2640 struct User {
2641 name: String,
2642 age: i32,
2643 }
2644
2645 #[derive(Debug)]
2646 struct Product {
2647 title: String,
2648 price: f64,
2649 }
2650
2651 let user = User {
2652 name: "Eve".to_string(),
2653 age: 28,
2654 };
2655
2656 let product = Product {
2657 title: "Book".to_string(),
2658 price: 19.99,
2659 };
2660
2661 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2663 let user_name_akp = AKp::new(user_name_kp);
2664
2665 let product_title_kp = KpType::new(
2666 |p: &Product| Some(&p.title),
2667 |p: &mut Product| Some(&mut p.title),
2668 );
2669 let product_title_akp = AKp::new(product_title_kp);
2670
2671 assert_eq!(
2673 user_name_akp.get_as::<User, String>(&user),
2674 Some(Some(&"Eve".to_string()))
2675 );
2676 assert_eq!(
2677 product_title_akp.get_as::<Product, String>(&product),
2678 Some(Some(&"Book".to_string()))
2679 );
2680
2681 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2683 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2684
2685 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2687 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2688 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2689 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2690 }
2691
2692 #[test]
2693 fn test_akp_heterogeneous_collection() {
2694 #[derive(Debug)]
2695 struct User {
2696 name: String,
2697 }
2698
2699 #[derive(Debug)]
2700 struct Product {
2701 title: String,
2702 }
2703
2704 let user = User {
2705 name: "Frank".to_string(),
2706 };
2707 let product = Product {
2708 title: "Laptop".to_string(),
2709 };
2710
2711 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2713 let product_title_kp = KpType::new(
2714 |p: &Product| Some(&p.title),
2715 |p: &mut Product| Some(&mut p.title),
2716 );
2717
2718 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2719
2720 let user_any: &dyn Any = &user;
2722 let product_any: &dyn Any = &product;
2723
2724 let user_value = keypaths[0].get(user_any);
2725 let product_value = keypaths[1].get(product_any);
2726
2727 assert!(user_value.is_some());
2728 assert!(product_value.is_some());
2729
2730 assert_eq!(
2732 user_value.and_then(|v| v.downcast_ref::<String>()),
2733 Some(&"Frank".to_string())
2734 );
2735 assert_eq!(
2736 product_value.and_then(|v| v.downcast_ref::<String>()),
2737 Some(&"Laptop".to_string())
2738 );
2739 }
2740
2741 #[test]
2742 fn test_akp_for_option() {
2743 #[derive(Debug)]
2744 struct User {
2745 name: String,
2746 }
2747
2748 let some_user = Some(User {
2749 name: "Grace".to_string(),
2750 });
2751 let none_user: Option<User> = None;
2752
2753 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2754 let name_akp = AKp::new(name_kp);
2755
2756 let opt_akp = name_akp.for_option::<User>();
2758
2759 assert_eq!(
2760 opt_akp.get_as::<Option<User>, String>(&some_user),
2761 Some(Some(&"Grace".to_string()))
2762 );
2763 assert_eq!(
2764 opt_akp.get_as::<Option<User>, String>(&none_user),
2765 Some(None)
2766 );
2767 }
2768
2769 #[test]
2770 fn test_akp_for_result() {
2771 #[derive(Debug)]
2772 struct User {
2773 name: String,
2774 }
2775
2776 let ok_user: Result<User, String> = Ok(User {
2777 name: "Henry".to_string(),
2778 });
2779 let err_user: Result<User, String> = Err("Not found".to_string());
2780
2781 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2782 let name_akp = AKp::new(name_kp);
2783
2784 let result_akp = name_akp.for_result::<User, String>();
2786
2787 assert_eq!(
2788 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2789 Some(Some(&"Henry".to_string()))
2790 );
2791 assert_eq!(
2792 result_akp.get_as::<Result<User, String>, String>(&err_user),
2793 Some(None)
2794 );
2795 }
2796
2797 #[test]
2800 fn test_kp_map() {
2801 #[derive(Debug)]
2802 struct User {
2803 name: String,
2804 age: i32,
2805 }
2806
2807 let user = User {
2808 name: "Alice".to_string(),
2809 age: 30,
2810 };
2811
2812 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2814 let len_kp = name_kp.map(|name: &String| name.len());
2815
2816 assert_eq!(len_kp.get(&user), Some(5));
2817
2818 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2820 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2821
2822 assert_eq!(double_age_kp.get(&user), Some(60));
2823
2824 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2826 assert_eq!(is_adult_kp.get(&user), Some(true));
2827 }
2828
2829 #[test]
2830 fn test_kp_filter() {
2831 #[derive(Debug)]
2832 struct User {
2833 name: String,
2834 age: i32,
2835 }
2836
2837 let adult = User {
2838 name: "Alice".to_string(),
2839 age: 30,
2840 };
2841
2842 let minor = User {
2843 name: "Bob".to_string(),
2844 age: 15,
2845 };
2846
2847 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2848 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2849
2850 assert_eq!(adult_age_kp.get(&adult), Some(&30));
2851 assert_eq!(adult_age_kp.get(&minor), None);
2852
2853 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2855 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2856
2857 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2858 assert_eq!(short_name_kp.get(&adult), None);
2859 }
2860
2861 #[test]
2862 fn test_kp_map_and_filter() {
2863 #[derive(Debug)]
2864 struct User {
2865 scores: Vec<i32>,
2866 }
2867
2868 let user = User {
2869 scores: vec![85, 92, 78, 95],
2870 };
2871
2872 let scores_kp = KpType::new(
2873 |u: &User| Some(&u.scores),
2874 |u: &mut User| Some(&mut u.scores),
2875 );
2876
2877 let avg_kp =
2879 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2880
2881 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2883
2884 assert_eq!(high_avg_kp.get(&user), Some(87)); }
2886
2887 #[test]
2888 fn test_enum_kp_map() {
2889 let ok_result: Result<String, i32> = Ok("hello".to_string());
2890 let err_result: Result<String, i32> = Err(42);
2891
2892 let ok_kp = enum_ok::<String, i32>();
2893 let len_kp = ok_kp.map(|s: &String| s.len());
2894
2895 assert_eq!(len_kp.get(&ok_result), Some(5));
2896 assert_eq!(len_kp.get(&err_result), None);
2897
2898 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2900 let none_opt: Option<Vec<i32>> = None;
2901
2902 let some_kp = enum_some::<Vec<i32>>();
2903 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2904
2905 assert_eq!(count_kp.get(&some_opt), Some(5));
2906 assert_eq!(count_kp.get(&none_opt), None);
2907 }
2908
2909 #[test]
2910 fn test_enum_kp_filter() {
2911 let ok_result1: Result<i32, String> = Ok(42);
2912 let ok_result2: Result<i32, String> = Ok(-5);
2913 let err_result: Result<i32, String> = Err("error".to_string());
2914
2915 let ok_kp = enum_ok::<i32, String>();
2916 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2917
2918 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2919 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2924 let short_str = Some("hi".to_string());
2925
2926 let some_kp = enum_some::<String>();
2927 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2928
2929 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2930 assert_eq!(long_kp.get(&short_str), None);
2931 }
2932
2933 #[test]
2934 fn test_pkp_filter() {
2935 #[derive(Debug)]
2936 struct User {
2937 name: String,
2938 age: i32,
2939 }
2940
2941 let adult = User {
2942 name: "Alice".to_string(),
2943 age: 30,
2944 };
2945
2946 let minor = User {
2947 name: "Bob".to_string(),
2948 age: 15,
2949 };
2950
2951 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2952 let age_pkp = PKp::new(age_kp);
2953
2954 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2956
2957 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2958 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2959
2960 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2962 let name_pkp = PKp::new(name_kp);
2963 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2964
2965 assert_eq!(
2966 short_name_pkp.get_as::<String>(&minor),
2967 Some(&"Bob".to_string())
2968 );
2969 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2970 }
2971
2972 #[test]
2973 fn test_akp_filter() {
2974 #[derive(Debug)]
2975 struct User {
2976 age: i32,
2977 }
2978
2979 #[derive(Debug)]
2980 struct Product {
2981 price: f64,
2982 }
2983
2984 let adult = User { age: 30 };
2985 let minor = User { age: 15 };
2986 let expensive = Product { price: 99.99 };
2987 let cheap = Product { price: 5.0 };
2988
2989 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2991 let age_akp = AKp::new(age_kp);
2992 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2993
2994 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2995 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2996
2997 let price_kp = KpType::new(
2999 |p: &Product| Some(&p.price),
3000 |p: &mut Product| Some(&mut p.price),
3001 );
3002 let price_akp = AKp::new(price_kp);
3003 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
3004
3005 assert_eq!(
3006 expensive_akp.get_as::<Product, f64>(&expensive),
3007 Some(Some(&99.99))
3008 );
3009 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
3010 }
3011
3012 #[test]
3015 fn test_kp_filter_map() {
3016 #[derive(Debug)]
3017 struct User {
3018 middle_name: Option<String>,
3019 }
3020
3021 let user_with = User {
3022 middle_name: Some("Marie".to_string()),
3023 };
3024 let user_without = User { middle_name: None };
3025
3026 let middle_kp = KpType::new(
3027 |u: &User| Some(&u.middle_name),
3028 |u: &mut User| Some(&mut u.middle_name),
3029 );
3030
3031 let first_char_kp = middle_kp
3032 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
3033
3034 assert_eq!(first_char_kp.get(&user_with), Some('M'));
3035 assert_eq!(first_char_kp.get(&user_without), None);
3036 }
3037
3038 #[test]
3039 fn test_kp_inspect() {
3040 #[derive(Debug)]
3041 struct User {
3042 name: String,
3043 }
3044
3045 let user = User {
3046 name: "Alice".to_string(),
3047 };
3048
3049 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3053
3054 let result = name_kp.get(&user);
3057 assert_eq!(result, Some(&"Alice".to_string()));
3058
3059 }
3062
3063 #[test]
3064 fn test_kp_fold_value() {
3065 #[derive(Debug)]
3066 struct User {
3067 scores: Vec<i32>,
3068 }
3069
3070 let user = User {
3071 scores: vec![85, 92, 78, 95],
3072 };
3073
3074 let scores_kp = KpType::new(
3075 |u: &User| Some(&u.scores),
3076 |u: &mut User| Some(&mut u.scores),
3077 );
3078
3079 let sum_fn =
3081 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
3082
3083 assert_eq!(sum_fn(&user), 350);
3084 }
3085
3086 #[test]
3087 fn test_kp_any_all() {
3088 #[derive(Debug)]
3089 struct User {
3090 scores: Vec<i32>,
3091 }
3092
3093 let user_high = User {
3094 scores: vec![85, 92, 88],
3095 };
3096 let user_mixed = User {
3097 scores: vec![65, 92, 78],
3098 };
3099
3100 let scores_kp = KpType::new(
3101 |u: &User| Some(&u.scores),
3102 |u: &mut User| Some(&mut u.scores),
3103 );
3104
3105 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
3107 assert!(has_high_fn(&user_high));
3108 assert!(has_high_fn(&user_mixed));
3109
3110 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
3112 assert!(all_passing_fn(&user_high));
3113 assert!(!all_passing_fn(&user_mixed));
3114 }
3115
3116 #[test]
3117 fn test_kp_count_items() {
3118 #[derive(Debug)]
3119 struct User {
3120 tags: Vec<String>,
3121 }
3122
3123 let user = User {
3124 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
3125 };
3126
3127 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3128 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
3129
3130 assert_eq!(count_fn(&user), Some(3));
3131 }
3132
3133 #[test]
3134 fn test_kp_find_in() {
3135 #[derive(Debug)]
3136 struct User {
3137 scores: Vec<i32>,
3138 }
3139
3140 let user = User {
3141 scores: vec![85, 92, 78, 95, 88],
3142 };
3143
3144 let scores_kp = KpType::new(
3145 |u: &User| Some(&u.scores),
3146 |u: &mut User| Some(&mut u.scores),
3147 );
3148
3149 let first_high_fn =
3151 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3152
3153 assert_eq!(first_high_fn(&user), Some(92));
3154
3155 let perfect_fn =
3157 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3158
3159 assert_eq!(perfect_fn(&user), None);
3160 }
3161
3162 #[test]
3163 fn test_kp_take_skip() {
3164 #[derive(Debug)]
3165 struct User {
3166 tags: Vec<String>,
3167 }
3168
3169 let user = User {
3170 tags: vec![
3171 "a".to_string(),
3172 "b".to_string(),
3173 "c".to_string(),
3174 "d".to_string(),
3175 ],
3176 };
3177
3178 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3179
3180 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3182 tags.iter().take(n).cloned().collect::<Vec<_>>()
3183 });
3184
3185 let taken = take_fn(&user).unwrap();
3186 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3187
3188 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3190 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3191 });
3192
3193 let skipped = skip_fn(&user).unwrap();
3194 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3195 }
3196
3197 #[test]
3198 fn test_kp_partition() {
3199 #[derive(Debug)]
3200 struct User {
3201 scores: Vec<i32>,
3202 }
3203
3204 let user = User {
3205 scores: vec![85, 92, 65, 95, 72, 58],
3206 };
3207
3208 let scores_kp = KpType::new(
3209 |u: &User| Some(&u.scores),
3210 |u: &mut User| Some(&mut u.scores),
3211 );
3212
3213 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3214 scores.iter().copied().partition(|&s| s >= 70)
3215 });
3216
3217 let (passing, failing) = partition_fn(&user).unwrap();
3218 assert_eq!(passing, vec![85, 92, 95, 72]);
3219 assert_eq!(failing, vec![65, 58]);
3220 }
3221
3222 #[test]
3223 fn test_kp_min_max() {
3224 #[derive(Debug)]
3225 struct User {
3226 scores: Vec<i32>,
3227 }
3228
3229 let user = User {
3230 scores: vec![85, 92, 78, 95, 88],
3231 };
3232
3233 let scores_kp = KpType::new(
3234 |u: &User| Some(&u.scores),
3235 |u: &mut User| Some(&mut u.scores),
3236 );
3237
3238 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3240 assert_eq!(min_fn(&user), Some(78));
3241
3242 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3244 assert_eq!(max_fn(&user), Some(95));
3245 }
3246
3247 #[test]
3248 fn test_kp_sum() {
3249 #[derive(Debug)]
3250 struct User {
3251 scores: Vec<i32>,
3252 }
3253
3254 let user = User {
3255 scores: vec![85, 92, 78],
3256 };
3257
3258 let scores_kp = KpType::new(
3259 |u: &User| Some(&u.scores),
3260 |u: &mut User| Some(&mut u.scores),
3261 );
3262
3263 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3264 assert_eq!(sum_fn(&user), Some(255));
3265
3266 let avg_fn =
3268 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3269 assert_eq!(avg_fn.get(&user), Some(85));
3270 }
3271
3272 #[test]
3273 fn test_kp_chain() {
3274 #[derive(Debug)]
3275 struct User {
3276 profile: Profile,
3277 }
3278
3279 #[derive(Debug)]
3280 struct Profile {
3281 settings: Settings,
3282 }
3283
3284 #[derive(Debug)]
3285 struct Settings {
3286 theme: String,
3287 }
3288
3289 let user = User {
3290 profile: Profile {
3291 settings: Settings {
3292 theme: "dark".to_string(),
3293 },
3294 },
3295 };
3296
3297 let profile_kp = KpType::new(
3298 |u: &User| Some(&u.profile),
3299 |u: &mut User| Some(&mut u.profile),
3300 );
3301 let settings_kp = KpType::new(
3302 |p: &Profile| Some(&p.settings),
3303 |p: &mut Profile| Some(&mut p.settings),
3304 );
3305 let theme_kp = KpType::new(
3306 |s: &Settings| Some(&s.theme),
3307 |s: &mut Settings| Some(&mut s.theme),
3308 );
3309
3310 let profile_settings = profile_kp.chain(settings_kp);
3312 let theme_path = profile_settings.chain(theme_kp);
3313 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3314 }
3315
3316 #[test]
3317 fn test_kp_zip() {
3318 #[derive(Debug)]
3319 struct User {
3320 name: String,
3321 age: i32,
3322 }
3323
3324 let user = User {
3325 name: "Alice".to_string(),
3326 age: 30,
3327 };
3328
3329 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3330 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3331
3332 let zipped_fn = zip_kps(&name_kp, &age_kp);
3333 let result = zipped_fn(&user);
3334
3335 assert_eq!(result, Some((&"Alice".to_string(), &30)));
3336 }
3337
3338 #[test]
3339 fn test_kp_complex_pipeline() {
3340 #[derive(Debug)]
3341 struct User {
3342 transactions: Vec<Transaction>,
3343 }
3344
3345 #[derive(Debug)]
3346 struct Transaction {
3347 amount: f64,
3348 category: String,
3349 }
3350
3351 let user = User {
3352 transactions: vec![
3353 Transaction {
3354 amount: 50.0,
3355 category: "food".to_string(),
3356 },
3357 Transaction {
3358 amount: 100.0,
3359 category: "transport".to_string(),
3360 },
3361 Transaction {
3362 amount: 25.0,
3363 category: "food".to_string(),
3364 },
3365 Transaction {
3366 amount: 200.0,
3367 category: "shopping".to_string(),
3368 },
3369 ],
3370 };
3371
3372 let txns_kp = KpType::new(
3373 |u: &User| Some(&u.transactions),
3374 |u: &mut User| Some(&mut u.transactions),
3375 );
3376
3377 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3379 txns.iter()
3380 .filter(|t| t.category == "food")
3381 .map(|t| t.amount)
3382 .sum::<f64>()
3383 });
3384
3385 assert_eq!(food_total.get(&user), Some(75.0));
3386
3387 let has_large =
3389 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3390
3391 assert!(has_large(&user));
3392
3393 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3395 assert_eq!(count(&user), Some(4));
3396 }
3397
3398 #[test]
3402 fn test_no_clone_required_for_root() {
3403 use std::sync::Arc;
3404 use std::sync::atomic::{AtomicUsize, Ordering};
3405
3406 struct NonCloneableRoot {
3409 data: Arc<AtomicUsize>,
3410 cached_value: usize,
3411 }
3412
3413 impl NonCloneableRoot {
3414 fn new() -> Self {
3415 Self {
3416 data: Arc::new(AtomicUsize::new(42)),
3417 cached_value: 42,
3418 }
3419 }
3420
3421 fn increment(&mut self) {
3422 self.data.fetch_add(1, Ordering::SeqCst);
3423 self.cached_value = self.data.load(Ordering::SeqCst);
3424 }
3425
3426 fn get_value(&self) -> &usize {
3427 &self.cached_value
3428 }
3429
3430 fn get_value_mut(&mut self) -> &mut usize {
3431 &mut self.cached_value
3432 }
3433 }
3434
3435 let mut root = NonCloneableRoot::new();
3436
3437 let data_kp = KpType::new(
3439 |r: &NonCloneableRoot| Some(r.get_value()),
3440 |r: &mut NonCloneableRoot| {
3441 r.increment();
3442 Some(r.get_value_mut())
3443 },
3444 );
3445
3446 assert_eq!(data_kp.get(&root), Some(&42));
3448
3449 {
3450 let doubled = data_kp.map(|val: &usize| val * 2);
3452 assert_eq!(doubled.get(&root), Some(84));
3453
3454 let filtered = data_kp.filter(|val: &usize| *val > 0);
3456 assert_eq!(filtered.get(&root), Some(&42));
3457 } let value_ref = data_kp.get_mut(&mut root);
3461 assert!(value_ref.is_some());
3462 }
3463
3464 #[test]
3465 fn test_no_clone_required_for_value() {
3466 use std::sync::Arc;
3467 use std::sync::atomic::{AtomicUsize, Ordering};
3468
3469 struct NonCloneableValue {
3471 counter: Arc<AtomicUsize>,
3472 }
3473
3474 impl NonCloneableValue {
3475 fn new(val: usize) -> Self {
3476 Self {
3477 counter: Arc::new(AtomicUsize::new(val)),
3478 }
3479 }
3480
3481 fn get(&self) -> usize {
3482 self.counter.load(Ordering::SeqCst)
3483 }
3484 }
3485
3486 struct Root {
3487 value: NonCloneableValue,
3488 }
3489
3490 let root = Root {
3491 value: NonCloneableValue::new(100),
3492 };
3493
3494 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3496
3497 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3499 assert_eq!(counter_kp.get(&root), Some(100));
3500
3501 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3503 assert!(filtered.get(&root).is_some());
3504 }
3505
3506 #[test]
3507 fn test_static_does_not_leak_memory() {
3508 use std::sync::Arc;
3509 use std::sync::atomic::{AtomicUsize, Ordering};
3510
3511 static CREATED: AtomicUsize = AtomicUsize::new(0);
3513 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3514
3515 struct Tracked {
3516 id: usize,
3517 }
3518
3519 impl Tracked {
3520 fn new() -> Self {
3521 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3522 Self { id }
3523 }
3524 }
3525
3526 impl Drop for Tracked {
3527 fn drop(&mut self) {
3528 DROPPED.fetch_add(1, Ordering::SeqCst);
3529 }
3530 }
3531
3532 struct Root {
3533 data: Tracked,
3534 }
3535
3536 CREATED.store(0, Ordering::SeqCst);
3538 DROPPED.store(0, Ordering::SeqCst);
3539
3540 {
3541 let root = Root {
3542 data: Tracked::new(),
3543 };
3544
3545 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3546
3547 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3549 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3550 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3551
3552 assert_eq!(mapped1.get(&root), Some(0));
3553 assert_eq!(mapped2.get(&root), Some(1));
3554 assert_eq!(mapped3.get(&root), Some(2));
3555
3556 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3558 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3559 }
3560
3561 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3563 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3564
3565 }
3567
3568 #[test]
3569 fn test_references_not_cloned() {
3570 use std::sync::Arc;
3571
3572 struct ExpensiveData {
3574 large_vec: Vec<u8>,
3575 }
3576
3577 impl ExpensiveData {
3578 fn new(size: usize) -> Self {
3579 Self {
3580 large_vec: vec![0u8; size],
3581 }
3582 }
3583
3584 fn size(&self) -> usize {
3585 self.large_vec.len()
3586 }
3587 }
3588
3589 struct Root {
3590 expensive: ExpensiveData,
3591 }
3592
3593 let root = Root {
3594 expensive: ExpensiveData::new(1_000_000), };
3596
3597 let expensive_kp = KpType::new(
3598 |r: &Root| Some(&r.expensive),
3599 |r: &mut Root| Some(&mut r.expensive),
3600 );
3601
3602 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3604 assert_eq!(size_kp.get(&root), Some(1_000_000));
3605
3606 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3608 assert!(large_filter.get(&root).is_some());
3609
3610 }
3612
3613 #[test]
3614 fn test_hof_with_arc_no_extra_clones() {
3615 use std::sync::Arc;
3616
3617 #[derive(Debug)]
3618 struct SharedData {
3619 value: String,
3620 }
3621
3622 struct Root {
3623 shared: Arc<SharedData>,
3624 }
3625
3626 let shared = Arc::new(SharedData {
3627 value: "shared".to_string(),
3628 });
3629
3630 assert_eq!(Arc::strong_count(&shared), 1);
3632
3633 {
3634 let root = Root {
3635 shared: Arc::clone(&shared),
3636 };
3637
3638 assert_eq!(Arc::strong_count(&shared), 2);
3640
3641 let shared_kp = KpType::new(
3642 |r: &Root| Some(&r.shared),
3643 |r: &mut Root| Some(&mut r.shared),
3644 );
3645
3646 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3648
3649 assert_eq!(value_kp.get(&root), Some(6));
3651 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3655 assert!(filtered.get(&root).is_some());
3656 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3661
3662 #[test]
3663 fn test_closure_captures_not_root_values() {
3664 use std::sync::Arc;
3665 use std::sync::atomic::{AtomicUsize, Ordering};
3666
3667 let call_count = Arc::new(AtomicUsize::new(0));
3669 let call_count_clone = Arc::clone(&call_count);
3670
3671 struct Root {
3672 value: i32,
3673 }
3674
3675 let root = Root { value: 42 };
3676
3677 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3678
3679 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3682 call_count_clone.fetch_add(1, Ordering::SeqCst);
3683 v * 2
3684 });
3685
3686 assert_eq!(doubled(&root), 84);
3688 assert_eq!(doubled(&root), 84);
3689 assert_eq!(doubled(&root), 84);
3690
3691 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3693
3694 }
3696
3697 #[test]
3698 fn test_static_with_borrowed_data() {
3699 struct Root {
3703 data: String,
3704 }
3705
3706 {
3707 let root = Root {
3708 data: "temporary".to_string(),
3709 };
3710
3711 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3712
3713 let len_kp = data_kp.map(|s: &String| s.len());
3715 assert_eq!(len_kp.get(&root), Some(9));
3716
3717 } }
3722
3723 #[test]
3724 fn test_multiple_hof_operations_no_accumulation() {
3725 use std::sync::Arc;
3726 use std::sync::atomic::{AtomicUsize, Ordering};
3727
3728 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3729
3730 struct Tracked {
3731 id: usize,
3732 }
3733
3734 impl Drop for Tracked {
3735 fn drop(&mut self) {
3736 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3737 }
3738 }
3739
3740 struct Root {
3741 values: Vec<Tracked>,
3742 }
3743
3744 DROP_COUNT.store(0, Ordering::SeqCst);
3745
3746 {
3747 let root = Root {
3748 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3749 };
3750
3751 let values_kp = KpType::new(
3752 |r: &Root| Some(&r.values),
3753 |r: &mut Root| Some(&mut r.values),
3754 );
3755
3756 let count = values_kp.count_items(|v| v.len());
3758 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3759 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3760 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3761
3762 assert_eq!(count(&root), Some(3));
3763 assert_eq!(sum(&root), Some(6));
3764 assert!(has_2(&root));
3765 assert!(all_positive(&root));
3766
3767 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3769 }
3770
3771 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3773 }
3774
3775 #[test]
3776 fn test_copy_bound_only_for_function_not_data() {
3777 #[derive(Debug)]
3781 struct NonCopyData {
3782 value: String,
3783 }
3784
3785 struct Root {
3786 data: NonCopyData,
3787 }
3788
3789 let root = Root {
3790 data: NonCopyData {
3791 value: "test".to_string(),
3792 },
3793 };
3794
3795 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3796
3797 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3800 assert_eq!(len_kp.get(&root), Some(4));
3801
3802 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3804 assert!(filtered.get(&root).is_some());
3805 }
3806
3807 #[test]
3808 fn test_no_memory_leak_with_cyclic_references() {
3809 use std::sync::atomic::{AtomicUsize, Ordering};
3810 use std::sync::{Arc, Weak};
3811
3812 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3813
3814 struct Node {
3815 id: usize,
3816 parent: Option<Weak<Node>>,
3817 }
3818
3819 impl Drop for Node {
3820 fn drop(&mut self) {
3821 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3822 }
3823 }
3824
3825 struct Root {
3826 node: Arc<Node>,
3827 }
3828
3829 DROP_COUNT.store(0, Ordering::SeqCst);
3830
3831 {
3832 let root = Root {
3833 node: Arc::new(Node {
3834 id: 1,
3835 parent: None,
3836 }),
3837 };
3838
3839 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3840
3841 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3843 assert_eq!(id_kp.get(&root), Some(1));
3844
3845 assert_eq!(Arc::strong_count(&root.node), 1);
3847
3848 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3850 }
3851
3852 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3854 }
3855
3856 #[test]
3857 fn test_hof_operations_are_zero_cost_abstractions() {
3858 struct Root {
3862 value: i32,
3863 }
3864
3865 let root = Root { value: 10 };
3866
3867 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3868
3869 let direct_result = value_kp.get(&root).map(|v| v * 2);
3871 assert_eq!(direct_result, Some(20));
3872
3873 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3875 let hof_result = mapped_kp.get(&root);
3876 assert_eq!(hof_result, Some(20));
3877
3878 assert_eq!(direct_result, hof_result);
3880 }
3881
3882 #[test]
3883 fn test_complex_closure_captures_allowed() {
3884 use std::sync::Arc;
3885
3886 struct Root {
3888 scores: Vec<i32>,
3889 }
3890
3891 let root = Root {
3892 scores: vec![85, 92, 78, 95, 88],
3893 };
3894
3895 let scores_kp = KpType::new(
3896 |r: &Root| Some(&r.scores),
3897 |r: &mut Root| Some(&mut r.scores),
3898 );
3899
3900 let threshold = 90;
3902 let multiplier = Arc::new(2);
3903
3904 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3906 let high: i32 = scores
3907 .iter()
3908 .filter(|&&s| s >= threshold)
3909 .map(|&s| s * *multiplier)
3910 .sum();
3911 acc + high
3912 });
3913
3914 assert_eq!(high_scores_doubled(&root), 374);
3916 }
3917
3918 #[test]
3922 fn test_pkp_filter_by_value_type() {
3923 use std::any::TypeId;
3924
3925 #[derive(Debug)]
3926 struct User {
3927 name: String,
3928 age: i32,
3929 score: f64,
3930 active: bool,
3931 }
3932
3933 let user = User {
3934 name: "Alice".to_string(),
3935 age: 30,
3936 score: 95.5,
3937 active: true,
3938 };
3939
3940 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3942 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3943 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3944 let active_kp = KpType::new(
3945 |u: &User| Some(&u.active),
3946 |u: &mut User| Some(&mut u.active),
3947 );
3948
3949 let all_keypaths: Vec<PKp<User>> = vec![
3951 PKp::new(name_kp),
3952 PKp::new(age_kp),
3953 PKp::new(score_kp),
3954 PKp::new(active_kp),
3955 ];
3956
3957 let string_kps: Vec<_> = all_keypaths
3959 .iter()
3960 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3961 .collect();
3962
3963 assert_eq!(string_kps.len(), 1);
3964 assert_eq!(
3965 string_kps[0].get_as::<String>(&user),
3966 Some(&"Alice".to_string())
3967 );
3968
3969 let i32_kps: Vec<_> = all_keypaths
3971 .iter()
3972 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3973 .collect();
3974
3975 assert_eq!(i32_kps.len(), 1);
3976 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3977
3978 let f64_kps: Vec<_> = all_keypaths
3980 .iter()
3981 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3982 .collect();
3983
3984 assert_eq!(f64_kps.len(), 1);
3985 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3986
3987 let bool_kps: Vec<_> = all_keypaths
3989 .iter()
3990 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3991 .collect();
3992
3993 assert_eq!(bool_kps.len(), 1);
3994 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3995 }
3996
3997 #[test]
3998 fn test_pkp_filter_by_struct_type() {
3999 use std::any::TypeId;
4000
4001 #[derive(Debug, PartialEq)]
4002 struct Address {
4003 street: String,
4004 city: String,
4005 }
4006
4007 #[derive(Debug)]
4008 struct User {
4009 name: String,
4010 age: i32,
4011 address: Address,
4012 }
4013
4014 let user = User {
4015 name: "Bob".to_string(),
4016 age: 25,
4017 address: Address {
4018 street: "123 Main St".to_string(),
4019 city: "NYC".to_string(),
4020 },
4021 };
4022
4023 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4025 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4026 let address_kp = KpType::new(
4027 |u: &User| Some(&u.address),
4028 |u: &mut User| Some(&mut u.address),
4029 );
4030
4031 let all_keypaths: Vec<PKp<User>> =
4032 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
4033
4034 let struct_kps: Vec<_> = all_keypaths
4036 .iter()
4037 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
4038 .collect();
4039
4040 assert_eq!(struct_kps.len(), 1);
4041 assert_eq!(
4042 struct_kps[0].get_as::<Address>(&user),
4043 Some(&Address {
4044 street: "123 Main St".to_string(),
4045 city: "NYC".to_string(),
4046 })
4047 );
4048
4049 let primitive_kps: Vec<_> = all_keypaths
4051 .iter()
4052 .filter(|pkp| {
4053 pkp.value_type_id() == TypeId::of::<String>()
4054 || pkp.value_type_id() == TypeId::of::<i32>()
4055 })
4056 .collect();
4057
4058 assert_eq!(primitive_kps.len(), 2);
4059 }
4060
4061 #[test]
4062 fn test_pkp_filter_by_arc_type() {
4063 use std::any::TypeId;
4064 use std::sync::Arc;
4065
4066 #[derive(Debug)]
4067 struct User {
4068 name: String,
4069 shared_data: Arc<String>,
4070 shared_number: Arc<i32>,
4071 }
4072
4073 let user = User {
4074 name: "Charlie".to_string(),
4075 shared_data: Arc::new("shared".to_string()),
4076 shared_number: Arc::new(42),
4077 };
4078
4079 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4081 let shared_data_kp = KpType::new(
4082 |u: &User| Some(&u.shared_data),
4083 |u: &mut User| Some(&mut u.shared_data),
4084 );
4085 let shared_number_kp = KpType::new(
4086 |u: &User| Some(&u.shared_number),
4087 |u: &mut User| Some(&mut u.shared_number),
4088 );
4089
4090 let all_keypaths: Vec<PKp<User>> = vec![
4091 PKp::new(name_kp),
4092 PKp::new(shared_data_kp),
4093 PKp::new(shared_number_kp),
4094 ];
4095
4096 let arc_string_kps: Vec<_> = all_keypaths
4098 .iter()
4099 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
4100 .collect();
4101
4102 assert_eq!(arc_string_kps.len(), 1);
4103 assert_eq!(
4104 arc_string_kps[0]
4105 .get_as::<Arc<String>>(&user)
4106 .map(|arc| arc.as_str()),
4107 Some("shared")
4108 );
4109
4110 let arc_i32_kps: Vec<_> = all_keypaths
4112 .iter()
4113 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
4114 .collect();
4115
4116 assert_eq!(arc_i32_kps.len(), 1);
4117 assert_eq!(
4118 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
4119 Some(42)
4120 );
4121
4122 let all_arc_kps: Vec<_> = all_keypaths
4124 .iter()
4125 .filter(|pkp| {
4126 pkp.value_type_id() == TypeId::of::<Arc<String>>()
4127 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
4128 })
4129 .collect();
4130
4131 assert_eq!(all_arc_kps.len(), 2);
4132 }
4133
4134 #[test]
4135 fn test_pkp_filter_by_box_type() {
4136 use std::any::TypeId;
4137
4138 #[derive(Debug)]
4139 struct User {
4140 name: String,
4141 boxed_value: Box<i32>,
4142 boxed_string: Box<String>,
4143 }
4144
4145 let user = User {
4146 name: "Diana".to_string(),
4147 boxed_value: Box::new(100),
4148 boxed_string: Box::new("boxed".to_string()),
4149 };
4150
4151 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4153 let boxed_value_kp = KpType::new(
4154 |u: &User| Some(&u.boxed_value),
4155 |u: &mut User| Some(&mut u.boxed_value),
4156 );
4157 let boxed_string_kp = KpType::new(
4158 |u: &User| Some(&u.boxed_string),
4159 |u: &mut User| Some(&mut u.boxed_string),
4160 );
4161
4162 let all_keypaths: Vec<PKp<User>> = vec![
4163 PKp::new(name_kp),
4164 PKp::new(boxed_value_kp),
4165 PKp::new(boxed_string_kp),
4166 ];
4167
4168 let box_i32_kps: Vec<_> = all_keypaths
4170 .iter()
4171 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4172 .collect();
4173
4174 assert_eq!(box_i32_kps.len(), 1);
4175 assert_eq!(
4176 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4177 Some(100)
4178 );
4179
4180 let box_string_kps: Vec<_> = all_keypaths
4182 .iter()
4183 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4184 .collect();
4185
4186 assert_eq!(box_string_kps.len(), 1);
4187 assert_eq!(
4188 box_string_kps[0]
4189 .get_as::<Box<String>>(&user)
4190 .map(|b| b.as_str()),
4191 Some("boxed")
4192 );
4193 }
4194
4195 #[test]
4196 fn test_akp_filter_by_root_and_value_type() {
4197 use std::any::TypeId;
4198
4199 #[derive(Debug)]
4200 struct User {
4201 name: String,
4202 age: i32,
4203 }
4204
4205 #[derive(Debug)]
4206 struct Product {
4207 title: String,
4208 price: f64,
4209 }
4210
4211 let user = User {
4212 name: "Eve".to_string(),
4213 age: 28,
4214 };
4215
4216 let product = Product {
4217 title: "Book".to_string(),
4218 price: 19.99,
4219 };
4220
4221 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4223 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4224 let product_title_kp = KpType::new(
4225 |p: &Product| Some(&p.title),
4226 |p: &mut Product| Some(&mut p.title),
4227 );
4228 let product_price_kp = KpType::new(
4229 |p: &Product| Some(&p.price),
4230 |p: &mut Product| Some(&mut p.price),
4231 );
4232
4233 let all_keypaths: Vec<AKp> = vec![
4234 AKp::new(user_name_kp),
4235 AKp::new(user_age_kp),
4236 AKp::new(product_title_kp),
4237 AKp::new(product_price_kp),
4238 ];
4239
4240 let user_kps: Vec<_> = all_keypaths
4242 .iter()
4243 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4244 .collect();
4245
4246 assert_eq!(user_kps.len(), 2);
4247
4248 let product_kps: Vec<_> = all_keypaths
4250 .iter()
4251 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4252 .collect();
4253
4254 assert_eq!(product_kps.len(), 2);
4255
4256 let string_value_kps: Vec<_> = all_keypaths
4258 .iter()
4259 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4260 .collect();
4261
4262 assert_eq!(string_value_kps.len(), 2);
4263
4264 let user_string_kps: Vec<_> = all_keypaths
4266 .iter()
4267 .filter(|akp| {
4268 akp.root_type_id() == TypeId::of::<User>()
4269 && akp.value_type_id() == TypeId::of::<String>()
4270 })
4271 .collect();
4272
4273 assert_eq!(user_string_kps.len(), 1);
4274 assert_eq!(
4275 user_string_kps[0].get_as::<User, String>(&user),
4276 Some(Some(&"Eve".to_string()))
4277 );
4278
4279 let product_f64_kps: Vec<_> = all_keypaths
4281 .iter()
4282 .filter(|akp| {
4283 akp.root_type_id() == TypeId::of::<Product>()
4284 && akp.value_type_id() == TypeId::of::<f64>()
4285 })
4286 .collect();
4287
4288 assert_eq!(product_f64_kps.len(), 1);
4289 assert_eq!(
4290 product_f64_kps[0].get_as::<Product, f64>(&product),
4291 Some(Some(&19.99))
4292 );
4293 }
4294
4295 #[test]
4296 fn test_akp_filter_by_arc_root_type() {
4297 use std::any::TypeId;
4298 use std::sync::Arc;
4299
4300 #[derive(Debug)]
4301 struct User {
4302 name: String,
4303 }
4304
4305 #[derive(Debug)]
4306 struct Product {
4307 title: String,
4308 }
4309
4310 let user = User {
4311 name: "Frank".to_string(),
4312 };
4313 let product = Product {
4314 title: "Laptop".to_string(),
4315 };
4316
4317 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4319 let product_title_kp = KpType::new(
4320 |p: &Product| Some(&p.title),
4321 |p: &mut Product| Some(&mut p.title),
4322 );
4323
4324 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4326 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4327
4328 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4329
4330 let arc_user_kps: Vec<_> = all_keypaths
4332 .iter()
4333 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4334 .collect();
4335
4336 assert_eq!(arc_user_kps.len(), 1);
4337
4338 let arc_user = Arc::new(user);
4340 assert_eq!(
4341 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4342 Some(Some(&"Frank".to_string()))
4343 );
4344
4345 let arc_product_kps: Vec<_> = all_keypaths
4347 .iter()
4348 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4349 .collect();
4350
4351 assert_eq!(arc_product_kps.len(), 1);
4352
4353 let arc_product = Arc::new(product);
4355 assert_eq!(
4356 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4357 Some(Some(&"Laptop".to_string()))
4358 );
4359 }
4360
4361 #[test]
4362 fn test_akp_filter_by_box_root_type() {
4363 use std::any::TypeId;
4364
4365 #[derive(Debug)]
4366 struct Config {
4367 setting: String,
4368 }
4369
4370 let config = Config {
4371 setting: "enabled".to_string(),
4372 };
4373
4374 let config_kp1 = KpType::new(
4376 |c: &Config| Some(&c.setting),
4377 |c: &mut Config| Some(&mut c.setting),
4378 );
4379 let config_kp2 = KpType::new(
4380 |c: &Config| Some(&c.setting),
4381 |c: &mut Config| Some(&mut c.setting),
4382 );
4383
4384 let regular_akp = AKp::new(config_kp1);
4386 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4387
4388 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4389
4390 let config_kps: Vec<_> = all_keypaths
4392 .iter()
4393 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4394 .collect();
4395
4396 assert_eq!(config_kps.len(), 1);
4397 assert_eq!(
4398 config_kps[0].get_as::<Config, String>(&config),
4399 Some(Some(&"enabled".to_string()))
4400 );
4401
4402 let box_config_kps: Vec<_> = all_keypaths
4404 .iter()
4405 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4406 .collect();
4407
4408 assert_eq!(box_config_kps.len(), 1);
4409
4410 let box_config = Box::new(Config {
4412 setting: "enabled".to_string(),
4413 });
4414 assert_eq!(
4415 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4416 Some(Some(&"enabled".to_string()))
4417 );
4418 }
4419
4420 #[test]
4421 fn test_mixed_collection_type_filtering() {
4422 use std::any::TypeId;
4423 use std::sync::Arc;
4424
4425 #[derive(Debug)]
4426 struct User {
4427 name: String,
4428 email: String,
4429 }
4430
4431 #[derive(Debug)]
4432 struct Product {
4433 title: String,
4434 sku: String,
4435 }
4436
4437 let user = User {
4438 name: "Grace".to_string(),
4439 email: "grace@example.com".to_string(),
4440 };
4441
4442 let product = Product {
4443 title: "Widget".to_string(),
4444 sku: "WID-001".to_string(),
4445 };
4446
4447 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4449 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4450 let user_email_kp1 =
4451 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4452 let user_email_kp2 =
4453 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4454 let product_title_kp = KpType::new(
4455 |p: &Product| Some(&p.title),
4456 |p: &mut Product| Some(&mut p.title),
4457 );
4458 let product_sku_kp = KpType::new(
4459 |p: &Product| Some(&p.sku),
4460 |p: &mut Product| Some(&mut p.sku),
4461 );
4462
4463 let all_keypaths: Vec<AKp> = vec![
4464 AKp::new(user_name_kp1),
4465 AKp::new(user_email_kp1),
4466 AKp::new(product_title_kp),
4467 AKp::new(product_sku_kp),
4468 AKp::new(user_name_kp2).for_arc::<User>(),
4469 AKp::new(user_email_kp2).for_box::<User>(),
4470 ];
4471
4472 let string_value_kps: Vec<_> = all_keypaths
4474 .iter()
4475 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4476 .collect();
4477
4478 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4482 .iter()
4483 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4484 .collect();
4485
4486 assert_eq!(user_root_kps.len(), 2);
4487
4488 let arc_user_kps: Vec<_> = all_keypaths
4490 .iter()
4491 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4492 .collect();
4493
4494 assert_eq!(arc_user_kps.len(), 1);
4495
4496 let box_user_kps: Vec<_> = all_keypaths
4498 .iter()
4499 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4500 .collect();
4501
4502 assert_eq!(box_user_kps.len(), 1);
4503
4504 let product_kps: Vec<_> = all_keypaths
4506 .iter()
4507 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4508 .collect();
4509
4510 assert_eq!(product_kps.len(), 2);
4511
4512 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4514 assert!(user_value.is_some());
4515 assert!(user_value.unwrap().is_some());
4516 }
4517
4518 #[test]
4523 fn test_kp_with_pin() {
4524 use std::pin::Pin;
4525
4526 #[derive(Debug)]
4530 struct SelfReferential {
4531 value: String,
4532 ptr_to_value: *const String, }
4534
4535 impl SelfReferential {
4536 fn new(s: String) -> Self {
4537 let mut sr = Self {
4538 value: s,
4539 ptr_to_value: std::ptr::null(),
4540 };
4541 sr.ptr_to_value = &sr.value as *const String;
4543 sr
4544 }
4545
4546 fn get_value(&self) -> &str {
4547 &self.value
4548 }
4549 }
4550
4551 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4553 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4554
4555 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4557 |p: &Pin<Box<SelfReferential>>| {
4558 Some(&p.as_ref().get_ref().value)
4560 },
4561 |p: &mut Pin<Box<SelfReferential>>| {
4562 unsafe {
4565 let sr = Pin::get_unchecked_mut(p.as_mut());
4566 Some(&mut sr.value)
4567 }
4568 },
4569 );
4570
4571 let result = kp.get(&pinned);
4573 assert_eq!(result, Some(&"pinned_data".to_string()));
4574
4575 assert_eq!(pinned.get_value(), "pinned_data");
4577 }
4578
4579 #[test]
4580 fn test_kp_with_pin_arc() {
4581 use std::pin::Pin;
4582 use std::sync::Arc;
4583
4584 struct AsyncState {
4585 status: String,
4586 data: Vec<i32>,
4587 }
4588
4589 let state = AsyncState {
4591 status: "ready".to_string(),
4592 data: vec![1, 2, 3, 4, 5],
4593 };
4594
4595 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4596
4597 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4599 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4600 |_: &mut Pin<Arc<AsyncState>>| {
4601 None::<&mut String>
4603 },
4604 );
4605
4606 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4608 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4609 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4610 );
4611
4612 let status = status_kp.get(&pinned_arc);
4613 assert_eq!(status, Some(&"ready".to_string()));
4614
4615 let data = data_kp.get(&pinned_arc);
4616 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4617 }
4618
4619 #[test]
4620 fn test_kp_with_maybe_uninit() {
4621 use std::mem::MaybeUninit;
4622
4623 struct Config {
4627 name: MaybeUninit<String>,
4628 value: MaybeUninit<i32>,
4629 initialized: bool,
4630 }
4631
4632 impl Config {
4633 fn new_uninit() -> Self {
4634 Self {
4635 name: MaybeUninit::uninit(),
4636 value: MaybeUninit::uninit(),
4637 initialized: false,
4638 }
4639 }
4640
4641 fn init(&mut self, name: String, value: i32) {
4642 self.name.write(name);
4643 self.value.write(value);
4644 self.initialized = true;
4645 }
4646
4647 fn get_name(&self) -> Option<&String> {
4648 if self.initialized {
4649 unsafe { Some(self.name.assume_init_ref()) }
4650 } else {
4651 None
4652 }
4653 }
4654
4655 fn get_value(&self) -> Option<&i32> {
4656 if self.initialized {
4657 unsafe { Some(self.value.assume_init_ref()) }
4658 } else {
4659 None
4660 }
4661 }
4662 }
4663
4664 let name_kp: KpType<Config, String> = Kp::new(
4666 |c: &Config| c.get_name(),
4667 |c: &mut Config| {
4668 if c.initialized {
4669 unsafe { Some(c.name.assume_init_mut()) }
4670 } else {
4671 None
4672 }
4673 },
4674 );
4675
4676 let value_kp: KpType<Config, i32> = Kp::new(
4677 |c: &Config| c.get_value(),
4678 |c: &mut Config| {
4679 if c.initialized {
4680 unsafe { Some(c.value.assume_init_mut()) }
4681 } else {
4682 None
4683 }
4684 },
4685 );
4686
4687 let uninit_config = Config::new_uninit();
4689 assert_eq!(name_kp.get(&uninit_config), None);
4690 assert_eq!(value_kp.get(&uninit_config), None);
4691
4692 let mut init_config = Config::new_uninit();
4694 init_config.init("test_config".to_string(), 42);
4695
4696 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4697 assert_eq!(value_kp.get(&init_config), Some(&42));
4698
4699 if let Some(val) = value_kp.get_mut(&mut init_config) {
4701 *val = 100;
4702 }
4703
4704 assert_eq!(value_kp.get(&init_config), Some(&100));
4705 }
4706
4707 #[test]
4708 fn test_kp_with_weak() {
4709 use std::sync::{Arc, Weak};
4710
4711 #[derive(Debug, Clone)]
4715 struct Node {
4716 value: i32,
4717 }
4718
4719 struct NodeWithParent {
4720 value: i32,
4721 parent: Option<Arc<Node>>, }
4723
4724 let parent = Arc::new(Node { value: 100 });
4725
4726 let child = NodeWithParent {
4727 value: 42,
4728 parent: Some(parent.clone()),
4729 };
4730
4731 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4733 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4734 |_: &mut NodeWithParent| None::<&mut i32>,
4735 );
4736
4737 let parent_val = parent_value_kp.get(&child);
4739 assert_eq!(parent_val, Some(&100));
4740 }
4741
4742 #[test]
4743 fn test_kp_with_rc_weak() {
4744 use std::rc::Rc;
4745
4746 struct TreeNode {
4749 value: String,
4750 parent: Option<Rc<TreeNode>>, }
4752
4753 let root = Rc::new(TreeNode {
4754 value: "root".to_string(),
4755 parent: None,
4756 });
4757
4758 let child1 = TreeNode {
4759 value: "child1".to_string(),
4760 parent: Some(root.clone()),
4761 };
4762
4763 let child2 = TreeNode {
4764 value: "child2".to_string(),
4765 parent: Some(root.clone()),
4766 };
4767
4768 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4770 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4771 |_: &mut TreeNode| None::<&mut String>,
4772 );
4773
4774 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4776 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4777
4778 assert_eq!(parent_name_kp.get(&root), None);
4780 }
4781
4782 #[test]
4783 fn test_kp_with_complex_weak_structure() {
4784 use std::sync::Arc;
4785
4786 struct Cache {
4789 data: String,
4790 backup: Option<Arc<Cache>>, }
4792
4793 let primary = Arc::new(Cache {
4794 data: "primary_data".to_string(),
4795 backup: None,
4796 });
4797
4798 let backup = Arc::new(Cache {
4799 data: "backup_data".to_string(),
4800 backup: Some(primary.clone()),
4801 });
4802
4803 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4805 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4806 |_: &mut Arc<Cache>| None::<&mut String>,
4807 );
4808
4809 let data = backup_data_kp.get(&backup);
4811 assert_eq!(data, Some(&"primary_data".to_string()));
4812
4813 let no_backup = backup_data_kp.get(&primary);
4815 assert_eq!(no_backup, None);
4816 }
4817
4818 #[test]
4819 fn test_kp_chain_with_pin_and_arc() {
4820 use std::pin::Pin;
4821 use std::sync::Arc;
4822
4823 struct Outer {
4826 inner: Arc<Inner>,
4827 }
4828
4829 struct Inner {
4830 value: String,
4831 }
4832
4833 let outer = Outer {
4834 inner: Arc::new(Inner {
4835 value: "nested_value".to_string(),
4836 }),
4837 };
4838
4839 let pinned_outer = Box::pin(outer);
4840
4841 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4843 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4844 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4845 );
4846
4847 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4849 |a: &Arc<Inner>| Some(&a.value),
4850 |_: &mut Arc<Inner>| None::<&mut String>,
4851 );
4852
4853 let chained = to_inner.then(to_value);
4855
4856 let result = chained.get(&pinned_outer);
4857 assert_eq!(result, Some(&"nested_value".to_string()));
4858 }
4859
4860 #[test]
4861 fn test_kp_with_maybe_uninit_array() {
4862 use std::mem::MaybeUninit;
4863
4864 struct Buffer {
4868 data: [MaybeUninit<u8>; 10],
4869 len: usize,
4870 }
4871
4872 impl Buffer {
4873 fn new() -> Self {
4874 Self {
4875 data: unsafe { MaybeUninit::uninit().assume_init() },
4876 len: 0,
4877 }
4878 }
4879
4880 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4881 if self.len >= self.data.len() {
4882 return Err("Buffer full");
4883 }
4884 self.data[self.len].write(byte);
4885 self.len += 1;
4886 Ok(())
4887 }
4888
4889 fn get(&self, idx: usize) -> Option<&u8> {
4890 if idx < self.len {
4891 unsafe { Some(self.data[idx].assume_init_ref()) }
4892 } else {
4893 None
4894 }
4895 }
4896
4897 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4898 if idx < self.len {
4899 unsafe { Some(self.data[idx].assume_init_mut()) }
4900 } else {
4901 None
4902 }
4903 }
4904 }
4905
4906 let len_kp: KpType<Buffer, usize> =
4908 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4909
4910 let mut buffer = Buffer::new();
4911
4912 assert_eq!(len_kp.get(&buffer), Some(&0));
4914
4915 buffer.push(1).unwrap();
4917 buffer.push(2).unwrap();
4918 buffer.push(3).unwrap();
4919
4920 assert_eq!(len_kp.get(&buffer), Some(&3));
4922
4923 assert_eq!(buffer.get(0), Some(&1));
4925 assert_eq!(buffer.get(1), Some(&2));
4926 assert_eq!(buffer.get(2), Some(&3));
4927 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4931 *elem = 20;
4932 }
4933 assert_eq!(buffer.get(1), Some(&20));
4934 }
4935
4936 #[test]
4937 fn test_kp_then_lock_deep_structs() {
4938 use std::sync::{Arc, Mutex};
4939
4940 #[derive(Clone)]
4941 struct Root {
4942 guard: Arc<Mutex<Level1>>,
4943 }
4944 #[derive(Clone)]
4945 struct Level1 {
4946 name: String,
4947 nested: Level2,
4948 }
4949 #[derive(Clone)]
4950 struct Level2 {
4951 count: i32,
4952 }
4953
4954 let root = Root {
4955 guard: Arc::new(Mutex::new(Level1 {
4956 name: "deep".to_string(),
4957 nested: Level2 { count: 42 },
4958 })),
4959 };
4960
4961 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4962 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4963
4964 let lock_kp = {
4965 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
4966 Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
4967 let next: KpType<Level1, Level1> =
4968 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4969 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4970 };
4971
4972 let chained = kp_to_guard.then_lock(lock_kp);
4973 let level1 = chained.get(&root);
4974 assert!(level1.is_some());
4975 assert_eq!(level1.unwrap().name, "deep");
4976 assert_eq!(level1.unwrap().nested.count, 42);
4977
4978 let mut_root = &mut root.clone();
4979 let mut_level1 = chained.get_mut(mut_root);
4980 assert!(mut_level1.is_some());
4981 mut_level1.unwrap().nested.count = 99;
4982 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4983 }
4984
4985 #[test]
4986 fn test_kp_then_lock_with_enum() {
4987 use std::sync::{Arc, Mutex};
4988
4989 #[derive(Clone)]
4990 enum Message {
4991 Request(LevelA),
4992 Response(i32),
4993 }
4994 #[derive(Clone)]
4995 struct LevelA {
4996 data: Arc<Mutex<i32>>,
4997 }
4998
4999 struct RootWithEnum {
5000 msg: Arc<Mutex<Message>>,
5001 }
5002
5003 let root = RootWithEnum {
5004 msg: Arc::new(Mutex::new(Message::Request(LevelA {
5005 data: Arc::new(Mutex::new(100)),
5006 }))),
5007 };
5008
5009 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
5010 Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
5011
5012 let lock_kp_msg = {
5013 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
5014 Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
5015 let next: KpType<Message, Message> =
5016 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
5017 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5018 };
5019
5020 let chained = kp_msg.then_lock(lock_kp_msg);
5021 let msg = chained.get(&root);
5022 assert!(msg.is_some());
5023 match msg.unwrap() {
5024 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
5025 Message::Response(_) => panic!("expected Request"),
5026 }
5027 }
5028
5029 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5030 #[tokio::test]
5031 async fn test_kp_then_async_deep_chain() {
5032 use std::sync::Arc;
5033 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5034
5035 #[derive(Clone)]
5036 struct Root {
5037 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
5038 }
5039 #[derive(Clone)]
5040 struct Level1 {
5041 value: i32,
5042 }
5043
5044 let root = Root {
5045 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
5046 };
5047
5048 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
5049 |r: &Root| Some(&r.tokio_guard),
5050 |r: &mut Root| Some(&mut r.tokio_guard),
5051 );
5052
5053 let async_kp = {
5054 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
5055 Kp::new(
5056 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
5057 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
5058 );
5059 let next: KpType<Level1, Level1> =
5060 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5061 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5062 };
5063
5064 let chained = kp_to_guard.then_async(async_kp);
5065 let level1 = chained.get(&root).await;
5066 assert!(level1.is_some());
5067 assert_eq!(level1.unwrap().value, 7);
5068 }
5069
5070 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5073 #[tokio::test]
5074 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
5075 use std::sync::{Arc, Mutex};
5076 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5077 use crate::lock::{LockKp, ArcMutexAccess};
5078
5079 #[derive(Clone)]
5081 struct Root {
5082 sync_mutex: Arc<Mutex<Level1>>,
5083 }
5084 #[derive(Clone)]
5086 struct Level1 {
5087 inner: Level2,
5088 }
5089 #[derive(Clone)]
5091 struct Level2 {
5092 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
5093 }
5094 #[derive(Clone)]
5096 struct Level3 {
5097 leaf: i32,
5098 }
5099
5100 let mut root = Root {
5101 sync_mutex: Arc::new(Mutex::new(Level1 {
5102 inner: Level2 {
5103 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
5104 },
5105 })),
5106 };
5107
5108 let identity_l1: KpType<Level1, Level1> =
5110 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5111 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
5112 Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
5113 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
5114
5115 let kp_l1_inner: KpType<Level1, Level2> =
5117 Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
5118
5119 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
5121 |l: &Level2| Some(&l.tokio_mutex),
5122 |l: &mut Level2| Some(&mut l.tokio_mutex),
5123 );
5124
5125 let async_l3 = {
5127 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
5128 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
5129 let next: KpType<Level3, Level3> =
5130 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
5131 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5132 };
5133
5134 let kp_l3_leaf: KpType<Level3, i32> =
5136 Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
5137
5138 let step1 = lock_root_to_l1.then(kp_l1_inner);
5140 let step2 = step1.then(kp_l2_tokio);
5141 let step3 = step2.then_async(async_l3);
5142 let deep_chain = step3.then(kp_l3_leaf);
5143
5144 let leaf = deep_chain.get(&root).await;
5146 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5147 assert_eq!(leaf, Some(&100));
5148
5149 let mut root_mut = root.clone();
5151 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5152 assert!(leaf_mut.is_some());
5153 *leaf_mut.unwrap() = 99;
5154
5155 let leaf_after = deep_chain.get(&root_mut).await;
5157 assert_eq!(leaf_after, Some(&99));
5158 }
5159}