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}
132
133#[macro_export]
154macro_rules! zip_with_kp {
155 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr) => {
156 match ($kp1.get($root), $kp2.get($root)) {
157 (Some(__a), Some(__b)) => Some($closure((__a, __b))),
158 _ => None,
159 }
160 };
161 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr) => {
162 match ($kp1.get($root), $kp2.get($root), $kp3.get($root)) {
163 (Some(__a), Some(__b), Some(__c)) => Some($closure((__a, __b, __c))),
164 _ => None,
165 }
166 };
167 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr) => {
168 match ($kp1.get($root), $kp2.get($root), $kp3.get($root), $kp4.get($root)) {
169 (Some(__a), Some(__b), Some(__c), Some(__d)) => Some($closure((__a, __b, __c, __d))),
170 _ => None,
171 }
172 };
173 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr) => {
174 match (
175 $kp1.get($root),
176 $kp2.get($root),
177 $kp3.get($root),
178 $kp4.get($root),
179 $kp5.get($root),
180 ) {
181 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e)) => {
182 Some($closure((__a, __b, __c, __d, __e)))
183 }
184 _ => None,
185 }
186 };
187 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr, $kp6:expr) => {
188 match (
189 $kp1.get($root),
190 $kp2.get($root),
191 $kp3.get($root),
192 $kp4.get($root),
193 $kp5.get($root),
194 $kp6.get($root),
195 ) {
196 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e), Some(__f)) => {
197 Some($closure((__a, __b, __c, __d, __e, __f)))
198 }
199 _ => None,
200 }
201 };
202}
203
204pub type KpValue<'a, R, V> = Kp<
206 R,
207 V,
208 &'a R,
209 V, &'a mut R,
211 V, for<'b> fn(&'b R) -> Option<V>,
213 for<'b> fn(&'b mut R) -> Option<V>,
214>;
215
216pub type KpOwned<R, V> = Kp<
218 R,
219 V,
220 R,
221 V, R,
223 V, fn(R) -> Option<V>,
225 fn(R) -> Option<V>,
226>;
227
228pub type KpRoot<R> = Kp<
230 R,
231 R,
232 R,
233 R, R,
235 R, fn(R) -> Option<R>,
237 fn(R) -> Option<R>,
238>;
239
240pub type KpVoid = Kp<
242 (),
243 (),
244 (),
245 (),
246 (),
247 (),
248 fn() -> Option<()>,
249 fn() -> Option<()>,
250>;
251
252
253
254
255pub type KpDynamic<R, V> = Kp<
256 R,
257 V,
258 &'static R,
259 &'static V,
260 &'static mut R,
261 &'static mut V,
262 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
263 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
264>;
265
266pub type KpBox<'a, R, V> = Kp<
267R, V,
268&'a R, &'a V,
269&'a mut R, &'a mut V,
270Box<dyn Fn(&'a R) -> Option<&'a V> + 'a>,
271Box<dyn Fn(&'a mut R) -> Option<&'a mut V> + 'a>,
272>;
273
274pub type KpArc<'a, R, V> = Kp<
275 R, V,
276 &'a R, &'a V,
277 &'a mut R, &'a mut V,
278 Arc<dyn Fn(&'a R) -> Option<&'a V> + Send + Sync + 'a>,
279 Arc<dyn Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync + 'a>,
280>;
281
282
283pub type KpType<'a, R, V> = Kp<
284 R,
285 V,
286 &'a R,
287 &'a V,
288 &'a mut R,
289 &'a mut V,
290 for<'b> fn(&'b R) -> Option<&'b V>,
291 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
292>;
293
294pub type KpOptionRefCellType<'a, R, V> = Kp<
297 R,
298 V,
299 &'a R,
300 std::cell::Ref<'a, V>,
301 &'a mut R,
302 std::cell::RefMut<'a, V>,
303 for<'b> fn(&'b R) -> Option<std::cell::Ref<'b, V>>,
304 for<'b> fn(&'b mut R) -> Option<std::cell::RefMut<'b, V>>,
305>;
306
307impl<'a, R, V> KpType<'a, R, V>
308where
309 'a: 'static,
310{
311 #[inline]
314 pub fn to_dynamic(self) -> KpDynamic<R, V> {
315 self.into()
316 }
317}
318
319impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V>
320where
321 'a: 'static,
322 R: 'static,
323 V: 'static,
324{
325 #[inline]
326 fn from(kp: KpType<'a, R, V>) -> Self {
327 let get_fn = kp.get;
328 let set_fn = kp.set;
329 Kp::new(
330 Box::new(move |t: &R| get_fn(t)),
331 Box::new(move |t: &mut R| set_fn(t)),
332 )
333 }
334}
335
336pub type KpComposed<R, V> = Kp<
372 R,
373 V,
374 &'static R,
375 &'static V,
376 &'static mut R,
377 &'static mut V,
378 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
379 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
380>;
381
382impl<R, V> Kp<
383 R,
384 V,
385 &'static R,
386 &'static V,
387 &'static mut R,
388 &'static mut V,
389 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
390 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
391> {
392 pub fn from_closures<G, S>(get: G, set: S) -> Self
395 where
396 G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
397 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
398 {
399 Self::new(Box::new(get), Box::new(set))
400 }
401}
402
403pub struct AKp {
404 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
405 root_type_id: TypeId,
406 value_type_id: TypeId,
407}
408
409impl AKp {
410 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
412 where
413 R: Any + 'static,
414 V: Any + 'static,
415 {
416 let root_type_id = TypeId::of::<R>();
417 let value_type_id = TypeId::of::<V>();
418 let getter_fn = keypath.get;
419
420 Self {
421 getter: Rc::new(move |any: &dyn Any| {
422 if let Some(root) = any.downcast_ref::<R>() {
423 getter_fn(root).map(|value: &V| value as &dyn Any)
424 } else {
425 None
426 }
427 }),
428 root_type_id,
429 value_type_id,
430 }
431 }
432
433 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
435 where
436 R: Any + 'static,
437 V: Any + 'static,
438 {
439 Self::new(keypath)
440 }
441
442 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
444 (self.getter)(root)
445 }
446
447 pub fn root_type_id(&self) -> TypeId {
449 self.root_type_id
450 }
451
452 pub fn value_type_id(&self) -> TypeId {
454 self.value_type_id
455 }
456
457 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
459 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
460 {
461 Some(
462 self.get(root as &dyn Any)
463 .and_then(|any| any.downcast_ref::<Value>()),
464 )
465 } else {
466 None
467 }
468 }
469
470 pub fn kind_name(&self) -> String {
472 format!("{:?}", self.value_type_id)
473 }
474
475 pub fn root_kind_name(&self) -> String {
477 format!("{:?}", self.root_type_id)
478 }
479
480 pub fn for_arc<Root>(&self) -> AKp
482 where
483 Root: Any + 'static,
484 {
485 let value_type_id = self.value_type_id;
486 let getter = self.getter.clone();
487
488 AKp {
489 getter: Rc::new(move |any: &dyn Any| {
490 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
491 getter(arc.as_ref() as &dyn Any)
492 } else {
493 None
494 }
495 }),
496 root_type_id: TypeId::of::<Arc<Root>>(),
497 value_type_id,
498 }
499 }
500
501 pub fn for_box<Root>(&self) -> AKp
503 where
504 Root: Any + 'static,
505 {
506 let value_type_id = self.value_type_id;
507 let getter = self.getter.clone();
508
509 AKp {
510 getter: Rc::new(move |any: &dyn Any| {
511 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
512 getter(boxed.as_ref() as &dyn Any)
513 } else {
514 None
515 }
516 }),
517 root_type_id: TypeId::of::<Box<Root>>(),
518 value_type_id,
519 }
520 }
521
522 pub fn for_rc<Root>(&self) -> AKp
524 where
525 Root: Any + 'static,
526 {
527 let value_type_id = self.value_type_id;
528 let getter = self.getter.clone();
529
530 AKp {
531 getter: Rc::new(move |any: &dyn Any| {
532 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
533 getter(rc.as_ref() as &dyn Any)
534 } else {
535 None
536 }
537 }),
538 root_type_id: TypeId::of::<Rc<Root>>(),
539 value_type_id,
540 }
541 }
542
543 pub fn for_option<Root>(&self) -> AKp
545 where
546 Root: Any + 'static,
547 {
548 let value_type_id = self.value_type_id;
549 let getter = self.getter.clone();
550
551 AKp {
552 getter: Rc::new(move |any: &dyn Any| {
553 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
554 opt.as_ref().and_then(|root| getter(root as &dyn Any))
555 } else {
556 None
557 }
558 }),
559 root_type_id: TypeId::of::<Option<Root>>(),
560 value_type_id,
561 }
562 }
563
564 pub fn for_result<Root, E>(&self) -> AKp
566 where
567 Root: Any + 'static,
568 E: Any + 'static,
569 {
570 let value_type_id = self.value_type_id;
571 let getter = self.getter.clone();
572
573 AKp {
574 getter: Rc::new(move |any: &dyn Any| {
575 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
576 result
577 .as_ref()
578 .ok()
579 .and_then(|root| getter(root as &dyn Any))
580 } else {
581 None
582 }
583 }),
584 root_type_id: TypeId::of::<Result<Root, E>>(),
585 value_type_id,
586 }
587 }
588
589 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
602 where
603 Root: Any + 'static,
604 OrigValue: Any + 'static,
605 MappedValue: Any + 'static,
606 F: Fn(&OrigValue) -> MappedValue + 'static,
607 {
608 let orig_root_type_id = self.root_type_id;
609 let orig_value_type_id = self.value_type_id;
610 let getter = self.getter.clone();
611 let mapped_type_id = TypeId::of::<MappedValue>();
612
613 AKp {
614 getter: Rc::new(move |any_root: &dyn Any| {
615 if any_root.type_id() == orig_root_type_id {
617 getter(any_root).and_then(|any_value| {
618 if orig_value_type_id == TypeId::of::<OrigValue>() {
620 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
621 let mapped = mapper(orig_val);
622 Box::leak(Box::new(mapped)) as &dyn Any
624 })
625 } else {
626 None
627 }
628 })
629 } else {
630 None
631 }
632 }),
633 root_type_id: orig_root_type_id,
634 value_type_id: mapped_type_id,
635 }
636 }
637
638 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
651 where
652 Root: Any + 'static,
653 Value: Any + 'static,
654 F: Fn(&Value) -> bool + 'static,
655 {
656 let orig_root_type_id = self.root_type_id;
657 let orig_value_type_id = self.value_type_id;
658 let getter = self.getter.clone();
659
660 AKp {
661 getter: Rc::new(move |any_root: &dyn Any| {
662 if any_root.type_id() == orig_root_type_id {
664 getter(any_root).filter(|any_value| {
665 if orig_value_type_id == TypeId::of::<Value>() {
667 any_value
668 .downcast_ref::<Value>()
669 .map(|val| predicate(val))
670 .unwrap_or(false)
671 } else {
672 false
673 }
674 })
675 } else {
676 None
677 }
678 }),
679 root_type_id: orig_root_type_id,
680 value_type_id: orig_value_type_id,
681 }
682 }
683}
684pub struct PKp<Root> {
685 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
686 value_type_id: TypeId,
687 _phantom: std::marker::PhantomData<Root>,
688}
689
690impl<Root> PKp<Root>
691where
692 Root: 'static,
693{
694 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
696 where
697 V: Any + 'static,
698 {
699 let value_type_id = TypeId::of::<V>();
700 let getter_fn = keypath.get;
701
702 Self {
703 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
704 value_type_id,
705 _phantom: std::marker::PhantomData,
706 }
707 }
708
709 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
711 where
712 V: Any + 'static,
713 {
714 Self::new(keypath)
715 }
716
717 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
719 (self.getter)(root)
720 }
721
722 pub fn value_type_id(&self) -> TypeId {
724 self.value_type_id
725 }
726
727 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
729 if self.value_type_id == TypeId::of::<Value>() {
730 self.get(root).and_then(|any| any.downcast_ref::<Value>())
731 } else {
732 None
733 }
734 }
735
736 pub fn kind_name(&self) -> String {
738 format!("{:?}", self.value_type_id)
739 }
740
741 pub fn for_arc(&self) -> PKp<Arc<Root>> {
743 let getter = self.getter.clone();
744 let value_type_id = self.value_type_id;
745
746 PKp {
747 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
748 value_type_id,
749 _phantom: std::marker::PhantomData,
750 }
751 }
752
753 pub fn for_box(&self) -> PKp<Box<Root>> {
755 let getter = self.getter.clone();
756 let value_type_id = self.value_type_id;
757
758 PKp {
759 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
760 value_type_id,
761 _phantom: std::marker::PhantomData,
762 }
763 }
764
765 pub fn for_rc(&self) -> PKp<Rc<Root>> {
767 let getter = self.getter.clone();
768 let value_type_id = self.value_type_id;
769
770 PKp {
771 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
772 value_type_id,
773 _phantom: std::marker::PhantomData,
774 }
775 }
776
777 pub fn for_option(&self) -> PKp<Option<Root>> {
779 let getter = self.getter.clone();
780 let value_type_id = self.value_type_id;
781
782 PKp {
783 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
784 value_type_id,
785 _phantom: std::marker::PhantomData,
786 }
787 }
788
789 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
791 where
792 E: 'static,
793 {
794 let getter = self.getter.clone();
795 let value_type_id = self.value_type_id;
796
797 PKp {
798 getter: Rc::new(move |result: &Result<Root, E>| {
799 result.as_ref().ok().and_then(|root| getter(root))
800 }),
801 value_type_id,
802 _phantom: std::marker::PhantomData,
803 }
804 }
805
806 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
820 where
821 OrigValue: Any + 'static,
822 MappedValue: Any + 'static,
823 F: Fn(&OrigValue) -> MappedValue + 'static,
824 {
825 let orig_type_id = self.value_type_id;
826 let getter = self.getter.clone();
827 let mapped_type_id = TypeId::of::<MappedValue>();
828
829 PKp {
830 getter: Rc::new(move |root: &Root| {
831 getter(root).and_then(|any_value| {
832 if orig_type_id == TypeId::of::<OrigValue>() {
834 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
835 let mapped = mapper(orig_val);
836 Box::leak(Box::new(mapped)) as &dyn Any
839 })
840 } else {
841 None
842 }
843 })
844 }),
845 value_type_id: mapped_type_id,
846 _phantom: std::marker::PhantomData,
847 }
848 }
849
850 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
864 where
865 Value: Any + 'static,
866 F: Fn(&Value) -> bool + 'static,
867 {
868 let orig_type_id = self.value_type_id;
869 let getter = self.getter.clone();
870
871 PKp {
872 getter: Rc::new(move |root: &Root| {
873 getter(root).filter(|any_value| {
874 if orig_type_id == TypeId::of::<Value>() {
876 any_value
877 .downcast_ref::<Value>()
878 .map(|val| predicate(val))
879 .unwrap_or(false)
880 } else {
881 false
882 }
883 })
884 }),
885 value_type_id: orig_type_id,
886 _phantom: std::marker::PhantomData,
887 }
888 }
889}
890
891#[derive(Clone)]
905pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
906where
907 Root: std::borrow::Borrow<R>,
908 MutRoot: std::borrow::BorrowMut<R>,
909 MutValue: std::borrow::BorrowMut<V>,
910 G: Fn(Root) -> Option<Value>,
911 S: Fn(MutRoot) -> Option<MutValue>,
912{
913 pub(crate) get: G,
915 pub(crate) set: S,
917 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
918}
919
920unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Send for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
922where
923 Root: std::borrow::Borrow<R>,
924 MutRoot: std::borrow::BorrowMut<R>,
925 MutValue: std::borrow::BorrowMut<V>,
926 G: Fn(Root) -> Option<Value> + Send,
927 S: Fn(MutRoot) -> Option<MutValue> + Send,
928{
929}
930unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Sync for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
931where
932 Root: std::borrow::Borrow<R>,
933 MutRoot: std::borrow::BorrowMut<R>,
934 MutValue: std::borrow::BorrowMut<V>,
935 G: Fn(Root) -> Option<Value> + Sync,
936 S: Fn(MutRoot) -> Option<MutValue> + Sync,
937{
938}
939
940impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
941where
942 Root: std::borrow::Borrow<R>,
943 Value: std::borrow::Borrow<V>,
944 MutRoot: std::borrow::BorrowMut<R>,
945 MutValue: std::borrow::BorrowMut<V>,
946 G: Fn(Root) -> Option<Value>,
947 S: Fn(MutRoot) -> Option<MutValue>,
948{
949 pub fn new(get: G, set: S) -> Self {
950 Self {
951 get: get,
952 set: set,
953 _p: std::marker::PhantomData,
954 }
955 }
956
957 pub const fn new_const(get: G, set: S) -> Self {
958 Self {
959 get: get,
960 set: set,
961 _p: std::marker::PhantomData,
962 }
963 }
964
965
966 #[inline]
967 pub fn get(&self, root: Root) -> Option<Value> {
968 (self.get)(root)
969 }
970 #[inline]
971 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
972 (self.set)(root)
973 }
974
975 #[inline]
977 pub fn get_optional(&self, root: Option<Root>) -> Option<Value> {
978 root.and_then(|r| (self.get)(r))
979 }
980
981 #[inline]
983 pub fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue> {
984 root.and_then(|r| (self.set)(r))
985 }
986
987 #[inline]
989 pub fn get_or_else<F>(&self, root: Root, f: F) -> Value
990 where
991 F: FnOnce() -> Value,
992 {
993 (self.get)(root).unwrap_or_else(f)
994 }
995
996 #[inline]
998 pub fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
999 where
1000 F: FnOnce() -> MutValue,
1001 {
1002 (self.set)(root).unwrap_or_else(f)
1003 }
1004
1005 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
1006 self,
1007 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1008 ) -> Kp<
1009 R,
1010 SV,
1011 Root,
1012 SubValue,
1013 MutRoot,
1014 MutSubValue,
1015 impl Fn(Root) -> Option<SubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
1016 impl Fn(MutRoot) -> Option<MutSubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
1017 >
1018 where
1019 SubValue: std::borrow::Borrow<SV>,
1020 MutSubValue: std::borrow::BorrowMut<SV>,
1021 G2: Fn(Value) -> Option<SubValue>,
1022 S2: Fn(MutValue) -> Option<MutSubValue>,
1023 V: 'static,
1024 {
1025 Kp::new(
1026 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
1027 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
1028 )
1029 }
1030
1031 pub fn then_lock<
1033 Lock,
1034 Mid,
1035 V2,
1036 LockValue,
1037 MidValue,
1038 Value2,
1039 MutLock,
1040 MutMid,
1041 MutValue2,
1042 G1,
1043 S1,
1044 L,
1045 G2,
1046 S2,
1047 >(
1048 self,
1049 lock_kp: crate::lock::LockKp<
1050 V,
1051 Lock,
1052 Mid,
1053 V2,
1054 Value,
1055 LockValue,
1056 MidValue,
1057 Value2,
1058 MutValue,
1059 MutLock,
1060 MutMid,
1061 MutValue2,
1062 G1,
1063 S1,
1064 L,
1065 G2,
1066 S2,
1067 >,
1068 ) -> 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>>
1069 where
1070 V: 'static + Clone,
1071 V2: 'static,
1072 Value: std::borrow::Borrow<V>,
1073 Value2: std::borrow::Borrow<V2>,
1074 MutValue: std::borrow::BorrowMut<V>,
1075 MutValue2: std::borrow::BorrowMut<V2>,
1076 LockValue: std::borrow::Borrow<Lock>,
1077 MidValue: std::borrow::Borrow<Mid>,
1078 MutLock: std::borrow::BorrowMut<Lock>,
1079 MutMid: std::borrow::BorrowMut<Mid>,
1080 G1: Fn(Value) -> Option<LockValue>,
1081 S1: Fn(MutValue) -> Option<MutLock>,
1082 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
1083 G2: Fn(MidValue) -> Option<Value2>,
1084 S2: Fn(MutMid) -> Option<MutValue2>,
1085 {
1086 crate::lock::KpThenLockKp {
1087 first: self,
1088 second: lock_kp,
1089 _p: std::marker::PhantomData,
1090 }
1091 }
1092
1093 #[cfg(feature = "pin_project")]
1096 pub fn then_pin_future<Struct, Output, L>(
1097 self,
1098 pin_fut: L,
1099 ) -> crate::pin::KpThenPinFuture<
1100 R,
1101 Struct,
1102 Output,
1103 Root,
1104 MutRoot,
1105 Value,
1106 MutValue,
1107 Self,
1108 L,
1109 >
1110 where
1111 V: 'static,
1112 Struct: Unpin + 'static,
1113 Output: 'static,
1114 Value: std::borrow::Borrow<Struct>,
1115 MutValue: std::borrow::BorrowMut<Struct>,
1116 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
1117 {
1118 crate::pin::KpThenPinFuture {
1119 first: self,
1120 second: pin_fut,
1121 _p: std::marker::PhantomData,
1122 }
1123 }
1124
1125 pub fn then_async<AsyncKp>(
1128 self,
1129 async_kp: AsyncKp,
1130 ) -> crate::async_lock::KpThenAsyncKeyPath<
1131 R,
1132 V,
1133 <AsyncKp::Value as KeyPathValueTarget>::Target,
1134 Root,
1135 Value,
1136 AsyncKp::Value,
1137 MutRoot,
1138 MutValue,
1139 AsyncKp::MutValue,
1140 Self,
1141 AsyncKp,
1142 >
1143 where
1144 V: 'static,
1145 Value: std::borrow::Borrow<V>,
1146 MutValue: std::borrow::BorrowMut<V>,
1147 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
1148 AsyncKp::Value: KeyPathValueTarget
1149 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1150 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1151 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
1152 {
1153 crate::async_lock::KpThenAsyncKeyPath {
1154 first: self,
1155 second: async_kp,
1156 _p: std::marker::PhantomData,
1157 }
1158 }
1159
1160 pub fn map<MappedValue, F>(
1173 &self,
1174 mapper: F,
1175 ) -> Kp<
1176 R,
1177 MappedValue,
1178 Root,
1179 MappedValue,
1180 MutRoot,
1181 MappedValue,
1182 impl Fn(Root) -> Option<MappedValue>,
1183 impl Fn(MutRoot) -> Option<MappedValue>,
1184 >
1185 where
1186 F: Fn(&V) -> MappedValue + Copy + 'static,
1189 V: 'static,
1190 MappedValue: 'static,
1191 {
1192 Kp::new(
1193 move |root: Root| {
1194 (&self.get)(root).map(|value| {
1195 let v: &V = value.borrow();
1196 mapper(v)
1197 })
1198 },
1199 move |root: MutRoot| {
1200 (&self.set)(root).map(|value| {
1201 let v: &V = value.borrow();
1202 mapper(v)
1203 })
1204 },
1205 )
1206 }
1207
1208 pub fn zip<V2, Value2, MutValue2, G2, S2>(
1226 self,
1227 other: Kp<R, V2, Root, Value2, MutRoot, MutValue2, G2, S2>,
1228 ) -> Kp<
1229 R,
1230 (Value, Value2),
1231 Root,
1232 (Value, Value2),
1233 MutRoot,
1234 (Value, Value2),
1235 impl Fn(Root) -> Option<(Value, Value2)>,
1236 impl Fn(MutRoot) -> Option<(Value, Value2)>,
1237 >
1238 where
1239 Root: Copy,
1240 Value2: std::borrow::Borrow<V2>,
1241 MutValue2: std::borrow::BorrowMut<V2>,
1242 G2: Fn(Root) -> Option<Value2>,
1243 S2: Fn(MutRoot) -> Option<MutValue2>,
1244 V2: 'static,
1245 {
1246 let first_get = self.get;
1247 let second_get = other.get;
1248 Kp::new(
1249 move |root: Root| {
1250 let a = (first_get)(root);
1251 let b = (second_get)(root);
1252 match (a, b) {
1253 (Some(a), Some(b)) => Some((a, b)),
1254 _ => None,
1255 }
1256 },
1257 move |_root: MutRoot| None::<(Value, Value2)>,
1259 )
1260 }
1261
1262 pub fn zip_with<V2, Value2, MutValue2, Z, G2, S2, F>(
1279 self,
1280 other: Kp<R, V2, Root, Value2, MutRoot, MutValue2, G2, S2>,
1281 transform: F,
1282 ) -> Kp<R, Z, Root, Z, MutRoot, Z, impl Fn(Root) -> Option<Z>, impl Fn(MutRoot) -> Option<Z>>
1283 where
1284 Root: Copy,
1285 Value2: std::borrow::Borrow<V2>,
1286 MutValue2: std::borrow::BorrowMut<V2>,
1287 G2: Fn(Root) -> Option<Value2>,
1288 S2: Fn(MutRoot) -> Option<MutValue2>,
1289 F: Fn(Value, Value2) -> Z + Copy + 'static,
1290 V2: 'static,
1291 Z: 'static,
1292 {
1293 let first_get = self.get;
1294 let second_get = other.get;
1295 Kp::new(
1296 move |root: Root| {
1297 let a = (first_get)(root);
1298 let b = (second_get)(root);
1299 match (a, b) {
1300 (Some(a), Some(b)) => Some(transform(a, b)),
1301 _ => None,
1302 }
1303 },
1304 move |_root: MutRoot| None::<Z>,
1305 )
1306 }
1307
1308 pub fn filter<F>(
1321 &self,
1322 predicate: F,
1323 ) -> Kp<
1324 R,
1325 V,
1326 Root,
1327 Value,
1328 MutRoot,
1329 MutValue,
1330 impl Fn(Root) -> Option<Value>,
1331 impl Fn(MutRoot) -> Option<MutValue>,
1332 >
1333 where
1334 F: Fn(&V) -> bool + Copy + 'static,
1337 V: 'static,
1338 {
1339 Kp::new(
1340 move |root: Root| {
1341 (&self.get)(root).filter(|value| {
1342 let v: &V = value.borrow();
1343 predicate(v)
1344 })
1345 },
1346 move |root: MutRoot| {
1347 (&self.set)(root).filter(|value| {
1348 let v: &V = value.borrow();
1349 predicate(v)
1350 })
1351 },
1352 )
1353 }
1354
1355 pub fn filter_map<MappedValue, F>(
1368 &self,
1369 mapper: F,
1370 ) -> Kp<
1371 R,
1372 MappedValue,
1373 Root,
1374 MappedValue,
1375 MutRoot,
1376 MappedValue,
1377 impl Fn(Root) -> Option<MappedValue>,
1378 impl Fn(MutRoot) -> Option<MappedValue>,
1379 >
1380 where
1381 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1384 V: 'static,
1385 MappedValue: 'static,
1386 {
1387 Kp::new(
1388 move |root: Root| {
1389 (&self.get)(root).and_then(|value| {
1390 let v: &V = value.borrow();
1391 mapper(v)
1392 })
1393 },
1394 move |root: MutRoot| {
1395 (&self.set)(root).and_then(|value| {
1396 let v: &V = value.borrow();
1397 mapper(v)
1398 })
1399 },
1400 )
1401 }
1402
1403 pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
1415 where
1416 F: Fn(&V) -> I + 'static,
1419 V: 'static,
1420 I: IntoIterator<Item = Item>,
1421 Item: 'static,
1422 {
1423 move |root: Root| {
1424 (&self.get)(root)
1425 .map(|value| {
1426 let v: &V = value.borrow();
1427 mapper(v).into_iter().collect()
1428 })
1429 .unwrap_or_else(Vec::new)
1430 }
1431 }
1432
1433 pub fn inspect<F>(
1444 &self,
1445 inspector: F,
1446 ) -> Kp<
1447 R,
1448 V,
1449 Root,
1450 Value,
1451 MutRoot,
1452 MutValue,
1453 impl Fn(Root) -> Option<Value>,
1454 impl Fn(MutRoot) -> Option<MutValue>,
1455 >
1456 where
1457 F: Fn(&V) + Copy + 'static,
1460 V: 'static,
1461 {
1462 Kp::new(
1463 move |root: Root| {
1464 (&self.get)(root).map(|value| {
1465 let v: &V = value.borrow();
1466 inspector(v);
1467 value
1468 })
1469 },
1470 move |root: MutRoot| {
1471 (&self.set)(root).map(|value| {
1472 let v: &V = value.borrow();
1473 inspector(v);
1474 value
1475 })
1476 },
1477 )
1478 }
1479
1480 pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
1494 where
1495 F: Fn(Acc, &V) -> Acc + 'static,
1498 V: 'static,
1499 Acc: Copy + 'static,
1501 {
1502 move |root: Root| {
1503 (&self.get)(root)
1504 .map(|value| {
1505 let v: &V = value.borrow();
1506 folder(init, v)
1507 })
1508 .unwrap_or(init)
1509 }
1510 }
1511
1512 pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1524 where
1525 F: Fn(&V) -> bool + 'static,
1528 V: 'static,
1529 {
1530 move |root: Root| {
1531 (&self.get)(root)
1532 .map(|value| {
1533 let v: &V = value.borrow();
1534 predicate(v)
1535 })
1536 .unwrap_or(false)
1537 }
1538 }
1539
1540 pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1552 where
1553 F: Fn(&V) -> bool + 'static,
1556 V: 'static,
1557 {
1558 move |root: Root| {
1559 (&self.get)(root)
1560 .map(|value| {
1561 let v: &V = value.borrow();
1562 predicate(v)
1563 })
1564 .unwrap_or(true)
1565 }
1566 }
1567
1568 pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
1580 where
1581 F: Fn(&V) -> usize + 'static,
1584 V: 'static,
1585 {
1586 move |root: Root| {
1587 (&self.get)(root).map(|value| {
1588 let v: &V = value.borrow();
1589 counter(v)
1590 })
1591 }
1592 }
1593
1594 pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
1608 where
1609 F: Fn(&V) -> Option<Item> + 'static,
1612 V: 'static,
1613 Item: 'static,
1614 {
1615 move |root: Root| {
1616 (&self.get)(root).and_then(|value| {
1617 let v: &V = value.borrow();
1618 finder(v)
1619 })
1620 }
1621 }
1622
1623 pub fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output>
1634 where
1635 F: Fn(&V, usize) -> Output + 'static,
1638 V: 'static,
1639 Output: 'static,
1640 {
1641 move |root: Root| {
1642 (&self.get)(root).map(|value| {
1643 let v: &V = value.borrow();
1644 taker(v, n)
1645 })
1646 }
1647 }
1648
1649 pub fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output>
1660 where
1661 F: Fn(&V, usize) -> Output + 'static,
1664 V: 'static,
1665 Output: 'static,
1666 {
1667 move |root: Root| {
1668 (&self.get)(root).map(|value| {
1669 let v: &V = value.borrow();
1670 skipper(v, n)
1671 })
1672 }
1673 }
1674
1675 pub fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output>
1688 where
1689 F: Fn(&V) -> Output + 'static,
1692 V: 'static,
1693 Output: 'static,
1694 {
1695 move |root: Root| {
1696 (&self.get)(root).map(|value| {
1697 let v: &V = value.borrow();
1698 partitioner(v)
1699 })
1700 }
1701 }
1702
1703 pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
1715 where
1716 F: Fn(&V) -> Option<Item> + 'static,
1719 V: 'static,
1720 Item: 'static,
1721 {
1722 move |root: Root| {
1723 (&self.get)(root).and_then(|value| {
1724 let v: &V = value.borrow();
1725 min_fn(v)
1726 })
1727 }
1728 }
1729
1730 pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
1742 where
1743 F: Fn(&V) -> Option<Item> + 'static,
1746 V: 'static,
1747 Item: 'static,
1748 {
1749 move |root: Root| {
1750 (&self.get)(root).and_then(|value| {
1751 let v: &V = value.borrow();
1752 max_fn(v)
1753 })
1754 }
1755 }
1756
1757 pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
1769 where
1770 F: Fn(&V) -> Sum + 'static,
1773 V: 'static,
1774 Sum: 'static,
1775 {
1776 move |root: Root| {
1777 (&self.get)(root).map(|value| {
1778 let v: &V = value.borrow();
1779 sum_fn(v)
1780 })
1781 }
1782 }
1783
1784 pub fn chain<SV, SubValue, MutSubValue, G2, S2>(
1787 self,
1788 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1789 ) -> Kp<
1790 R,
1791 SV,
1792 Root,
1793 SubValue,
1794 MutRoot,
1795 MutSubValue,
1796 impl Fn(Root) -> Option<SubValue>,
1797 impl Fn(MutRoot) -> Option<MutSubValue>,
1798 >
1799 where
1800 SubValue: std::borrow::Borrow<SV>,
1801 MutSubValue: std::borrow::BorrowMut<SV>,
1802 G2: Fn(Value) -> Option<SubValue>,
1803 S2: Fn(MutValue) -> Option<MutSubValue>,
1804 V: 'static,
1805 {
1806 self.then(next)
1807 }
1808
1809 pub fn for_arc<'b>(
1810 &self,
1811 ) -> Kp<
1812 std::sync::Arc<R>,
1813 V,
1814 std::sync::Arc<R>,
1815 Value,
1816 std::sync::Arc<R>,
1817 MutValue,
1818 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1819 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1820 >
1821 where
1822 R: 'b,
1823 V: 'b,
1824 Root: for<'a> From<&'a R>,
1825 MutRoot: for<'a> From<&'a mut R>,
1826 {
1827 Kp::new(
1828 move |arc_root: std::sync::Arc<R>| {
1829 let r_ref: &R = &*arc_root;
1830 (&self.get)(Root::from(r_ref))
1831 },
1832 move |mut arc_root: std::sync::Arc<R>| {
1833 std::sync::Arc::get_mut(&mut arc_root)
1835 .and_then(|r_mut| (&self.set)(MutRoot::from(r_mut)))
1836 },
1837 )
1838 }
1839
1840 pub fn for_box<'a>(
1841 &self,
1842 ) -> Kp<
1843 Box<R>,
1844 V,
1845 Box<R>,
1846 Value,
1847 Box<R>,
1848 MutValue,
1849 impl Fn(Box<R>) -> Option<Value>,
1850 impl Fn(Box<R>) -> Option<MutValue>,
1851 >
1852 where
1853 R: 'a,
1854 V: 'a,
1855 Root: for<'b> From<&'b R>,
1856 MutRoot: for<'b> From<&'b mut R>,
1857 {
1858 Kp::new(
1859 move |r: Box<R>| {
1860 let r_ref: &R = r.as_ref();
1861 (&self.get)(Root::from(r_ref))
1862 },
1863 move |mut r: Box<R>| {
1864 (self.set)(MutRoot::from(r.as_mut()))
1866 },
1867 )
1868 }
1869}
1870
1871pub fn zip_kps<'a, RootType, Value1, Value2>(
1885 kp1: &'a KpType<'a, RootType, Value1>,
1886 kp2: &'a KpType<'a, RootType, Value2>,
1887) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1888where
1889 RootType: 'a,
1890 Value1: 'a,
1891 Value2: 'a,
1892{
1893 move |root: &'a RootType| {
1894 let val1 = (kp1.get)(root)?;
1895 let val2 = (kp2.get)(root)?;
1896 Some((val1, val2))
1897 }
1898}
1899
1900impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1901where
1902 Root: std::borrow::Borrow<R>,
1903 MutRoot: std::borrow::BorrowMut<R>,
1904 G: Fn(Root) -> Option<Root>,
1905 S: Fn(MutRoot) -> Option<MutRoot>,
1906{
1907 pub fn identity_typed() -> Kp<
1908 R,
1909 R,
1910 Root,
1911 Root,
1912 MutRoot,
1913 MutRoot,
1914 fn(Root) -> Option<Root>,
1915 fn(MutRoot) -> Option<MutRoot>,
1916 > {
1917 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1918 }
1919
1920 pub fn identity<'a>() -> KpType<'a, R, R> {
1921 KpType::new(|r| Some(r), |r| Some(r))
1922 }
1923}
1924
1925pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1934where
1935 Root: std::borrow::Borrow<Enum>,
1936 Value: std::borrow::Borrow<Variant>,
1937 MutRoot: std::borrow::BorrowMut<Enum>,
1938 MutValue: std::borrow::BorrowMut<Variant>,
1939 G: Fn(Root) -> Option<Value>,
1940 S: Fn(MutRoot) -> Option<MutValue>,
1941 E: Fn(Variant) -> Enum,
1942{
1943 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1944 embedder: E,
1945}
1946
1947unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1949 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1950where
1951 Root: std::borrow::Borrow<Enum>,
1952 Value: std::borrow::Borrow<Variant>,
1953 MutRoot: std::borrow::BorrowMut<Enum>,
1954 MutValue: std::borrow::BorrowMut<Variant>,
1955 G: Fn(Root) -> Option<Value> + Send,
1956 S: Fn(MutRoot) -> Option<MutValue> + Send,
1957 E: Fn(Variant) -> Enum + Send,
1958{
1959}
1960unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1961 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1962where
1963 Root: std::borrow::Borrow<Enum>,
1964 Value: std::borrow::Borrow<Variant>,
1965 MutRoot: std::borrow::BorrowMut<Enum>,
1966 MutValue: std::borrow::BorrowMut<Variant>,
1967 G: Fn(Root) -> Option<Value> + Sync,
1968 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1969 E: Fn(Variant) -> Enum + Sync,
1970{
1971}
1972
1973impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1974 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1975where
1976 Root: std::borrow::Borrow<Enum>,
1977 Value: std::borrow::Borrow<Variant>,
1978 MutRoot: std::borrow::BorrowMut<Enum>,
1979 MutValue: std::borrow::BorrowMut<Variant>,
1980 G: Fn(Root) -> Option<Value>,
1981 S: Fn(MutRoot) -> Option<MutValue>,
1982 E: Fn(Variant) -> Enum,
1983{
1984 pub fn new(
1986 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1987 embedder: E,
1988 ) -> Self {
1989 Self {
1990 extractor,
1991 embedder,
1992 }
1993 }
1994
1995 pub fn get(&self, enum_value: Root) -> Option<Value> {
1997 self.extractor.get(enum_value)
1998 }
1999
2000 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
2002 self.extractor.get_mut(enum_value)
2003 }
2004
2005 pub fn embed(&self, value: Variant) -> Enum {
2007 (self.embedder)(value)
2008 }
2009
2010 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2012 &self.extractor
2013 }
2014
2015 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2017 self.extractor
2018 }
2019
2020 pub fn map<MappedValue, F>(
2031 &self,
2032 mapper: F,
2033 ) -> EnumKp<
2034 Enum,
2035 MappedValue,
2036 Root,
2037 MappedValue,
2038 MutRoot,
2039 MappedValue,
2040 impl Fn(Root) -> Option<MappedValue>,
2041 impl Fn(MutRoot) -> Option<MappedValue>,
2042 impl Fn(MappedValue) -> Enum,
2043 >
2044 where
2045 F: Fn(&Variant) -> MappedValue + Copy + 'static,
2048 Variant: 'static,
2049 MappedValue: 'static,
2050 E: Fn(Variant) -> Enum + Copy + 'static,
2052 {
2053 let mapped_extractor = self.extractor.map(mapper);
2054
2055 let new_embedder = move |_value: MappedValue| -> Enum {
2059 panic!(
2060 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
2061 )
2062 };
2063
2064 EnumKp::new(mapped_extractor, new_embedder)
2065 }
2066
2067 pub fn filter<F>(
2079 &self,
2080 predicate: F,
2081 ) -> EnumKp<
2082 Enum,
2083 Variant,
2084 Root,
2085 Value,
2086 MutRoot,
2087 MutValue,
2088 impl Fn(Root) -> Option<Value>,
2089 impl Fn(MutRoot) -> Option<MutValue>,
2090 E,
2091 >
2092 where
2093 F: Fn(&Variant) -> bool + Copy + 'static,
2096 Variant: 'static,
2097 E: Copy,
2099 {
2100 let filtered_extractor = self.extractor.filter(predicate);
2101 EnumKp::new(filtered_extractor, self.embedder)
2102 }
2103}
2104
2105pub type EnumKpType<'a, Enum, Variant> = EnumKp<
2107 Enum,
2108 Variant,
2109 &'a Enum,
2110 &'a Variant,
2111 &'a mut Enum,
2112 &'a mut Variant,
2113 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2114 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2115 fn(Variant) -> Enum,
2116>;
2117
2118pub fn enum_variant<'a, Enum, Variant>(
2136 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2137 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2138 embedder: fn(Variant) -> Enum,
2139) -> EnumKpType<'a, Enum, Variant> {
2140 EnumKp::new(Kp::new(getter, setter), embedder)
2141}
2142
2143pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
2153 EnumKp::new(
2154 Kp::new(
2155 |r: &Result<T, E>| r.as_ref().ok(),
2156 |r: &mut Result<T, E>| r.as_mut().ok(),
2157 ),
2158 |t: T| Ok(t),
2159 )
2160}
2161
2162pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
2172 EnumKp::new(
2173 Kp::new(
2174 |r: &Result<T, E>| r.as_ref().err(),
2175 |r: &mut Result<T, E>| r.as_mut().err(),
2176 ),
2177 |e: E| Err(e),
2178 )
2179}
2180
2181pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
2191 EnumKp::new(
2192 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
2193 |t: T| Some(t),
2194 )
2195}
2196
2197pub fn variant_of<'a, Enum, Variant>(
2215 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2216 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2217 embedder: fn(Variant) -> Enum,
2218) -> EnumKpType<'a, Enum, Variant> {
2219 enum_variant(getter, setter, embedder)
2220}
2221
2222pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
2235 Kp::new(
2236 |b: &Box<T>| Some(b.as_ref()),
2237 |b: &mut Box<T>| Some(b.as_mut()),
2238 )
2239}
2240
2241pub fn kp_arc<'a, T>() -> Kp<
2252 Arc<T>,
2253 T,
2254 &'a Arc<T>,
2255 &'a T,
2256 &'a mut Arc<T>,
2257 &'a mut T,
2258 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
2259 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
2260> {
2261 Kp::new(
2262 |arc: &Arc<T>| Some(arc.as_ref()),
2263 |arc: &mut Arc<T>| Arc::get_mut(arc),
2264 )
2265}
2266
2267pub fn kp_rc<'a, T>() -> Kp<
2278 std::rc::Rc<T>,
2279 T,
2280 &'a std::rc::Rc<T>,
2281 &'a T,
2282 &'a mut std::rc::Rc<T>,
2283 &'a mut T,
2284 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
2285 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
2286> {
2287 Kp::new(
2288 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
2289 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
2290 )
2291}
2292
2293use std::any::{Any, TypeId};
2296use std::rc::Rc;
2297
2298#[cfg(test)]
2313mod tests {
2314 use super::*;
2315 use std::collections::HashMap;
2316
2317 #[derive(Debug)]
2318 struct TestKP {
2319 a: String,
2320 b: String,
2321 c: std::sync::Arc<String>,
2322 d: std::sync::Mutex<String>,
2323 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
2324 f: Option<TestKP2>,
2325 g: HashMap<i32, TestKP2>,
2326 }
2327
2328 impl TestKP {
2329 fn new() -> Self {
2330 Self {
2331 a: String::from("a"),
2332 b: String::from("b"),
2333 c: std::sync::Arc::new(String::from("c")),
2334 d: std::sync::Mutex::new(String::from("d")),
2335 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2336 f: Some(TestKP2 {
2337 a: String::from("a3"),
2338 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2339 }),
2340 g: HashMap::new(),
2341 }
2342 }
2343
2344 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2345 KpComposed::from_closures(
2346 move |r: &TestKP| r.g.get(&index),
2347 move |r: &mut TestKP| r.g.get_mut(&index),
2348 )
2349 }
2350
2351 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2354 TestKP2,
2355 String,
2356 Root,
2357 Value,
2358 MutRoot,
2359 MutValue,
2360 impl Fn(Root) -> Option<Value>,
2361 impl Fn(MutRoot) -> Option<MutValue>,
2362 >
2363 where
2364 Root: std::borrow::Borrow<TestKP2>,
2365 MutRoot: std::borrow::BorrowMut<TestKP2>,
2366 Value: std::borrow::Borrow<String> + From<String>,
2367 MutValue: std::borrow::BorrowMut<String> + From<String>,
2368 {
2369 Kp::new(
2370 |r: Root| Some(Value::from(r.borrow().a.clone())),
2371 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2372 )
2373 }
2374
2375 fn c<'a>() -> KpType<'a, TestKP, String> {
2378 KpType::new(
2379 |r: &TestKP| Some(r.c.as_ref()),
2380 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2381 Some(arc_str) => Some(arc_str),
2382 None => None,
2383 },
2384 )
2385 }
2386
2387 fn a<'a>() -> KpType<'a, TestKP, String> {
2388 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2389 }
2390
2391 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2392 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2393 }
2394
2395 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2396 KpType::identity()
2397 }
2398 }
2399
2400 #[derive(Debug)]
2401 struct TestKP2 {
2402 a: String,
2403 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2404 }
2405
2406 impl TestKP2 {
2407 fn new() -> Self {
2408 TestKP2 {
2409 a: String::from("a2"),
2410 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2411 }
2412 }
2413
2414 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2415 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2422 fn(MutRoot) -> Option<MutRoot>,
2423 >
2424 where
2425 Root: std::borrow::Borrow<TestKP2>,
2426 MutRoot: std::borrow::BorrowMut<TestKP2>,
2427 G: Fn(Root) -> Option<Root>,
2428 S: Fn(MutRoot) -> Option<MutRoot>,
2429 {
2430 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2431 }
2432
2433 fn a<'a>() -> KpType<'a, TestKP2, String> {
2434 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2435 }
2436
2437 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2438 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2439 }
2440
2441 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2446 KpType::identity()
2447 }
2448 }
2449
2450 #[derive(Debug)]
2451 struct TestKP3 {
2452 a: String,
2453 b: std::sync::Arc<std::sync::Mutex<String>>,
2454 }
2455
2456 impl TestKP3 {
2457 fn new() -> Self {
2458 TestKP3 {
2459 a: String::from("a2"),
2460 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2461 }
2462 }
2463
2464 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2465 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2472 fn(MutRoot) -> Option<MutRoot>,
2473 >
2474 where
2475 Root: std::borrow::Borrow<TestKP3>,
2476 MutRoot: std::borrow::BorrowMut<TestKP3>,
2477 G: Fn(Root) -> Option<Root>,
2478 S: Fn(MutRoot) -> Option<MutRoot>,
2479 {
2480 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2481 }
2482
2483 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2484 KpType::identity()
2485 }
2486 }
2487
2488 impl TestKP3 {}
2489
2490 impl TestKP {}
2491 #[test]
2492 fn test_a() {
2493 let instance2 = TestKP2::new();
2494 let mut instance = TestKP::new();
2495 let kp = TestKP::identity();
2496 let kp_a = TestKP::a();
2497 let wres = TestKP::f().then(TestKP2::a()).get_mut(&mut instance).unwrap();
2499 *wres = String::from("a3 changed successfully");
2500 let res = TestKP::f().then(TestKP2::a()).get(&instance);
2501 println!("{:?}", res);
2502 let res = TestKP::f().then(TestKP2::identity()).get(&instance);
2503 println!("{:?}", res);
2504 let res = kp.get(&instance);
2505 println!("{:?}", res);
2506
2507 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2508 println!("{:?}", new_kp_from_hashmap.get(&instance));
2509 }
2510
2511 #[test]
2590 fn test_enum_kp_result_ok() {
2591 let ok_result: Result<String, i32> = Ok("success".to_string());
2592 let mut err_result: Result<String, i32> = Err(42);
2593
2594 let ok_kp = enum_ok();
2595
2596 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2598 assert_eq!(ok_kp.get(&err_result), None);
2599
2600 let embedded = ok_kp.embed("embedded".to_string());
2602 assert_eq!(embedded, Ok("embedded".to_string()));
2603
2604 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2606 *val = "modified".to_string();
2607 }
2608 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2611 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2612 *val = "modified".to_string();
2613 }
2614 assert_eq!(ok_result2, Ok("modified".to_string()));
2615 }
2616
2617 #[test]
2618 fn test_enum_kp_result_err() {
2619 let ok_result: Result<String, i32> = Ok("success".to_string());
2620 let mut err_result: Result<String, i32> = Err(42);
2621
2622 let err_kp = enum_err();
2623
2624 assert_eq!(err_kp.get(&err_result), Some(&42));
2626 assert_eq!(err_kp.get(&ok_result), None);
2627
2628 let embedded = err_kp.embed(99);
2630 assert_eq!(embedded, Err(99));
2631
2632 if let Some(val) = err_kp.get_mut(&mut err_result) {
2634 *val = 100;
2635 }
2636 assert_eq!(err_result, Err(100));
2637 }
2638
2639 #[test]
2640 fn test_enum_kp_option_some() {
2641 let some_opt = Some("value".to_string());
2642 let mut none_opt: Option<String> = None;
2643
2644 let some_kp = enum_some();
2645
2646 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2648 assert_eq!(some_kp.get(&none_opt), None);
2649
2650 let embedded = some_kp.embed("embedded".to_string());
2652 assert_eq!(embedded, Some("embedded".to_string()));
2653
2654 let mut some_opt2 = Some("original".to_string());
2656 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2657 *val = "modified".to_string();
2658 }
2659 assert_eq!(some_opt2, Some("modified".to_string()));
2660 }
2661
2662 #[test]
2663 fn test_enum_kp_custom_enum() {
2664 #[derive(Debug, PartialEq)]
2665 enum MyEnum {
2666 A(String),
2667 B(i32),
2668 C,
2669 }
2670
2671 let mut enum_a = MyEnum::A("hello".to_string());
2672 let enum_b = MyEnum::B(42);
2673 let enum_c = MyEnum::C;
2674
2675 let kp_a = enum_variant(
2677 |e: &MyEnum| match e {
2678 MyEnum::A(s) => Some(s),
2679 _ => None,
2680 },
2681 |e: &mut MyEnum| match e {
2682 MyEnum::A(s) => Some(s),
2683 _ => None,
2684 },
2685 |s: String| MyEnum::A(s),
2686 );
2687
2688 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2690 assert_eq!(kp_a.get(&enum_b), None);
2691 assert_eq!(kp_a.get(&enum_c), None);
2692
2693 let embedded = kp_a.embed("world".to_string());
2695 assert_eq!(embedded, MyEnum::A("world".to_string()));
2696
2697 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2699 *val = "modified".to_string();
2700 }
2701 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2702 }
2703
2704 #[test]
2705 fn test_container_kp_box() {
2706 let boxed = Box::new("value".to_string());
2707 let mut boxed_mut = Box::new("original".to_string());
2708
2709 let box_kp = kp_box();
2710
2711 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2713
2714 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2716 *val = "modified".to_string();
2717 }
2718 assert_eq!(*boxed_mut, "modified".to_string());
2719 }
2720
2721 #[test]
2722 fn test_container_kp_arc() {
2723 let arc = Arc::new("value".to_string());
2724 let mut arc_mut = Arc::new("original".to_string());
2725
2726 let arc_kp = kp_arc();
2727
2728 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2730
2731 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2733 *val = "modified".to_string();
2734 }
2735 assert_eq!(*arc_mut, "modified".to_string());
2736
2737 let arc_shared = Arc::new("shared".to_string());
2739 let arc_shared2 = Arc::clone(&arc_shared);
2740 let mut arc_shared_mut = arc_shared;
2741 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2742 }
2743
2744 #[test]
2745 fn test_enum_kp_composition() {
2746 #[derive(Debug, PartialEq)]
2748 struct Inner {
2749 value: String,
2750 }
2751
2752 let result: Result<Inner, i32> = Ok(Inner {
2753 value: "nested".to_string(),
2754 });
2755
2756 let inner_kp = KpType::new(
2758 |i: &Inner| Some(&i.value),
2759 |i: &mut Inner| Some(&mut i.value),
2760 );
2761
2762 let ok_kp = enum_ok::<Inner, i32>();
2764 let ok_kp_base = ok_kp.into_kp();
2765 let composed = ok_kp_base.then(inner_kp);
2766
2767 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2768 }
2769
2770 #[test]
2771 fn test_pkp_basic() {
2772 #[derive(Debug)]
2773 struct User {
2774 name: String,
2775 age: i32,
2776 }
2777
2778 let user = User {
2779 name: "Alice".to_string(),
2780 age: 30,
2781 };
2782
2783 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2785 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2786
2787 let name_pkp = PKp::new(name_kp);
2789 let age_pkp = PKp::new(age_kp);
2790
2791 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2793 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2794
2795 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2797 assert_eq!(age_pkp.get_as::<String>(&user), None);
2798
2799 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2801 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2802 }
2803
2804 #[test]
2805 fn test_pkp_collection() {
2806 #[derive(Debug)]
2807 struct User {
2808 name: String,
2809 age: i32,
2810 }
2811
2812 let user = User {
2813 name: "Bob".to_string(),
2814 age: 25,
2815 };
2816
2817 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2819 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2820
2821 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2822
2823 let name_value = keypaths[0].get_as::<String>(&user);
2825 let age_value = keypaths[1].get_as::<i32>(&user);
2826
2827 assert_eq!(name_value, Some(&"Bob".to_string()));
2828 assert_eq!(age_value, Some(&25));
2829 }
2830
2831 #[test]
2832 fn test_pkp_for_arc() {
2833 #[derive(Debug)]
2834 struct User {
2835 name: String,
2836 }
2837
2838 let user = Arc::new(User {
2839 name: "Charlie".to_string(),
2840 });
2841
2842 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2843 let name_pkp = PKp::new(name_kp);
2844
2845 let arc_pkp = name_pkp.for_arc();
2847
2848 assert_eq!(
2849 arc_pkp.get_as::<String>(&user),
2850 Some(&"Charlie".to_string())
2851 );
2852 }
2853
2854 #[test]
2855 fn test_pkp_for_option() {
2856 #[derive(Debug)]
2857 struct User {
2858 name: String,
2859 }
2860
2861 let some_user = Some(User {
2862 name: "Diana".to_string(),
2863 });
2864 let none_user: Option<User> = None;
2865
2866 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2867 let name_pkp = PKp::new(name_kp);
2868
2869 let opt_pkp = name_pkp.for_option();
2871
2872 assert_eq!(
2873 opt_pkp.get_as::<String>(&some_user),
2874 Some(&"Diana".to_string())
2875 );
2876 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2877 }
2878
2879 #[test]
2880 fn test_akp_basic() {
2881 #[derive(Debug)]
2882 struct User {
2883 name: String,
2884 age: i32,
2885 }
2886
2887 #[derive(Debug)]
2888 struct Product {
2889 title: String,
2890 price: f64,
2891 }
2892
2893 let user = User {
2894 name: "Eve".to_string(),
2895 age: 28,
2896 };
2897
2898 let product = Product {
2899 title: "Book".to_string(),
2900 price: 19.99,
2901 };
2902
2903 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2905 let user_name_akp = AKp::new(user_name_kp);
2906
2907 let product_title_kp = KpType::new(
2908 |p: &Product| Some(&p.title),
2909 |p: &mut Product| Some(&mut p.title),
2910 );
2911 let product_title_akp = AKp::new(product_title_kp);
2912
2913 assert_eq!(
2915 user_name_akp.get_as::<User, String>(&user),
2916 Some(Some(&"Eve".to_string()))
2917 );
2918 assert_eq!(
2919 product_title_akp.get_as::<Product, String>(&product),
2920 Some(Some(&"Book".to_string()))
2921 );
2922
2923 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2925 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2926
2927 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2929 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2930 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2931 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2932 }
2933
2934 #[test]
2935 fn test_akp_heterogeneous_collection() {
2936 #[derive(Debug)]
2937 struct User {
2938 name: String,
2939 }
2940
2941 #[derive(Debug)]
2942 struct Product {
2943 title: String,
2944 }
2945
2946 let user = User {
2947 name: "Frank".to_string(),
2948 };
2949 let product = Product {
2950 title: "Laptop".to_string(),
2951 };
2952
2953 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2955 let product_title_kp = KpType::new(
2956 |p: &Product| Some(&p.title),
2957 |p: &mut Product| Some(&mut p.title),
2958 );
2959
2960 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2961
2962 let user_any: &dyn Any = &user;
2964 let product_any: &dyn Any = &product;
2965
2966 let user_value = keypaths[0].get(user_any);
2967 let product_value = keypaths[1].get(product_any);
2968
2969 assert!(user_value.is_some());
2970 assert!(product_value.is_some());
2971
2972 assert_eq!(
2974 user_value.and_then(|v| v.downcast_ref::<String>()),
2975 Some(&"Frank".to_string())
2976 );
2977 assert_eq!(
2978 product_value.and_then(|v| v.downcast_ref::<String>()),
2979 Some(&"Laptop".to_string())
2980 );
2981 }
2982
2983 #[test]
2984 fn test_akp_for_option() {
2985 #[derive(Debug)]
2986 struct User {
2987 name: String,
2988 }
2989
2990 let some_user = Some(User {
2991 name: "Grace".to_string(),
2992 });
2993 let none_user: Option<User> = None;
2994
2995 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2996 let name_akp = AKp::new(name_kp);
2997
2998 let opt_akp = name_akp.for_option::<User>();
3000
3001 assert_eq!(
3002 opt_akp.get_as::<Option<User>, String>(&some_user),
3003 Some(Some(&"Grace".to_string()))
3004 );
3005 assert_eq!(
3006 opt_akp.get_as::<Option<User>, String>(&none_user),
3007 Some(None)
3008 );
3009 }
3010
3011 #[test]
3012 fn test_akp_for_result() {
3013 #[derive(Debug)]
3014 struct User {
3015 name: String,
3016 }
3017
3018 let ok_user: Result<User, String> = Ok(User {
3019 name: "Henry".to_string(),
3020 });
3021 let err_user: Result<User, String> = Err("Not found".to_string());
3022
3023 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3024 let name_akp = AKp::new(name_kp);
3025
3026 let result_akp = name_akp.for_result::<User, String>();
3028
3029 assert_eq!(
3030 result_akp.get_as::<Result<User, String>, String>(&ok_user),
3031 Some(Some(&"Henry".to_string()))
3032 );
3033 assert_eq!(
3034 result_akp.get_as::<Result<User, String>, String>(&err_user),
3035 Some(None)
3036 );
3037 }
3038
3039 #[test]
3042 fn test_kp_map() {
3043 #[derive(Debug)]
3044 struct User {
3045 name: String,
3046 age: i32,
3047 }
3048
3049 let user = User {
3050 name: "Alice".to_string(),
3051 age: 30,
3052 };
3053
3054 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3056 let len_kp = name_kp.map(|name: &String| name.len());
3057
3058 assert_eq!(len_kp.get(&user), Some(5));
3059
3060 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3062 let double_age_kp = age_kp.map(|age: &i32| age * 2);
3063
3064 assert_eq!(double_age_kp.get(&user), Some(60));
3065
3066 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
3068 assert_eq!(is_adult_kp.get(&user), Some(true));
3069 }
3070
3071 #[test]
3072 fn test_kp_filter() {
3073 #[derive(Debug)]
3074 struct User {
3075 name: String,
3076 age: i32,
3077 }
3078
3079 let adult = User {
3080 name: "Alice".to_string(),
3081 age: 30,
3082 };
3083
3084 let minor = User {
3085 name: "Bob".to_string(),
3086 age: 15,
3087 };
3088
3089 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3090 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
3091
3092 assert_eq!(adult_age_kp.get(&adult), Some(&30));
3093 assert_eq!(adult_age_kp.get(&minor), None);
3094
3095 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3097 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
3098
3099 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
3100 assert_eq!(short_name_kp.get(&adult), None);
3101 }
3102
3103 #[test]
3104 fn test_kp_map_and_filter() {
3105 #[derive(Debug)]
3106 struct User {
3107 scores: Vec<i32>,
3108 }
3109
3110 let user = User {
3111 scores: vec![85, 92, 78, 95],
3112 };
3113
3114 let scores_kp = KpType::new(
3115 |u: &User| Some(&u.scores),
3116 |u: &mut User| Some(&mut u.scores),
3117 );
3118
3119 let avg_kp =
3121 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3122
3123 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
3125
3126 assert_eq!(high_avg_kp.get(&user), Some(87)); }
3128
3129 #[test]
3130 fn test_enum_kp_map() {
3131 let ok_result: Result<String, i32> = Ok("hello".to_string());
3132 let err_result: Result<String, i32> = Err(42);
3133
3134 let ok_kp = enum_ok::<String, i32>();
3135 let len_kp = ok_kp.map(|s: &String| s.len());
3136
3137 assert_eq!(len_kp.get(&ok_result), Some(5));
3138 assert_eq!(len_kp.get(&err_result), None);
3139
3140 let some_opt = Some(vec![1, 2, 3, 4, 5]);
3142 let none_opt: Option<Vec<i32>> = None;
3143
3144 let some_kp = enum_some::<Vec<i32>>();
3145 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
3146
3147 assert_eq!(count_kp.get(&some_opt), Some(5));
3148 assert_eq!(count_kp.get(&none_opt), None);
3149 }
3150
3151 #[test]
3152 fn test_enum_kp_filter() {
3153 let ok_result1: Result<i32, String> = Ok(42);
3154 let ok_result2: Result<i32, String> = Ok(-5);
3155 let err_result: Result<i32, String> = Err("error".to_string());
3156
3157 let ok_kp = enum_ok::<i32, String>();
3158 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
3159
3160 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
3161 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
3166 let short_str = Some("hi".to_string());
3167
3168 let some_kp = enum_some::<String>();
3169 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
3170
3171 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
3172 assert_eq!(long_kp.get(&short_str), None);
3173 }
3174
3175 #[test]
3176 fn test_pkp_filter() {
3177 #[derive(Debug)]
3178 struct User {
3179 name: String,
3180 age: i32,
3181 }
3182
3183 let adult = User {
3184 name: "Alice".to_string(),
3185 age: 30,
3186 };
3187
3188 let minor = User {
3189 name: "Bob".to_string(),
3190 age: 15,
3191 };
3192
3193 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3194 let age_pkp = PKp::new(age_kp);
3195
3196 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
3198
3199 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
3200 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
3201
3202 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3204 let name_pkp = PKp::new(name_kp);
3205 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
3206
3207 assert_eq!(
3208 short_name_pkp.get_as::<String>(&minor),
3209 Some(&"Bob".to_string())
3210 );
3211 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
3212 }
3213
3214 #[test]
3215 fn test_akp_filter() {
3216 #[derive(Debug)]
3217 struct User {
3218 age: i32,
3219 }
3220
3221 #[derive(Debug)]
3222 struct Product {
3223 price: f64,
3224 }
3225
3226 let adult = User { age: 30 };
3227 let minor = User { age: 15 };
3228 let expensive = Product { price: 99.99 };
3229 let cheap = Product { price: 5.0 };
3230
3231 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3233 let age_akp = AKp::new(age_kp);
3234 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
3235
3236 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
3237 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
3238
3239 let price_kp = KpType::new(
3241 |p: &Product| Some(&p.price),
3242 |p: &mut Product| Some(&mut p.price),
3243 );
3244 let price_akp = AKp::new(price_kp);
3245 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
3246
3247 assert_eq!(
3248 expensive_akp.get_as::<Product, f64>(&expensive),
3249 Some(Some(&99.99))
3250 );
3251 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
3252 }
3253
3254 #[test]
3257 fn test_kp_filter_map() {
3258 #[derive(Debug)]
3259 struct User {
3260 middle_name: Option<String>,
3261 }
3262
3263 let user_with = User {
3264 middle_name: Some("Marie".to_string()),
3265 };
3266 let user_without = User { middle_name: None };
3267
3268 let middle_kp = KpType::new(
3269 |u: &User| Some(&u.middle_name),
3270 |u: &mut User| Some(&mut u.middle_name),
3271 );
3272
3273 let first_char_kp = middle_kp
3274 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
3275
3276 assert_eq!(first_char_kp.get(&user_with), Some('M'));
3277 assert_eq!(first_char_kp.get(&user_without), None);
3278 }
3279
3280 #[test]
3281 fn test_kp_inspect() {
3282 #[derive(Debug)]
3283 struct User {
3284 name: String,
3285 }
3286
3287 let user = User {
3288 name: "Alice".to_string(),
3289 };
3290
3291 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3295
3296 let result = name_kp.get(&user);
3299 assert_eq!(result, Some(&"Alice".to_string()));
3300
3301 }
3304
3305 #[test]
3306 fn test_kp_fold_value() {
3307 #[derive(Debug)]
3308 struct User {
3309 scores: Vec<i32>,
3310 }
3311
3312 let user = User {
3313 scores: vec![85, 92, 78, 95],
3314 };
3315
3316 let scores_kp = KpType::new(
3317 |u: &User| Some(&u.scores),
3318 |u: &mut User| Some(&mut u.scores),
3319 );
3320
3321 let sum_fn =
3323 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
3324
3325 assert_eq!(sum_fn(&user), 350);
3326 }
3327
3328 #[test]
3329 fn test_kp_any_all() {
3330 #[derive(Debug)]
3331 struct User {
3332 scores: Vec<i32>,
3333 }
3334
3335 let user_high = User {
3336 scores: vec![85, 92, 88],
3337 };
3338 let user_mixed = User {
3339 scores: vec![65, 92, 78],
3340 };
3341
3342 let scores_kp = KpType::new(
3343 |u: &User| Some(&u.scores),
3344 |u: &mut User| Some(&mut u.scores),
3345 );
3346
3347 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
3349 assert!(has_high_fn(&user_high));
3350 assert!(has_high_fn(&user_mixed));
3351
3352 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
3354 assert!(all_passing_fn(&user_high));
3355 assert!(!all_passing_fn(&user_mixed));
3356 }
3357
3358 #[test]
3359 fn test_kp_count_items() {
3360 #[derive(Debug)]
3361 struct User {
3362 tags: Vec<String>,
3363 }
3364
3365 let user = User {
3366 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
3367 };
3368
3369 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3370 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
3371
3372 assert_eq!(count_fn(&user), Some(3));
3373 }
3374
3375 #[test]
3376 fn test_kp_find_in() {
3377 #[derive(Debug)]
3378 struct User {
3379 scores: Vec<i32>,
3380 }
3381
3382 let user = User {
3383 scores: vec![85, 92, 78, 95, 88],
3384 };
3385
3386 let scores_kp = KpType::new(
3387 |u: &User| Some(&u.scores),
3388 |u: &mut User| Some(&mut u.scores),
3389 );
3390
3391 let first_high_fn =
3393 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3394
3395 assert_eq!(first_high_fn(&user), Some(92));
3396
3397 let perfect_fn =
3399 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3400
3401 assert_eq!(perfect_fn(&user), None);
3402 }
3403
3404 #[test]
3405 fn test_kp_take_skip() {
3406 #[derive(Debug)]
3407 struct User {
3408 tags: Vec<String>,
3409 }
3410
3411 let user = User {
3412 tags: vec![
3413 "a".to_string(),
3414 "b".to_string(),
3415 "c".to_string(),
3416 "d".to_string(),
3417 ],
3418 };
3419
3420 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3421
3422 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3424 tags.iter().take(n).cloned().collect::<Vec<_>>()
3425 });
3426
3427 let taken = take_fn(&user).unwrap();
3428 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3429
3430 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3432 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3433 });
3434
3435 let skipped = skip_fn(&user).unwrap();
3436 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3437 }
3438
3439 #[test]
3440 fn test_kp_partition() {
3441 #[derive(Debug)]
3442 struct User {
3443 scores: Vec<i32>,
3444 }
3445
3446 let user = User {
3447 scores: vec![85, 92, 65, 95, 72, 58],
3448 };
3449
3450 let scores_kp = KpType::new(
3451 |u: &User| Some(&u.scores),
3452 |u: &mut User| Some(&mut u.scores),
3453 );
3454
3455 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3456 scores.iter().copied().partition(|&s| s >= 70)
3457 });
3458
3459 let (passing, failing) = partition_fn(&user).unwrap();
3460 assert_eq!(passing, vec![85, 92, 95, 72]);
3461 assert_eq!(failing, vec![65, 58]);
3462 }
3463
3464 #[test]
3465 fn test_kp_min_max() {
3466 #[derive(Debug)]
3467 struct User {
3468 scores: Vec<i32>,
3469 }
3470
3471 let user = User {
3472 scores: vec![85, 92, 78, 95, 88],
3473 };
3474
3475 let scores_kp = KpType::new(
3476 |u: &User| Some(&u.scores),
3477 |u: &mut User| Some(&mut u.scores),
3478 );
3479
3480 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3482 assert_eq!(min_fn(&user), Some(78));
3483
3484 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3486 assert_eq!(max_fn(&user), Some(95));
3487 }
3488
3489 #[test]
3490 fn test_kp_sum() {
3491 #[derive(Debug)]
3492 struct User {
3493 scores: Vec<i32>,
3494 }
3495
3496 let user = User {
3497 scores: vec![85, 92, 78],
3498 };
3499
3500 let scores_kp = KpType::new(
3501 |u: &User| Some(&u.scores),
3502 |u: &mut User| Some(&mut u.scores),
3503 );
3504
3505 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3506 assert_eq!(sum_fn(&user), Some(255));
3507
3508 let avg_fn =
3510 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3511 assert_eq!(avg_fn.get(&user), Some(85));
3512 }
3513
3514 #[test]
3515 fn test_kp_chain() {
3516 #[derive(Debug)]
3517 struct User {
3518 profile: Profile,
3519 }
3520
3521 #[derive(Debug)]
3522 struct Profile {
3523 settings: Settings,
3524 }
3525
3526 #[derive(Debug)]
3527 struct Settings {
3528 theme: String,
3529 }
3530
3531 let user = User {
3532 profile: Profile {
3533 settings: Settings {
3534 theme: "dark".to_string(),
3535 },
3536 },
3537 };
3538
3539 let profile_kp = KpType::new(
3540 |u: &User| Some(&u.profile),
3541 |u: &mut User| Some(&mut u.profile),
3542 );
3543 let settings_kp = KpType::new(
3544 |p: &Profile| Some(&p.settings),
3545 |p: &mut Profile| Some(&mut p.settings),
3546 );
3547 let theme_kp = KpType::new(
3548 |s: &Settings| Some(&s.theme),
3549 |s: &mut Settings| Some(&mut s.theme),
3550 );
3551
3552 let profile_settings = profile_kp.chain(settings_kp);
3554 let theme_path = profile_settings.chain(theme_kp);
3555 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3556 }
3557
3558 #[test]
3559 fn test_kp_zip() {
3560 #[derive(Debug)]
3561 struct User {
3562 name: String,
3563 age: i32,
3564 }
3565
3566 let user = User {
3567 name: "Alice".to_string(),
3568 age: 30,
3569 };
3570
3571 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3572 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3573
3574 let zipped_fn = zip_kps(&name_kp, &age_kp);
3575 let result = zipped_fn(&user);
3576
3577 assert_eq!(result, Some((&"Alice".to_string(), &30)));
3578 }
3579
3580 #[test]
3581 fn test_kp_complex_pipeline() {
3582 #[derive(Debug)]
3583 struct User {
3584 transactions: Vec<Transaction>,
3585 }
3586
3587 #[derive(Debug)]
3588 struct Transaction {
3589 amount: f64,
3590 category: String,
3591 }
3592
3593 let user = User {
3594 transactions: vec![
3595 Transaction {
3596 amount: 50.0,
3597 category: "food".to_string(),
3598 },
3599 Transaction {
3600 amount: 100.0,
3601 category: "transport".to_string(),
3602 },
3603 Transaction {
3604 amount: 25.0,
3605 category: "food".to_string(),
3606 },
3607 Transaction {
3608 amount: 200.0,
3609 category: "shopping".to_string(),
3610 },
3611 ],
3612 };
3613
3614 let txns_kp = KpType::new(
3615 |u: &User| Some(&u.transactions),
3616 |u: &mut User| Some(&mut u.transactions),
3617 );
3618
3619 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3621 txns.iter()
3622 .filter(|t| t.category == "food")
3623 .map(|t| t.amount)
3624 .sum::<f64>()
3625 });
3626
3627 assert_eq!(food_total.get(&user), Some(75.0));
3628
3629 let has_large =
3631 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3632
3633 assert!(has_large(&user));
3634
3635 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3637 assert_eq!(count(&user), Some(4));
3638 }
3639
3640 #[test]
3644 fn test_no_clone_required_for_root() {
3645 use std::sync::Arc;
3646 use std::sync::atomic::{AtomicUsize, Ordering};
3647
3648 struct NonCloneableRoot {
3651 data: Arc<AtomicUsize>,
3652 cached_value: usize,
3653 }
3654
3655 impl NonCloneableRoot {
3656 fn new() -> Self {
3657 Self {
3658 data: Arc::new(AtomicUsize::new(42)),
3659 cached_value: 42,
3660 }
3661 }
3662
3663 fn increment(&mut self) {
3664 self.data.fetch_add(1, Ordering::SeqCst);
3665 self.cached_value = self.data.load(Ordering::SeqCst);
3666 }
3667
3668 fn get_value(&self) -> &usize {
3669 &self.cached_value
3670 }
3671
3672 fn get_value_mut(&mut self) -> &mut usize {
3673 &mut self.cached_value
3674 }
3675 }
3676
3677 let mut root = NonCloneableRoot::new();
3678
3679 let data_kp = KpType::new(
3681 |r: &NonCloneableRoot| Some(r.get_value()),
3682 |r: &mut NonCloneableRoot| {
3683 r.increment();
3684 Some(r.get_value_mut())
3685 },
3686 );
3687
3688 assert_eq!(data_kp.get(&root), Some(&42));
3690
3691 {
3692 let doubled = data_kp.map(|val: &usize| val * 2);
3694 assert_eq!(doubled.get(&root), Some(84));
3695
3696 let filtered = data_kp.filter(|val: &usize| *val > 0);
3698 assert_eq!(filtered.get(&root), Some(&42));
3699 } let value_ref = data_kp.get_mut(&mut root);
3703 assert!(value_ref.is_some());
3704 }
3705
3706 #[test]
3707 fn test_no_clone_required_for_value() {
3708 use std::sync::Arc;
3709 use std::sync::atomic::{AtomicUsize, Ordering};
3710
3711 struct NonCloneableValue {
3713 counter: Arc<AtomicUsize>,
3714 }
3715
3716 impl NonCloneableValue {
3717 fn new(val: usize) -> Self {
3718 Self {
3719 counter: Arc::new(AtomicUsize::new(val)),
3720 }
3721 }
3722
3723 fn get(&self) -> usize {
3724 self.counter.load(Ordering::SeqCst)
3725 }
3726 }
3727
3728 struct Root {
3729 value: NonCloneableValue,
3730 }
3731
3732 let root = Root {
3733 value: NonCloneableValue::new(100),
3734 };
3735
3736 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3738
3739 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3741 assert_eq!(counter_kp.get(&root), Some(100));
3742
3743 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3745 assert!(filtered.get(&root).is_some());
3746 }
3747
3748 #[test]
3749 fn test_static_does_not_leak_memory() {
3750 use std::sync::Arc;
3751 use std::sync::atomic::{AtomicUsize, Ordering};
3752
3753 static CREATED: AtomicUsize = AtomicUsize::new(0);
3755 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3756
3757 struct Tracked {
3758 id: usize,
3759 }
3760
3761 impl Tracked {
3762 fn new() -> Self {
3763 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3764 Self { id }
3765 }
3766 }
3767
3768 impl Drop for Tracked {
3769 fn drop(&mut self) {
3770 DROPPED.fetch_add(1, Ordering::SeqCst);
3771 }
3772 }
3773
3774 struct Root {
3775 data: Tracked,
3776 }
3777
3778 CREATED.store(0, Ordering::SeqCst);
3780 DROPPED.store(0, Ordering::SeqCst);
3781
3782 {
3783 let root = Root {
3784 data: Tracked::new(),
3785 };
3786
3787 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3788
3789 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3791 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3792 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3793
3794 assert_eq!(mapped1.get(&root), Some(0));
3795 assert_eq!(mapped2.get(&root), Some(1));
3796 assert_eq!(mapped3.get(&root), Some(2));
3797
3798 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3800 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3801 }
3802
3803 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3805 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3806
3807 }
3809
3810 #[test]
3811 fn test_references_not_cloned() {
3812 use std::sync::Arc;
3813
3814 struct ExpensiveData {
3816 large_vec: Vec<u8>,
3817 }
3818
3819 impl ExpensiveData {
3820 fn new(size: usize) -> Self {
3821 Self {
3822 large_vec: vec![0u8; size],
3823 }
3824 }
3825
3826 fn size(&self) -> usize {
3827 self.large_vec.len()
3828 }
3829 }
3830
3831 struct Root {
3832 expensive: ExpensiveData,
3833 }
3834
3835 let root = Root {
3836 expensive: ExpensiveData::new(1_000_000), };
3838
3839 let expensive_kp = KpType::new(
3840 |r: &Root| Some(&r.expensive),
3841 |r: &mut Root| Some(&mut r.expensive),
3842 );
3843
3844 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3846 assert_eq!(size_kp.get(&root), Some(1_000_000));
3847
3848 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3850 assert!(large_filter.get(&root).is_some());
3851
3852 }
3854
3855 #[test]
3856 fn test_hof_with_arc_no_extra_clones() {
3857 use std::sync::Arc;
3858
3859 #[derive(Debug)]
3860 struct SharedData {
3861 value: String,
3862 }
3863
3864 struct Root {
3865 shared: Arc<SharedData>,
3866 }
3867
3868 let shared = Arc::new(SharedData {
3869 value: "shared".to_string(),
3870 });
3871
3872 assert_eq!(Arc::strong_count(&shared), 1);
3874
3875 {
3876 let root = Root {
3877 shared: Arc::clone(&shared),
3878 };
3879
3880 assert_eq!(Arc::strong_count(&shared), 2);
3882
3883 let shared_kp = KpType::new(
3884 |r: &Root| Some(&r.shared),
3885 |r: &mut Root| Some(&mut r.shared),
3886 );
3887
3888 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3890
3891 assert_eq!(value_kp.get(&root), Some(6));
3893 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3897 assert!(filtered.get(&root).is_some());
3898 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3903
3904 #[test]
3905 fn test_closure_captures_not_root_values() {
3906 use std::sync::Arc;
3907 use std::sync::atomic::{AtomicUsize, Ordering};
3908
3909 let call_count = Arc::new(AtomicUsize::new(0));
3911 let call_count_clone = Arc::clone(&call_count);
3912
3913 struct Root {
3914 value: i32,
3915 }
3916
3917 let root = Root { value: 42 };
3918
3919 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3920
3921 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3924 call_count_clone.fetch_add(1, Ordering::SeqCst);
3925 v * 2
3926 });
3927
3928 assert_eq!(doubled(&root), 84);
3930 assert_eq!(doubled(&root), 84);
3931 assert_eq!(doubled(&root), 84);
3932
3933 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3935
3936 }
3938
3939 #[test]
3940 fn test_static_with_borrowed_data() {
3941 struct Root {
3945 data: String,
3946 }
3947
3948 {
3949 let root = Root {
3950 data: "temporary".to_string(),
3951 };
3952
3953 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3954
3955 let len_kp = data_kp.map(|s: &String| s.len());
3957 assert_eq!(len_kp.get(&root), Some(9));
3958
3959 } }
3964
3965 #[test]
3966 fn test_multiple_hof_operations_no_accumulation() {
3967 use std::sync::Arc;
3968 use std::sync::atomic::{AtomicUsize, Ordering};
3969
3970 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3971
3972 struct Tracked {
3973 id: usize,
3974 }
3975
3976 impl Drop for Tracked {
3977 fn drop(&mut self) {
3978 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3979 }
3980 }
3981
3982 struct Root {
3983 values: Vec<Tracked>,
3984 }
3985
3986 DROP_COUNT.store(0, Ordering::SeqCst);
3987
3988 {
3989 let root = Root {
3990 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3991 };
3992
3993 let values_kp = KpType::new(
3994 |r: &Root| Some(&r.values),
3995 |r: &mut Root| Some(&mut r.values),
3996 );
3997
3998 let count = values_kp.count_items(|v| v.len());
4000 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
4001 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
4002 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
4003
4004 assert_eq!(count(&root), Some(3));
4005 assert_eq!(sum(&root), Some(6));
4006 assert!(has_2(&root));
4007 assert!(all_positive(&root));
4008
4009 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4011 }
4012
4013 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
4015 }
4016
4017 #[test]
4018 fn test_copy_bound_only_for_function_not_data() {
4019 #[derive(Debug)]
4023 struct NonCopyData {
4024 value: String,
4025 }
4026
4027 struct Root {
4028 data: NonCopyData,
4029 }
4030
4031 let root = Root {
4032 data: NonCopyData {
4033 value: "test".to_string(),
4034 },
4035 };
4036
4037 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4038
4039 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
4042 assert_eq!(len_kp.get(&root), Some(4));
4043
4044 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
4046 assert!(filtered.get(&root).is_some());
4047 }
4048
4049 #[test]
4050 fn test_no_memory_leak_with_cyclic_references() {
4051 use std::sync::atomic::{AtomicUsize, Ordering};
4052 use std::sync::{Arc, Weak};
4053
4054 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
4055
4056 struct Node {
4057 id: usize,
4058 parent: Option<Weak<Node>>,
4059 }
4060
4061 impl Drop for Node {
4062 fn drop(&mut self) {
4063 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4064 }
4065 }
4066
4067 struct Root {
4068 node: Arc<Node>,
4069 }
4070
4071 DROP_COUNT.store(0, Ordering::SeqCst);
4072
4073 {
4074 let root = Root {
4075 node: Arc::new(Node {
4076 id: 1,
4077 parent: None,
4078 }),
4079 };
4080
4081 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
4082
4083 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
4085 assert_eq!(id_kp.get(&root), Some(1));
4086
4087 assert_eq!(Arc::strong_count(&root.node), 1);
4089
4090 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4092 }
4093
4094 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
4096 }
4097
4098 #[test]
4099 fn test_hof_operations_are_zero_cost_abstractions() {
4100 struct Root {
4104 value: i32,
4105 }
4106
4107 let root = Root { value: 10 };
4108
4109 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4110
4111 let direct_result = value_kp.get(&root).map(|v| v * 2);
4113 assert_eq!(direct_result, Some(20));
4114
4115 let mapped_kp = value_kp.map(|v: &i32| v * 2);
4117 let hof_result = mapped_kp.get(&root);
4118 assert_eq!(hof_result, Some(20));
4119
4120 assert_eq!(direct_result, hof_result);
4122 }
4123
4124 #[test]
4125 fn test_complex_closure_captures_allowed() {
4126 use std::sync::Arc;
4127
4128 struct Root {
4130 scores: Vec<i32>,
4131 }
4132
4133 let root = Root {
4134 scores: vec![85, 92, 78, 95, 88],
4135 };
4136
4137 let scores_kp = KpType::new(
4138 |r: &Root| Some(&r.scores),
4139 |r: &mut Root| Some(&mut r.scores),
4140 );
4141
4142 let threshold = 90;
4144 let multiplier = Arc::new(2);
4145
4146 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
4148 let high: i32 = scores
4149 .iter()
4150 .filter(|&&s| s >= threshold)
4151 .map(|&s| s * *multiplier)
4152 .sum();
4153 acc + high
4154 });
4155
4156 assert_eq!(high_scores_doubled(&root), 374);
4158 }
4159
4160 #[test]
4164 fn test_pkp_filter_by_value_type() {
4165 use std::any::TypeId;
4166
4167 #[derive(Debug)]
4168 struct User {
4169 name: String,
4170 age: i32,
4171 score: f64,
4172 active: bool,
4173 }
4174
4175 let user = User {
4176 name: "Alice".to_string(),
4177 age: 30,
4178 score: 95.5,
4179 active: true,
4180 };
4181
4182 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4184 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4185 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
4186 let active_kp = KpType::new(
4187 |u: &User| Some(&u.active),
4188 |u: &mut User| Some(&mut u.active),
4189 );
4190
4191 let all_keypaths: Vec<PKp<User>> = vec![
4193 PKp::new(name_kp),
4194 PKp::new(age_kp),
4195 PKp::new(score_kp),
4196 PKp::new(active_kp),
4197 ];
4198
4199 let string_kps: Vec<_> = all_keypaths
4201 .iter()
4202 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
4203 .collect();
4204
4205 assert_eq!(string_kps.len(), 1);
4206 assert_eq!(
4207 string_kps[0].get_as::<String>(&user),
4208 Some(&"Alice".to_string())
4209 );
4210
4211 let i32_kps: Vec<_> = all_keypaths
4213 .iter()
4214 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
4215 .collect();
4216
4217 assert_eq!(i32_kps.len(), 1);
4218 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
4219
4220 let f64_kps: Vec<_> = all_keypaths
4222 .iter()
4223 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
4224 .collect();
4225
4226 assert_eq!(f64_kps.len(), 1);
4227 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
4228
4229 let bool_kps: Vec<_> = all_keypaths
4231 .iter()
4232 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
4233 .collect();
4234
4235 assert_eq!(bool_kps.len(), 1);
4236 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
4237 }
4238
4239 #[test]
4240 fn test_pkp_filter_by_struct_type() {
4241 use std::any::TypeId;
4242
4243 #[derive(Debug, PartialEq)]
4244 struct Address {
4245 street: String,
4246 city: String,
4247 }
4248
4249 #[derive(Debug)]
4250 struct User {
4251 name: String,
4252 age: i32,
4253 address: Address,
4254 }
4255
4256 let user = User {
4257 name: "Bob".to_string(),
4258 age: 25,
4259 address: Address {
4260 street: "123 Main St".to_string(),
4261 city: "NYC".to_string(),
4262 },
4263 };
4264
4265 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4267 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4268 let address_kp = KpType::new(
4269 |u: &User| Some(&u.address),
4270 |u: &mut User| Some(&mut u.address),
4271 );
4272
4273 let all_keypaths: Vec<PKp<User>> =
4274 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
4275
4276 let struct_kps: Vec<_> = all_keypaths
4278 .iter()
4279 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
4280 .collect();
4281
4282 assert_eq!(struct_kps.len(), 1);
4283 assert_eq!(
4284 struct_kps[0].get_as::<Address>(&user),
4285 Some(&Address {
4286 street: "123 Main St".to_string(),
4287 city: "NYC".to_string(),
4288 })
4289 );
4290
4291 let primitive_kps: Vec<_> = all_keypaths
4293 .iter()
4294 .filter(|pkp| {
4295 pkp.value_type_id() == TypeId::of::<String>()
4296 || pkp.value_type_id() == TypeId::of::<i32>()
4297 })
4298 .collect();
4299
4300 assert_eq!(primitive_kps.len(), 2);
4301 }
4302
4303 #[test]
4304 fn test_pkp_filter_by_arc_type() {
4305 use std::any::TypeId;
4306 use std::sync::Arc;
4307
4308 #[derive(Debug)]
4309 struct User {
4310 name: String,
4311 shared_data: Arc<String>,
4312 shared_number: Arc<i32>,
4313 }
4314
4315 let user = User {
4316 name: "Charlie".to_string(),
4317 shared_data: Arc::new("shared".to_string()),
4318 shared_number: Arc::new(42),
4319 };
4320
4321 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4323 let shared_data_kp = KpType::new(
4324 |u: &User| Some(&u.shared_data),
4325 |u: &mut User| Some(&mut u.shared_data),
4326 );
4327 let shared_number_kp = KpType::new(
4328 |u: &User| Some(&u.shared_number),
4329 |u: &mut User| Some(&mut u.shared_number),
4330 );
4331
4332 let all_keypaths: Vec<PKp<User>> = vec![
4333 PKp::new(name_kp),
4334 PKp::new(shared_data_kp),
4335 PKp::new(shared_number_kp),
4336 ];
4337
4338 let arc_string_kps: Vec<_> = all_keypaths
4340 .iter()
4341 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
4342 .collect();
4343
4344 assert_eq!(arc_string_kps.len(), 1);
4345 assert_eq!(
4346 arc_string_kps[0]
4347 .get_as::<Arc<String>>(&user)
4348 .map(|arc| arc.as_str()),
4349 Some("shared")
4350 );
4351
4352 let arc_i32_kps: Vec<_> = all_keypaths
4354 .iter()
4355 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
4356 .collect();
4357
4358 assert_eq!(arc_i32_kps.len(), 1);
4359 assert_eq!(
4360 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
4361 Some(42)
4362 );
4363
4364 let all_arc_kps: Vec<_> = all_keypaths
4366 .iter()
4367 .filter(|pkp| {
4368 pkp.value_type_id() == TypeId::of::<Arc<String>>()
4369 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
4370 })
4371 .collect();
4372
4373 assert_eq!(all_arc_kps.len(), 2);
4374 }
4375
4376 #[test]
4377 fn test_pkp_filter_by_box_type() {
4378 use std::any::TypeId;
4379
4380 #[derive(Debug)]
4381 struct User {
4382 name: String,
4383 boxed_value: Box<i32>,
4384 boxed_string: Box<String>,
4385 }
4386
4387 let user = User {
4388 name: "Diana".to_string(),
4389 boxed_value: Box::new(100),
4390 boxed_string: Box::new("boxed".to_string()),
4391 };
4392
4393 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4395 let boxed_value_kp = KpType::new(
4396 |u: &User| Some(&u.boxed_value),
4397 |u: &mut User| Some(&mut u.boxed_value),
4398 );
4399 let boxed_string_kp = KpType::new(
4400 |u: &User| Some(&u.boxed_string),
4401 |u: &mut User| Some(&mut u.boxed_string),
4402 );
4403
4404 let all_keypaths: Vec<PKp<User>> = vec![
4405 PKp::new(name_kp),
4406 PKp::new(boxed_value_kp),
4407 PKp::new(boxed_string_kp),
4408 ];
4409
4410 let box_i32_kps: Vec<_> = all_keypaths
4412 .iter()
4413 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4414 .collect();
4415
4416 assert_eq!(box_i32_kps.len(), 1);
4417 assert_eq!(
4418 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4419 Some(100)
4420 );
4421
4422 let box_string_kps: Vec<_> = all_keypaths
4424 .iter()
4425 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4426 .collect();
4427
4428 assert_eq!(box_string_kps.len(), 1);
4429 assert_eq!(
4430 box_string_kps[0]
4431 .get_as::<Box<String>>(&user)
4432 .map(|b| b.as_str()),
4433 Some("boxed")
4434 );
4435 }
4436
4437 #[test]
4438 fn test_akp_filter_by_root_and_value_type() {
4439 use std::any::TypeId;
4440
4441 #[derive(Debug)]
4442 struct User {
4443 name: String,
4444 age: i32,
4445 }
4446
4447 #[derive(Debug)]
4448 struct Product {
4449 title: String,
4450 price: f64,
4451 }
4452
4453 let user = User {
4454 name: "Eve".to_string(),
4455 age: 28,
4456 };
4457
4458 let product = Product {
4459 title: "Book".to_string(),
4460 price: 19.99,
4461 };
4462
4463 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4465 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4466 let product_title_kp = KpType::new(
4467 |p: &Product| Some(&p.title),
4468 |p: &mut Product| Some(&mut p.title),
4469 );
4470 let product_price_kp = KpType::new(
4471 |p: &Product| Some(&p.price),
4472 |p: &mut Product| Some(&mut p.price),
4473 );
4474
4475 let all_keypaths: Vec<AKp> = vec![
4476 AKp::new(user_name_kp),
4477 AKp::new(user_age_kp),
4478 AKp::new(product_title_kp),
4479 AKp::new(product_price_kp),
4480 ];
4481
4482 let user_kps: Vec<_> = all_keypaths
4484 .iter()
4485 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4486 .collect();
4487
4488 assert_eq!(user_kps.len(), 2);
4489
4490 let product_kps: Vec<_> = all_keypaths
4492 .iter()
4493 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4494 .collect();
4495
4496 assert_eq!(product_kps.len(), 2);
4497
4498 let string_value_kps: Vec<_> = all_keypaths
4500 .iter()
4501 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4502 .collect();
4503
4504 assert_eq!(string_value_kps.len(), 2);
4505
4506 let user_string_kps: Vec<_> = all_keypaths
4508 .iter()
4509 .filter(|akp| {
4510 akp.root_type_id() == TypeId::of::<User>()
4511 && akp.value_type_id() == TypeId::of::<String>()
4512 })
4513 .collect();
4514
4515 assert_eq!(user_string_kps.len(), 1);
4516 assert_eq!(
4517 user_string_kps[0].get_as::<User, String>(&user),
4518 Some(Some(&"Eve".to_string()))
4519 );
4520
4521 let product_f64_kps: Vec<_> = all_keypaths
4523 .iter()
4524 .filter(|akp| {
4525 akp.root_type_id() == TypeId::of::<Product>()
4526 && akp.value_type_id() == TypeId::of::<f64>()
4527 })
4528 .collect();
4529
4530 assert_eq!(product_f64_kps.len(), 1);
4531 assert_eq!(
4532 product_f64_kps[0].get_as::<Product, f64>(&product),
4533 Some(Some(&19.99))
4534 );
4535 }
4536
4537 #[test]
4538 fn test_akp_filter_by_arc_root_type() {
4539 use std::any::TypeId;
4540 use std::sync::Arc;
4541
4542 #[derive(Debug)]
4543 struct User {
4544 name: String,
4545 }
4546
4547 #[derive(Debug)]
4548 struct Product {
4549 title: String,
4550 }
4551
4552 let user = User {
4553 name: "Frank".to_string(),
4554 };
4555 let product = Product {
4556 title: "Laptop".to_string(),
4557 };
4558
4559 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4561 let product_title_kp = KpType::new(
4562 |p: &Product| Some(&p.title),
4563 |p: &mut Product| Some(&mut p.title),
4564 );
4565
4566 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4568 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4569
4570 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4571
4572 let arc_user_kps: Vec<_> = all_keypaths
4574 .iter()
4575 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4576 .collect();
4577
4578 assert_eq!(arc_user_kps.len(), 1);
4579
4580 let arc_user = Arc::new(user);
4582 assert_eq!(
4583 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4584 Some(Some(&"Frank".to_string()))
4585 );
4586
4587 let arc_product_kps: Vec<_> = all_keypaths
4589 .iter()
4590 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4591 .collect();
4592
4593 assert_eq!(arc_product_kps.len(), 1);
4594
4595 let arc_product = Arc::new(product);
4597 assert_eq!(
4598 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4599 Some(Some(&"Laptop".to_string()))
4600 );
4601 }
4602
4603 #[test]
4604 fn test_akp_filter_by_box_root_type() {
4605 use std::any::TypeId;
4606
4607 #[derive(Debug)]
4608 struct Config {
4609 setting: String,
4610 }
4611
4612 let config = Config {
4613 setting: "enabled".to_string(),
4614 };
4615
4616 let config_kp1 = KpType::new(
4618 |c: &Config| Some(&c.setting),
4619 |c: &mut Config| Some(&mut c.setting),
4620 );
4621 let config_kp2 = KpType::new(
4622 |c: &Config| Some(&c.setting),
4623 |c: &mut Config| Some(&mut c.setting),
4624 );
4625
4626 let regular_akp = AKp::new(config_kp1);
4628 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4629
4630 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4631
4632 let config_kps: Vec<_> = all_keypaths
4634 .iter()
4635 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4636 .collect();
4637
4638 assert_eq!(config_kps.len(), 1);
4639 assert_eq!(
4640 config_kps[0].get_as::<Config, String>(&config),
4641 Some(Some(&"enabled".to_string()))
4642 );
4643
4644 let box_config_kps: Vec<_> = all_keypaths
4646 .iter()
4647 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4648 .collect();
4649
4650 assert_eq!(box_config_kps.len(), 1);
4651
4652 let box_config = Box::new(Config {
4654 setting: "enabled".to_string(),
4655 });
4656 assert_eq!(
4657 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4658 Some(Some(&"enabled".to_string()))
4659 );
4660 }
4661
4662 #[test]
4663 fn test_mixed_collection_type_filtering() {
4664 use std::any::TypeId;
4665 use std::sync::Arc;
4666
4667 #[derive(Debug)]
4668 struct User {
4669 name: String,
4670 email: String,
4671 }
4672
4673 #[derive(Debug)]
4674 struct Product {
4675 title: String,
4676 sku: String,
4677 }
4678
4679 let user = User {
4680 name: "Grace".to_string(),
4681 email: "grace@example.com".to_string(),
4682 };
4683
4684 let product = Product {
4685 title: "Widget".to_string(),
4686 sku: "WID-001".to_string(),
4687 };
4688
4689 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4691 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4692 let user_email_kp1 =
4693 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4694 let user_email_kp2 =
4695 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4696 let product_title_kp = KpType::new(
4697 |p: &Product| Some(&p.title),
4698 |p: &mut Product| Some(&mut p.title),
4699 );
4700 let product_sku_kp = KpType::new(
4701 |p: &Product| Some(&p.sku),
4702 |p: &mut Product| Some(&mut p.sku),
4703 );
4704
4705 let all_keypaths: Vec<AKp> = vec![
4706 AKp::new(user_name_kp1),
4707 AKp::new(user_email_kp1),
4708 AKp::new(product_title_kp),
4709 AKp::new(product_sku_kp),
4710 AKp::new(user_name_kp2).for_arc::<User>(),
4711 AKp::new(user_email_kp2).for_box::<User>(),
4712 ];
4713
4714 let string_value_kps: Vec<_> = all_keypaths
4716 .iter()
4717 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4718 .collect();
4719
4720 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4724 .iter()
4725 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4726 .collect();
4727
4728 assert_eq!(user_root_kps.len(), 2);
4729
4730 let arc_user_kps: Vec<_> = all_keypaths
4732 .iter()
4733 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4734 .collect();
4735
4736 assert_eq!(arc_user_kps.len(), 1);
4737
4738 let box_user_kps: Vec<_> = all_keypaths
4740 .iter()
4741 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4742 .collect();
4743
4744 assert_eq!(box_user_kps.len(), 1);
4745
4746 let product_kps: Vec<_> = all_keypaths
4748 .iter()
4749 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4750 .collect();
4751
4752 assert_eq!(product_kps.len(), 2);
4753
4754 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4756 assert!(user_value.is_some());
4757 assert!(user_value.unwrap().is_some());
4758 }
4759
4760 #[test]
4765 fn test_kp_with_pin() {
4766 use std::pin::Pin;
4767
4768 #[derive(Debug)]
4772 struct SelfReferential {
4773 value: String,
4774 ptr_to_value: *const String, }
4776
4777 impl SelfReferential {
4778 fn new(s: String) -> Self {
4779 let mut sr = Self {
4780 value: s,
4781 ptr_to_value: std::ptr::null(),
4782 };
4783 sr.ptr_to_value = &sr.value as *const String;
4785 sr
4786 }
4787
4788 fn get_value(&self) -> &str {
4789 &self.value
4790 }
4791 }
4792
4793 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4795 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4796
4797 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4799 |p: &Pin<Box<SelfReferential>>| {
4800 Some(&p.as_ref().get_ref().value)
4802 },
4803 |p: &mut Pin<Box<SelfReferential>>| {
4804 unsafe {
4807 let sr = Pin::get_unchecked_mut(p.as_mut());
4808 Some(&mut sr.value)
4809 }
4810 },
4811 );
4812
4813 let result = kp.get(&pinned);
4815 assert_eq!(result, Some(&"pinned_data".to_string()));
4816
4817 assert_eq!(pinned.get_value(), "pinned_data");
4819 }
4820
4821 #[test]
4822 fn test_kp_with_pin_arc() {
4823 use std::pin::Pin;
4824 use std::sync::Arc;
4825
4826 struct AsyncState {
4827 status: String,
4828 data: Vec<i32>,
4829 }
4830
4831 let state = AsyncState {
4833 status: "ready".to_string(),
4834 data: vec![1, 2, 3, 4, 5],
4835 };
4836
4837 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4838
4839 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4841 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4842 |_: &mut Pin<Arc<AsyncState>>| {
4843 None::<&mut String>
4845 },
4846 );
4847
4848 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4850 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4851 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4852 );
4853
4854 let status = status_kp.get(&pinned_arc);
4855 assert_eq!(status, Some(&"ready".to_string()));
4856
4857 let data = data_kp.get(&pinned_arc);
4858 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4859 }
4860
4861 #[test]
4862 fn test_kp_with_maybe_uninit() {
4863 use std::mem::MaybeUninit;
4864
4865 struct Config {
4869 name: MaybeUninit<String>,
4870 value: MaybeUninit<i32>,
4871 initialized: bool,
4872 }
4873
4874 impl Config {
4875 fn new_uninit() -> Self {
4876 Self {
4877 name: MaybeUninit::uninit(),
4878 value: MaybeUninit::uninit(),
4879 initialized: false,
4880 }
4881 }
4882
4883 fn init(&mut self, name: String, value: i32) {
4884 self.name.write(name);
4885 self.value.write(value);
4886 self.initialized = true;
4887 }
4888
4889 fn get_name(&self) -> Option<&String> {
4890 if self.initialized {
4891 unsafe { Some(self.name.assume_init_ref()) }
4892 } else {
4893 None
4894 }
4895 }
4896
4897 fn get_value(&self) -> Option<&i32> {
4898 if self.initialized {
4899 unsafe { Some(self.value.assume_init_ref()) }
4900 } else {
4901 None
4902 }
4903 }
4904 }
4905
4906 let name_kp: KpType<Config, String> = Kp::new(
4908 |c: &Config| c.get_name(),
4909 |c: &mut Config| {
4910 if c.initialized {
4911 unsafe { Some(c.name.assume_init_mut()) }
4912 } else {
4913 None
4914 }
4915 },
4916 );
4917
4918 let value_kp: KpType<Config, i32> = Kp::new(
4919 |c: &Config| c.get_value(),
4920 |c: &mut Config| {
4921 if c.initialized {
4922 unsafe { Some(c.value.assume_init_mut()) }
4923 } else {
4924 None
4925 }
4926 },
4927 );
4928
4929 let uninit_config = Config::new_uninit();
4931 assert_eq!(name_kp.get(&uninit_config), None);
4932 assert_eq!(value_kp.get(&uninit_config), None);
4933
4934 let mut init_config = Config::new_uninit();
4936 init_config.init("test_config".to_string(), 42);
4937
4938 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4939 assert_eq!(value_kp.get(&init_config), Some(&42));
4940
4941 if let Some(val) = value_kp.get_mut(&mut init_config) {
4943 *val = 100;
4944 }
4945
4946 assert_eq!(value_kp.get(&init_config), Some(&100));
4947 }
4948
4949 #[test]
4950 fn test_kp_with_weak() {
4951 use std::sync::{Arc, Weak};
4952
4953 #[derive(Debug, Clone)]
4957 struct Node {
4958 value: i32,
4959 }
4960
4961 struct NodeWithParent {
4962 value: i32,
4963 parent: Option<Arc<Node>>, }
4965
4966 let parent = Arc::new(Node { value: 100 });
4967
4968 let child = NodeWithParent {
4969 value: 42,
4970 parent: Some(parent.clone()),
4971 };
4972
4973 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4975 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4976 |_: &mut NodeWithParent| None::<&mut i32>,
4977 );
4978
4979 let parent_val = parent_value_kp.get(&child);
4981 assert_eq!(parent_val, Some(&100));
4982 }
4983
4984 #[test]
4985 fn test_kp_with_rc_weak() {
4986 use std::rc::Rc;
4987
4988 struct TreeNode {
4991 value: String,
4992 parent: Option<Rc<TreeNode>>, }
4994
4995 let root = Rc::new(TreeNode {
4996 value: "root".to_string(),
4997 parent: None,
4998 });
4999
5000 let child1 = TreeNode {
5001 value: "child1".to_string(),
5002 parent: Some(root.clone()),
5003 };
5004
5005 let child2 = TreeNode {
5006 value: "child2".to_string(),
5007 parent: Some(root.clone()),
5008 };
5009
5010 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
5012 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
5013 |_: &mut TreeNode| None::<&mut String>,
5014 );
5015
5016 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
5018 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
5019
5020 assert_eq!(parent_name_kp.get(&root), None);
5022 }
5023
5024 #[test]
5025 fn test_kp_with_complex_weak_structure() {
5026 use std::sync::Arc;
5027
5028 struct Cache {
5031 data: String,
5032 backup: Option<Arc<Cache>>, }
5034
5035 let primary = Arc::new(Cache {
5036 data: "primary_data".to_string(),
5037 backup: None,
5038 });
5039
5040 let backup = Arc::new(Cache {
5041 data: "backup_data".to_string(),
5042 backup: Some(primary.clone()),
5043 });
5044
5045 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
5047 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
5048 |_: &mut Arc<Cache>| None::<&mut String>,
5049 );
5050
5051 let data = backup_data_kp.get(&backup);
5053 assert_eq!(data, Some(&"primary_data".to_string()));
5054
5055 let no_backup = backup_data_kp.get(&primary);
5057 assert_eq!(no_backup, None);
5058 }
5059
5060 #[test]
5061 fn test_kp_chain_with_pin_and_arc() {
5062 use std::pin::Pin;
5063 use std::sync::Arc;
5064
5065 struct Outer {
5068 inner: Arc<Inner>,
5069 }
5070
5071 struct Inner {
5072 value: String,
5073 }
5074
5075 let outer = Outer {
5076 inner: Arc::new(Inner {
5077 value: "nested_value".to_string(),
5078 }),
5079 };
5080
5081 let pinned_outer = Box::pin(outer);
5082
5083 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
5085 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
5086 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
5087 );
5088
5089 let to_value: KpType<Arc<Inner>, String> = Kp::new(
5091 |a: &Arc<Inner>| Some(&a.value),
5092 |_: &mut Arc<Inner>| None::<&mut String>,
5093 );
5094
5095 let chained = to_inner.then(to_value);
5097
5098 let result = chained.get(&pinned_outer);
5099 assert_eq!(result, Some(&"nested_value".to_string()));
5100 }
5101
5102 #[test]
5103 fn test_kp_with_maybe_uninit_array() {
5104 use std::mem::MaybeUninit;
5105
5106 struct Buffer {
5110 data: [MaybeUninit<u8>; 10],
5111 len: usize,
5112 }
5113
5114 impl Buffer {
5115 fn new() -> Self {
5116 Self {
5117 data: unsafe { MaybeUninit::uninit().assume_init() },
5118 len: 0,
5119 }
5120 }
5121
5122 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
5123 if self.len >= self.data.len() {
5124 return Err("Buffer full");
5125 }
5126 self.data[self.len].write(byte);
5127 self.len += 1;
5128 Ok(())
5129 }
5130
5131 fn get(&self, idx: usize) -> Option<&u8> {
5132 if idx < self.len {
5133 unsafe { Some(self.data[idx].assume_init_ref()) }
5134 } else {
5135 None
5136 }
5137 }
5138
5139 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
5140 if idx < self.len {
5141 unsafe { Some(self.data[idx].assume_init_mut()) }
5142 } else {
5143 None
5144 }
5145 }
5146 }
5147
5148 let len_kp: KpType<Buffer, usize> =
5150 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
5151
5152 let mut buffer = Buffer::new();
5153
5154 assert_eq!(len_kp.get(&buffer), Some(&0));
5156
5157 buffer.push(1).unwrap();
5159 buffer.push(2).unwrap();
5160 buffer.push(3).unwrap();
5161
5162 assert_eq!(len_kp.get(&buffer), Some(&3));
5164
5165 assert_eq!(buffer.get(0), Some(&1));
5167 assert_eq!(buffer.get(1), Some(&2));
5168 assert_eq!(buffer.get(2), Some(&3));
5169 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
5173 *elem = 20;
5174 }
5175 assert_eq!(buffer.get(1), Some(&20));
5176 }
5177
5178 #[test]
5179 fn test_kp_then_lock_deep_structs() {
5180 use std::sync::{Arc, Mutex};
5181
5182 #[derive(Clone)]
5183 struct Root {
5184 guard: Arc<Mutex<Level1>>,
5185 }
5186 #[derive(Clone)]
5187 struct Level1 {
5188 name: String,
5189 nested: Level2,
5190 }
5191 #[derive(Clone)]
5192 struct Level2 {
5193 count: i32,
5194 }
5195
5196 let root = Root {
5197 guard: Arc::new(Mutex::new(Level1 {
5198 name: "deep".to_string(),
5199 nested: Level2 { count: 42 },
5200 })),
5201 };
5202
5203 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
5204 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
5205
5206 let lock_kp = {
5207 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
5208 Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
5209 let next: KpType<Level1, Level1> =
5210 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5211 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5212 };
5213
5214 let chained = kp_to_guard.then_lock(lock_kp);
5215 let level1 = chained.get(&root);
5216 assert!(level1.is_some());
5217 assert_eq!(level1.unwrap().name, "deep");
5218 assert_eq!(level1.unwrap().nested.count, 42);
5219
5220 let mut_root = &mut root.clone();
5221 let mut_level1 = chained.get_mut(mut_root);
5222 assert!(mut_level1.is_some());
5223 mut_level1.unwrap().nested.count = 99;
5224 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
5225 }
5226
5227 #[test]
5228 fn test_kp_then_lock_with_enum() {
5229 use std::sync::{Arc, Mutex};
5230
5231 #[derive(Clone)]
5232 enum Message {
5233 Request(LevelA),
5234 Response(i32),
5235 }
5236 #[derive(Clone)]
5237 struct LevelA {
5238 data: Arc<Mutex<i32>>,
5239 }
5240
5241 struct RootWithEnum {
5242 msg: Arc<Mutex<Message>>,
5243 }
5244
5245 let root = RootWithEnum {
5246 msg: Arc::new(Mutex::new(Message::Request(LevelA {
5247 data: Arc::new(Mutex::new(100)),
5248 }))),
5249 };
5250
5251 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
5252 Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
5253
5254 let lock_kp_msg = {
5255 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
5256 Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
5257 let next: KpType<Message, Message> =
5258 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
5259 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5260 };
5261
5262 let chained = kp_msg.then_lock(lock_kp_msg);
5263 let msg = chained.get(&root);
5264 assert!(msg.is_some());
5265 match msg.unwrap() {
5266 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
5267 Message::Response(_) => panic!("expected Request"),
5268 }
5269 }
5270
5271 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5272 #[tokio::test]
5273 async fn test_kp_then_async_deep_chain() {
5274 use std::sync::Arc;
5275 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5276
5277 #[derive(Clone)]
5278 struct Root {
5279 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
5280 }
5281 #[derive(Clone)]
5282 struct Level1 {
5283 value: i32,
5284 }
5285
5286 let root = Root {
5287 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
5288 };
5289
5290 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
5291 |r: &Root| Some(&r.tokio_guard),
5292 |r: &mut Root| Some(&mut r.tokio_guard),
5293 );
5294
5295 let async_kp = {
5296 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
5297 Kp::new(
5298 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
5299 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
5300 );
5301 let next: KpType<Level1, Level1> =
5302 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5303 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5304 };
5305
5306 let chained = kp_to_guard.then_async(async_kp);
5307 let level1 = chained.get(&root).await;
5308 assert!(level1.is_some());
5309 assert_eq!(level1.unwrap().value, 7);
5310 }
5311
5312 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5315 #[tokio::test]
5316 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
5317 use std::sync::{Arc, Mutex};
5318 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5319 use crate::lock::{LockKp, ArcMutexAccess};
5320
5321 #[derive(Clone)]
5323 struct Root {
5324 sync_mutex: Arc<Mutex<Level1>>,
5325 }
5326 #[derive(Clone)]
5328 struct Level1 {
5329 inner: Level2,
5330 }
5331 #[derive(Clone)]
5333 struct Level2 {
5334 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
5335 }
5336 #[derive(Clone)]
5338 struct Level3 {
5339 leaf: i32,
5340 }
5341
5342 let mut root = Root {
5343 sync_mutex: Arc::new(Mutex::new(Level1 {
5344 inner: Level2 {
5345 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
5346 },
5347 })),
5348 };
5349
5350 let identity_l1: KpType<Level1, Level1> =
5352 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5353 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
5354 Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
5355 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
5356
5357 let kp_l1_inner: KpType<Level1, Level2> =
5359 Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
5360
5361 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
5363 |l: &Level2| Some(&l.tokio_mutex),
5364 |l: &mut Level2| Some(&mut l.tokio_mutex),
5365 );
5366
5367 let async_l3 = {
5369 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
5370 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
5371 let next: KpType<Level3, Level3> =
5372 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
5373 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5374 };
5375
5376 let kp_l3_leaf: KpType<Level3, i32> =
5378 Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
5379
5380 let step1 = lock_root_to_l1.then(kp_l1_inner);
5382 let step2 = step1.then(kp_l2_tokio);
5383 let step3 = step2.then_async(async_l3);
5384 let deep_chain = step3.then(kp_l3_leaf);
5385
5386 let leaf = deep_chain.get(&root).await;
5388 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5389 assert_eq!(leaf, Some(&100));
5390
5391 let mut root_mut = root.clone();
5393 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5394 assert!(leaf_mut.is_some());
5395 *leaf_mut.unwrap() = 99;
5396
5397 let leaf_after = deep_chain.get(&root_mut).await;
5399 assert_eq!(leaf_after, Some(&99));
5400 }
5401}