1use std::sync::{Arc, Mutex};
14
15pub mod lock;
17pub mod prelude;
18
19pub use lock::{
20 ArcMutexAccess, ArcRwLockAccess, LockAccess, LockKp, LockKpType, RcRefCellAccess,
21 StdMutexAccess, StdRwLockAccess,
22};
23
24#[cfg(feature = "parking_lot")]
25pub use lock::{
26 DirectParkingLotMutexAccess, DirectParkingLotRwLockAccess, ParkingLotMutexAccess,
27 ParkingLotRwLockAccess,
28};
29
30pub mod async_lock;
32
33#[cfg(feature = "pin_project")]
76pub mod pin;
77
78pub trait KeyPathValueTarget {
82 type Target: Sized;
83}
84impl<T> KeyPathValueTarget for &T {
85 type Target = T;
86}
87impl<T> KeyPathValueTarget for &mut T {
88 type Target = T;
89}
90
91#[macro_export]
93macro_rules! keypath {
94 { $root:ident . $field:ident } => { $root::$field() };
95 { $root:ident . $field:ident . $($ty:ident . $f:ident).+ } => {
96 $root::$field() $(.then($ty::$f()))+
97 };
98 ($root:ident . $field:ident) => { $root::$field() };
99 ($root:ident . $field:ident . $($ty:ident . $f:ident).+) => {
100 $root::$field() $(.then($ty::$f()))+
101 };
102}
103
104#[macro_export]
108macro_rules! get_or {
109 ($kp:expr, $root:expr, $default:expr) => {
110 $kp.get($root).unwrap_or($default)
111 };
112 ($root:expr => $($path:tt)*, $default:expr) => {
113 $crate::get_or!($crate::keypath!($($path)*), $root, $default)
114 };
115}
116
117#[macro_export]
122macro_rules! get_or_else {
123 ($kp:expr, $root:expr, $closure:expr) => {
124 $kp.get($root).map(|r| r.clone()).unwrap_or_else($closure)
125 };
126 ($root:expr => ($($path:tt)*), $closure:expr) => {
127 $crate::get_or_else!($crate::keypath!($($path)*), $root, $closure)
128 };
129}
130
131#[macro_export]
152macro_rules! zip_with_kp {
153 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr) => {
154 match ($kp1.get($root), $kp2.get($root)) {
155 (Some(__a), Some(__b)) => Some($closure((__a, __b))),
156 _ => None,
157 }
158 };
159 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr) => {
160 match ($kp1.get($root), $kp2.get($root), $kp3.get($root)) {
161 (Some(__a), Some(__b), Some(__c)) => Some($closure((__a, __b, __c))),
162 _ => None,
163 }
164 };
165 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr) => {
166 match (
167 $kp1.get($root),
168 $kp2.get($root),
169 $kp3.get($root),
170 $kp4.get($root),
171 ) {
172 (Some(__a), Some(__b), Some(__c), Some(__d)) => Some($closure((__a, __b, __c, __d))),
173 _ => None,
174 }
175 };
176 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr) => {
177 match (
178 $kp1.get($root),
179 $kp2.get($root),
180 $kp3.get($root),
181 $kp4.get($root),
182 $kp5.get($root),
183 ) {
184 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e)) => {
185 Some($closure((__a, __b, __c, __d, __e)))
186 }
187 _ => None,
188 }
189 };
190 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr, $kp6:expr) => {
191 match (
192 $kp1.get($root),
193 $kp2.get($root),
194 $kp3.get($root),
195 $kp4.get($root),
196 $kp5.get($root),
197 $kp6.get($root),
198 ) {
199 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e), Some(__f)) => {
200 Some($closure((__a, __b, __c, __d, __e, __f)))
201 }
202 _ => None,
203 }
204 };
205}
206
207pub type KpValue<'a, R, V> = Kp<
209 R,
210 V,
211 &'a R,
212 V, &'a mut R,
214 V, for<'b> fn(&'b R) -> Option<V>,
216 for<'b> fn(&'b mut R) -> Option<V>,
217>;
218
219pub type KpOwned<R, V> = Kp<
221 R,
222 V,
223 R,
224 V, R,
226 V, fn(R) -> Option<V>,
228 fn(R) -> Option<V>,
229>;
230
231pub type KpRoot<R> = Kp<
233 R,
234 R,
235 R,
236 R, R,
238 R, fn(R) -> Option<R>,
240 fn(R) -> Option<R>,
241>;
242
243pub type KpVoid = Kp<(), (), (), (), (), (), fn() -> Option<()>, fn() -> Option<()>>;
245
246pub type KpDynamic<R, V> = Kp<
247 R,
248 V,
249 &'static R,
250 &'static V,
251 &'static mut R,
252 &'static mut V,
253 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
254 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
255>;
256
257pub type KpBox<'a, R, V> = Kp<
258 R,
259 V,
260 &'a R,
261 &'a V,
262 &'a mut R,
263 &'a mut V,
264 Box<dyn Fn(&'a R) -> Option<&'a V> + 'a>,
265 Box<dyn Fn(&'a mut R) -> Option<&'a mut V> + 'a>,
266>;
267
268pub type KpArc<'a, R, V> = Kp<
269 R,
270 V,
271 &'a R,
272 &'a V,
273 &'a mut R,
274 &'a mut V,
275 Arc<dyn Fn(&'a R) -> Option<&'a V> + Send + Sync + 'a>,
276 Arc<dyn Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync + 'a>,
277>;
278
279pub type KpType<'a, R, V> = Kp<
280 R,
281 V,
282 &'a R,
283 &'a V,
284 &'a mut R,
285 &'a mut V,
286 for<'b> fn(&'b R) -> Option<&'b V>,
287 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
288>;
289
290pub type KpTraitType<'a, R, V> = dyn KpTrait<
291 R,
292 V,
293 &'a R,
294 &'a V,
295 &'a mut R,
296 &'a mut V,
297 for<'b> fn(&'b R) -> Option<&'b V>,
298 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
299 >;
300
301pub type KpOptionRefCellType<'a, R, V> = Kp<
304 R,
305 V,
306 &'a R,
307 std::cell::Ref<'a, V>,
308 &'a mut R,
309 std::cell::RefMut<'a, V>,
310 for<'b> fn(&'b R) -> Option<std::cell::Ref<'b, V>>,
311 for<'b> fn(&'b mut R) -> Option<std::cell::RefMut<'b, V>>,
312>;
313
314impl<'a, R, V> KpType<'a, R, V>
315where
316 'a: 'static,
317{
318 #[inline]
321 pub fn to_dynamic(self) -> KpDynamic<R, V> {
322 self.into()
323 }
324}
325
326impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V>
327where
328 'a: 'static,
329 R: 'static,
330 V: 'static,
331{
332 #[inline]
333 fn from(kp: KpType<'a, R, V>) -> Self {
334 let get_fn = kp.get;
335 let set_fn = kp.set;
336 Kp::new(
337 Box::new(move |t: &R| get_fn(t)),
338 Box::new(move |t: &mut R| set_fn(t)),
339 )
340 }
341}
342
343pub type KpComposed<R, V> = Kp<
379 R,
380 V,
381 &'static R,
382 &'static V,
383 &'static mut R,
384 &'static mut V,
385 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
386 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
387>;
388
389impl<R, V>
390 Kp<
391 R,
392 V,
393 &'static R,
394 &'static V,
395 &'static mut R,
396 &'static mut V,
397 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
398 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
399 >
400{
401 pub fn from_closures<G, S>(get: G, set: S) -> Self
404 where
405 G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
406 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
407 {
408 Self::new(Box::new(get), Box::new(set))
409 }
410}
411
412pub struct AKp {
413 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
414 root_type_id: TypeId,
415 value_type_id: TypeId,
416}
417
418impl AKp {
419 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
421 where
422 R: Any + 'static,
423 V: Any + 'static,
424 {
425 let root_type_id = TypeId::of::<R>();
426 let value_type_id = TypeId::of::<V>();
427 let getter_fn = keypath.get;
428
429 Self {
430 getter: Rc::new(move |any: &dyn Any| {
431 if let Some(root) = any.downcast_ref::<R>() {
432 getter_fn(root).map(|value: &V| value as &dyn Any)
433 } else {
434 None
435 }
436 }),
437 root_type_id,
438 value_type_id,
439 }
440 }
441
442 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
444 where
445 R: Any + 'static,
446 V: Any + 'static,
447 {
448 Self::new(keypath)
449 }
450
451 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
453 (self.getter)(root)
454 }
455
456 pub fn root_type_id(&self) -> TypeId {
458 self.root_type_id
459 }
460
461 pub fn value_type_id(&self) -> TypeId {
463 self.value_type_id
464 }
465
466 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
468 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
469 {
470 Some(
471 self.get(root as &dyn Any)
472 .and_then(|any| any.downcast_ref::<Value>()),
473 )
474 } else {
475 None
476 }
477 }
478
479 pub fn kind_name(&self) -> String {
481 format!("{:?}", self.value_type_id)
482 }
483
484 pub fn root_kind_name(&self) -> String {
486 format!("{:?}", self.root_type_id)
487 }
488
489 pub fn for_arc<Root>(&self) -> AKp
491 where
492 Root: Any + 'static,
493 {
494 let value_type_id = self.value_type_id;
495 let getter = self.getter.clone();
496
497 AKp {
498 getter: Rc::new(move |any: &dyn Any| {
499 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
500 getter(arc.as_ref() as &dyn Any)
501 } else {
502 None
503 }
504 }),
505 root_type_id: TypeId::of::<Arc<Root>>(),
506 value_type_id,
507 }
508 }
509
510 pub fn for_box<Root>(&self) -> AKp
512 where
513 Root: Any + 'static,
514 {
515 let value_type_id = self.value_type_id;
516 let getter = self.getter.clone();
517
518 AKp {
519 getter: Rc::new(move |any: &dyn Any| {
520 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
521 getter(boxed.as_ref() as &dyn Any)
522 } else {
523 None
524 }
525 }),
526 root_type_id: TypeId::of::<Box<Root>>(),
527 value_type_id,
528 }
529 }
530
531 pub fn for_rc<Root>(&self) -> AKp
533 where
534 Root: Any + 'static,
535 {
536 let value_type_id = self.value_type_id;
537 let getter = self.getter.clone();
538
539 AKp {
540 getter: Rc::new(move |any: &dyn Any| {
541 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
542 getter(rc.as_ref() as &dyn Any)
543 } else {
544 None
545 }
546 }),
547 root_type_id: TypeId::of::<Rc<Root>>(),
548 value_type_id,
549 }
550 }
551
552 pub fn for_option<Root>(&self) -> AKp
554 where
555 Root: Any + 'static,
556 {
557 let value_type_id = self.value_type_id;
558 let getter = self.getter.clone();
559
560 AKp {
561 getter: Rc::new(move |any: &dyn Any| {
562 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
563 opt.as_ref().and_then(|root| getter(root as &dyn Any))
564 } else {
565 None
566 }
567 }),
568 root_type_id: TypeId::of::<Option<Root>>(),
569 value_type_id,
570 }
571 }
572
573 pub fn for_result<Root, E>(&self) -> AKp
575 where
576 Root: Any + 'static,
577 E: Any + 'static,
578 {
579 let value_type_id = self.value_type_id;
580 let getter = self.getter.clone();
581
582 AKp {
583 getter: Rc::new(move |any: &dyn Any| {
584 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
585 result
586 .as_ref()
587 .ok()
588 .and_then(|root| getter(root as &dyn Any))
589 } else {
590 None
591 }
592 }),
593 root_type_id: TypeId::of::<Result<Root, E>>(),
594 value_type_id,
595 }
596 }
597
598 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
611 where
612 Root: Any + 'static,
613 OrigValue: Any + 'static,
614 MappedValue: Any + 'static,
615 F: Fn(&OrigValue) -> MappedValue + 'static,
616 {
617 let orig_root_type_id = self.root_type_id;
618 let orig_value_type_id = self.value_type_id;
619 let getter = self.getter.clone();
620 let mapped_type_id = TypeId::of::<MappedValue>();
621
622 AKp {
623 getter: Rc::new(move |any_root: &dyn Any| {
624 if any_root.type_id() == orig_root_type_id {
626 getter(any_root).and_then(|any_value| {
627 if orig_value_type_id == TypeId::of::<OrigValue>() {
629 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
630 let mapped = mapper(orig_val);
631 Box::leak(Box::new(mapped)) as &dyn Any
633 })
634 } else {
635 None
636 }
637 })
638 } else {
639 None
640 }
641 }),
642 root_type_id: orig_root_type_id,
643 value_type_id: mapped_type_id,
644 }
645 }
646
647 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
660 where
661 Root: Any + 'static,
662 Value: Any + 'static,
663 F: Fn(&Value) -> bool + 'static,
664 {
665 let orig_root_type_id = self.root_type_id;
666 let orig_value_type_id = self.value_type_id;
667 let getter = self.getter.clone();
668
669 AKp {
670 getter: Rc::new(move |any_root: &dyn Any| {
671 if any_root.type_id() == orig_root_type_id {
673 getter(any_root).filter(|any_value| {
674 if orig_value_type_id == TypeId::of::<Value>() {
676 any_value
677 .downcast_ref::<Value>()
678 .map(|val| predicate(val))
679 .unwrap_or(false)
680 } else {
681 false
682 }
683 })
684 } else {
685 None
686 }
687 }),
688 root_type_id: orig_root_type_id,
689 value_type_id: orig_value_type_id,
690 }
691 }
692}
693pub struct PKp<Root> {
694 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
695 value_type_id: TypeId,
696 _phantom: std::marker::PhantomData<Root>,
697}
698
699impl<Root> PKp<Root>
700where
701 Root: 'static,
702{
703 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
705 where
706 V: Any + 'static,
707 {
708 let value_type_id = TypeId::of::<V>();
709 let getter_fn = keypath.get;
710
711 Self {
712 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
713 value_type_id,
714 _phantom: std::marker::PhantomData,
715 }
716 }
717
718 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
720 where
721 V: Any + 'static,
722 {
723 Self::new(keypath)
724 }
725
726 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
728 (self.getter)(root)
729 }
730
731 pub fn value_type_id(&self) -> TypeId {
733 self.value_type_id
734 }
735
736 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
738 if self.value_type_id == TypeId::of::<Value>() {
739 self.get(root).and_then(|any| any.downcast_ref::<Value>())
740 } else {
741 None
742 }
743 }
744
745 pub fn kind_name(&self) -> String {
747 format!("{:?}", self.value_type_id)
748 }
749
750 pub fn for_arc(&self) -> PKp<Arc<Root>> {
752 let getter = self.getter.clone();
753 let value_type_id = self.value_type_id;
754
755 PKp {
756 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
757 value_type_id,
758 _phantom: std::marker::PhantomData,
759 }
760 }
761
762 pub fn for_box(&self) -> PKp<Box<Root>> {
764 let getter = self.getter.clone();
765 let value_type_id = self.value_type_id;
766
767 PKp {
768 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
769 value_type_id,
770 _phantom: std::marker::PhantomData,
771 }
772 }
773
774 pub fn for_rc(&self) -> PKp<Rc<Root>> {
776 let getter = self.getter.clone();
777 let value_type_id = self.value_type_id;
778
779 PKp {
780 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
781 value_type_id,
782 _phantom: std::marker::PhantomData,
783 }
784 }
785
786 pub fn for_option(&self) -> PKp<Option<Root>> {
788 let getter = self.getter.clone();
789 let value_type_id = self.value_type_id;
790
791 PKp {
792 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
793 value_type_id,
794 _phantom: std::marker::PhantomData,
795 }
796 }
797
798 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
800 where
801 E: 'static,
802 {
803 let getter = self.getter.clone();
804 let value_type_id = self.value_type_id;
805
806 PKp {
807 getter: Rc::new(move |result: &Result<Root, E>| {
808 result.as_ref().ok().and_then(|root| getter(root))
809 }),
810 value_type_id,
811 _phantom: std::marker::PhantomData,
812 }
813 }
814
815 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
829 where
830 OrigValue: Any + 'static,
831 MappedValue: Any + 'static,
832 F: Fn(&OrigValue) -> MappedValue + 'static,
833 {
834 let orig_type_id = self.value_type_id;
835 let getter = self.getter.clone();
836 let mapped_type_id = TypeId::of::<MappedValue>();
837
838 PKp {
839 getter: Rc::new(move |root: &Root| {
840 getter(root).and_then(|any_value| {
841 if orig_type_id == TypeId::of::<OrigValue>() {
843 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
844 let mapped = mapper(orig_val);
845 Box::leak(Box::new(mapped)) as &dyn Any
848 })
849 } else {
850 None
851 }
852 })
853 }),
854 value_type_id: mapped_type_id,
855 _phantom: std::marker::PhantomData,
856 }
857 }
858
859 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
873 where
874 Value: Any + 'static,
875 F: Fn(&Value) -> bool + 'static,
876 {
877 let orig_type_id = self.value_type_id;
878 let getter = self.getter.clone();
879
880 PKp {
881 getter: Rc::new(move |root: &Root| {
882 getter(root).filter(|any_value| {
883 if orig_type_id == TypeId::of::<Value>() {
885 any_value
886 .downcast_ref::<Value>()
887 .map(|val| predicate(val))
888 .unwrap_or(false)
889 } else {
890 false
891 }
892 })
893 }),
894 value_type_id: orig_type_id,
895 _phantom: std::marker::PhantomData,
896 }
897 }
898}
899
900pub trait KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S> {
903 fn type_id_of_root() -> TypeId
904 where
905 R: 'static,
906 {
907 std::any::TypeId::of::<R>()
908 }
909 fn type_id_of_value() -> TypeId
910 where
911 V: 'static,
912 {
913 std::any::TypeId::of::<V>()
914 }
915 fn get(&self, root: Root) -> Option<Value>;
916 fn get_mut(&self, root: MutRoot) -> Option<MutValue>;
917 fn then<SV, SubValue, MutSubValue, G2, S2>(
918 self,
919 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
920 ) -> Kp<
921 R,
922 SV,
923 Root,
924 SubValue,
925 MutRoot,
926 MutSubValue,
927 impl Fn(Root) -> Option<SubValue>,
928 impl Fn(MutRoot) -> Option<MutSubValue>,
929 >
930 where
931 Self: Sized,
932 Root: std::borrow::Borrow<R>,
933 Value: std::borrow::Borrow<V>,
934 MutRoot: std::borrow::BorrowMut<R>,
935 MutValue: std::borrow::BorrowMut<V>,
936 SubValue: std::borrow::Borrow<SV>,
937 MutSubValue: std::borrow::BorrowMut<SV>,
938 G2: Fn(Value) -> Option<SubValue>,
939 S2: Fn(MutValue) -> Option<MutSubValue>,
940 V: 'static;
941}
942
943pub trait ChainExt<R, V, Root, Value, MutRoot, MutValue> {
944 fn then_lock<
946 Lock,
947 Mid,
948 V2,
949 LockValue,
950 MidValue,
951 Value2,
952 MutLock,
953 MutMid,
954 MutValue2,
955 G1,
956 S1,
957 L,
958 G2,
959 S2,
960 >(
961 self,
962 lock_kp: crate::lock::LockKp<
963 V,
964 Lock,
965 Mid,
966 V2,
967 Value,
968 LockValue,
969 MidValue,
970 Value2,
971 MutValue,
972 MutLock,
973 MutMid,
974 MutValue2,
975 G1,
976 S1,
977 L,
978 G2,
979 S2,
980 >,
981 ) -> crate::lock::KpThenLockKp<
982 R,
983 V,
984 V2,
985 Root,
986 Value,
987 Value2,
988 MutRoot,
989 MutValue,
990 MutValue2,
991 Self,
992 crate::lock::LockKp<
993 V,
994 Lock,
995 Mid,
996 V2,
997 Value,
998 LockValue,
999 MidValue,
1000 Value2,
1001 MutValue,
1002 MutLock,
1003 MutMid,
1004 MutValue2,
1005 G1,
1006 S1,
1007 L,
1008 G2,
1009 S2,
1010 >,
1011 >
1012 where
1013 V: 'static + Clone,
1014 V2: 'static,
1015 Value: std::borrow::Borrow<V>,
1016 Value2: std::borrow::Borrow<V2>,
1017 MutValue: std::borrow::BorrowMut<V>,
1018 MutValue2: std::borrow::BorrowMut<V2>,
1019 LockValue: std::borrow::Borrow<Lock>,
1020 MidValue: std::borrow::Borrow<Mid>,
1021 MutLock: std::borrow::BorrowMut<Lock>,
1022 MutMid: std::borrow::BorrowMut<Mid>,
1023 G1: Fn(Value) -> Option<LockValue>,
1024 S1: Fn(MutValue) -> Option<MutLock>,
1025 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
1026 G2: Fn(MidValue) -> Option<Value2>,
1027 S2: Fn(MutMid) -> Option<MutValue2>,
1028 Self: Sized;
1029
1030 #[cfg(feature = "pin_project")]
1032 fn then_pin_future<Struct, Output, L>(
1033 self,
1034 pin_fut: L,
1035 ) -> crate::pin::KpThenPinFuture<R, Struct, Output, Root, MutRoot, Value, MutValue, Self, L>
1036 where
1037 V: 'static,
1038 Struct: Unpin + 'static,
1039 Output: 'static,
1040 Value: std::borrow::Borrow<Struct>,
1041 MutValue: std::borrow::BorrowMut<Struct>,
1042 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
1043 Self: Sized;
1044
1045 fn then_async<AsyncKp>(
1047 self,
1048 async_kp: AsyncKp,
1049 ) -> crate::async_lock::KpThenAsyncKeyPath<
1050 R,
1051 V,
1052 <AsyncKp::Value as KeyPathValueTarget>::Target,
1053 Root,
1054 Value,
1055 AsyncKp::Value,
1056 MutRoot,
1057 MutValue,
1058 AsyncKp::MutValue,
1059 Self,
1060 AsyncKp,
1061 >
1062 where
1063 V: 'static,
1064 Value: std::borrow::Borrow<V>,
1065 MutValue: std::borrow::BorrowMut<V>,
1066 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
1067 AsyncKp::Value: KeyPathValueTarget
1068 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1069 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1070 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
1071 Self: Sized;
1072}
1073
1074impl<R, V, Root, Value, MutRoot, MutValue, G, S> ChainExt<R, V, Root, Value, MutRoot, MutValue>
1075 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1076where
1077 Root: std::borrow::Borrow<R>,
1078 Value: std::borrow::Borrow<V>,
1079 MutRoot: std::borrow::BorrowMut<R>,
1080 MutValue: std::borrow::BorrowMut<V>,
1081 G: Fn(Root) -> Option<Value>,
1082 S: Fn(MutRoot) -> Option<MutValue>,
1083{
1084 fn then_lock<
1085 Lock,
1086 Mid,
1087 V2,
1088 LockValue,
1089 MidValue,
1090 Value2,
1091 MutLock,
1092 MutMid,
1093 MutValue2,
1094 G1,
1095 S1,
1096 L,
1097 G2,
1098 S2,
1099 >(
1100 self,
1101 lock_kp: crate::lock::LockKp<
1102 V,
1103 Lock,
1104 Mid,
1105 V2,
1106 Value,
1107 LockValue,
1108 MidValue,
1109 Value2,
1110 MutValue,
1111 MutLock,
1112 MutMid,
1113 MutValue2,
1114 G1,
1115 S1,
1116 L,
1117 G2,
1118 S2,
1119 >,
1120 ) -> crate::lock::KpThenLockKp<
1121 R,
1122 V,
1123 V2,
1124 Root,
1125 Value,
1126 Value2,
1127 MutRoot,
1128 MutValue,
1129 MutValue2,
1130 Self,
1131 crate::lock::LockKp<
1132 V,
1133 Lock,
1134 Mid,
1135 V2,
1136 Value,
1137 LockValue,
1138 MidValue,
1139 Value2,
1140 MutValue,
1141 MutLock,
1142 MutMid,
1143 MutValue2,
1144 G1,
1145 S1,
1146 L,
1147 G2,
1148 S2,
1149 >,
1150 >
1151 where
1152 V: 'static + Clone,
1153 V2: 'static,
1154 Value: std::borrow::Borrow<V>,
1155 Value2: std::borrow::Borrow<V2>,
1156 MutValue: std::borrow::BorrowMut<V>,
1157 MutValue2: std::borrow::BorrowMut<V2>,
1158 LockValue: std::borrow::Borrow<Lock>,
1159 MidValue: std::borrow::Borrow<Mid>,
1160 MutLock: std::borrow::BorrowMut<Lock>,
1161 MutMid: std::borrow::BorrowMut<Mid>,
1162 G1: Fn(Value) -> Option<LockValue>,
1163 S1: Fn(MutValue) -> Option<MutLock>,
1164 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
1165 G2: Fn(MidValue) -> Option<Value2>,
1166 S2: Fn(MutMid) -> Option<MutValue2>,
1167 {
1168 crate::lock::KpThenLockKp {
1169 first: self,
1170 second: lock_kp,
1171 _p: std::marker::PhantomData,
1172 }
1173 }
1174
1175 #[cfg(feature = "pin_project")]
1176 fn then_pin_future<Struct, Output, L>(
1177 self,
1178 pin_fut: L,
1179 ) -> crate::pin::KpThenPinFuture<R, Struct, Output, Root, MutRoot, Value, MutValue, Self, L>
1180 where
1181 V: 'static,
1182 Struct: Unpin + 'static,
1183 Output: 'static,
1184 Value: std::borrow::Borrow<Struct>,
1185 MutValue: std::borrow::BorrowMut<Struct>,
1186 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
1187 {
1188 crate::pin::KpThenPinFuture {
1189 first: self,
1190 second: pin_fut,
1191 _p: std::marker::PhantomData,
1192 }
1193 }
1194
1195 fn then_async<AsyncKp>(
1196 self,
1197 async_kp: AsyncKp,
1198 ) -> crate::async_lock::KpThenAsyncKeyPath<
1199 R,
1200 V,
1201 <AsyncKp::Value as KeyPathValueTarget>::Target,
1202 Root,
1203 Value,
1204 AsyncKp::Value,
1205 MutRoot,
1206 MutValue,
1207 AsyncKp::MutValue,
1208 Self,
1209 AsyncKp,
1210 >
1211 where
1212 V: 'static,
1213 Value: std::borrow::Borrow<V>,
1214 MutValue: std::borrow::BorrowMut<V>,
1215 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
1216 AsyncKp::Value: KeyPathValueTarget
1217 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1218 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1219 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
1220 {
1221 crate::async_lock::KpThenAsyncKeyPath {
1222 first: self,
1223 second: async_kp,
1224 _p: std::marker::PhantomData,
1225 }
1226 }
1227}
1228
1229pub trait AccessorTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
1230 KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1231{
1232 #[inline]
1234 fn get_optional(&self, root: Option<Root>) -> Option<Value> {
1235 root.and_then(|r| self.get(r))
1236 }
1237
1238 #[inline]
1240 fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue> {
1241 root.and_then(|r| self.get_mut(r))
1242 }
1243
1244 #[inline]
1246 fn get_or_else<F>(&self, root: Root, f: F) -> Value
1247 where
1248 F: FnOnce() -> Value,
1249 {
1250 self.get(root).unwrap_or_else(f)
1251 }
1252
1253 #[inline]
1255 fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
1256 where
1257 F: FnOnce() -> MutValue,
1258 {
1259 self.get_mut(root).unwrap_or_else(f)
1260 }
1261}
1262
1263pub trait CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
1264 KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1265where
1266 Root: std::borrow::Borrow<R>,
1267 Value: std::borrow::Borrow<V>,
1268 MutRoot: std::borrow::BorrowMut<R>,
1269 MutValue: std::borrow::BorrowMut<V>,
1270 G: Fn(Root) -> Option<Value>,
1271 S: Fn(MutRoot) -> Option<MutValue>,
1272{
1273 fn for_arc<'b>(
1274 &self,
1275 ) -> Kp<
1276 std::sync::Arc<R>,
1277 V,
1278 std::sync::Arc<R>,
1279 Value,
1280 std::sync::Arc<R>,
1281 MutValue,
1282 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1283 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1284 >
1285 where
1286 R: 'b,
1287 V: 'b,
1288 Root: for<'a> From<&'a R>,
1289 MutRoot: for<'a> From<&'a mut R>,
1290 {
1291 Kp::new(
1292 move |arc_root: std::sync::Arc<R>| {
1293 let r_ref: &R = &*arc_root;
1294 self.get(Root::from(r_ref))
1295 },
1296 move |mut arc_root: std::sync::Arc<R>| {
1297 std::sync::Arc::get_mut(&mut arc_root)
1299 .and_then(|r_mut| self.get_mut(MutRoot::from(r_mut)))
1300 },
1301 )
1302 }
1303
1304 fn for_box<'a>(
1305 &self,
1306 ) -> Kp<
1307 Box<R>,
1308 V,
1309 Box<R>,
1310 Value,
1311 Box<R>,
1312 MutValue,
1313 impl Fn(Box<R>) -> Option<Value>,
1314 impl Fn(Box<R>) -> Option<MutValue>,
1315 >
1316 where
1317 R: 'a,
1318 V: 'a,
1319 Root: for<'b> From<&'b R>,
1320 MutRoot: for<'b> From<&'b mut R>,
1321 {
1322 Kp::new(
1323 move |r: Box<R>| {
1324 let r_ref: &R = r.as_ref();
1325 self.get(Root::from(r_ref))
1326 },
1327 move |mut r: Box<R>| {
1328 self.get_mut(MutRoot::from(r.as_mut()))
1330 },
1331 )
1332 }
1333}
1334
1335pub trait HOFTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
1336 KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1337where
1338 Root: std::borrow::Borrow<R>,
1339 Value: std::borrow::Borrow<V>,
1340 MutRoot: std::borrow::BorrowMut<R>,
1341 MutValue: std::borrow::BorrowMut<V>,
1342 G: Fn(Root) -> Option<Value>,
1343 S: Fn(MutRoot) -> Option<MutValue>,
1344{
1345 fn map<MappedValue, F>(
1395 &self,
1396 mapper: F,
1397 ) -> Kp<
1398 R,
1399 MappedValue,
1400 Root,
1401 MappedValue,
1402 MutRoot,
1403 MappedValue,
1404 impl Fn(Root) -> Option<MappedValue> + '_,
1405 impl Fn(MutRoot) -> Option<MappedValue> + '_,
1406 >
1407 where
1408 F: Fn(&V) -> MappedValue + Copy + 'static,
1409 V: 'static,
1410 MappedValue: 'static,
1411 {
1412 Kp::new(
1413 move |root: Root| {
1414 self.get(root).map(|value| {
1415 let v: &V = value.borrow();
1416 mapper(v)
1417 })
1418 },
1419 move |root: MutRoot| {
1420 self.get_mut(root).map(|value| {
1421 let v: &V = value.borrow();
1422 mapper(v)
1423 })
1424 },
1425 )
1426 }
1427
1428 fn filter<F>(
1430 &self,
1431 predicate: F,
1432 ) -> Kp<
1433 R,
1434 V,
1435 Root,
1436 Value,
1437 MutRoot,
1438 MutValue,
1439 impl Fn(Root) -> Option<Value> + '_,
1440 impl Fn(MutRoot) -> Option<MutValue> + '_,
1441 >
1442 where
1443 F: Fn(&V) -> bool + Copy + 'static,
1444 V: 'static,
1445 {
1446 Kp::new(
1447 move |root: Root| {
1448 self.get(root).filter(|value| {
1449 let v: &V = value.borrow();
1450 predicate(v)
1451 })
1452 },
1453 move |root: MutRoot| {
1454 self.get_mut(root).filter(|value| {
1455 let v: &V = value.borrow();
1456 predicate(v)
1457 })
1458 },
1459 )
1460 }
1461
1462 fn filter_map<MappedValue, F>(
1464 &self,
1465 mapper: F,
1466 ) -> Kp<
1467 R,
1468 MappedValue,
1469 Root,
1470 MappedValue,
1471 MutRoot,
1472 MappedValue,
1473 impl Fn(Root) -> Option<MappedValue> + '_,
1474 impl Fn(MutRoot) -> Option<MappedValue> + '_,
1475 >
1476 where
1477 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1478 V: 'static,
1479 MappedValue: 'static,
1480 {
1481 Kp::new(
1482 move |root: Root| {
1483 self.get(root).and_then(|value| {
1484 let v: &V = value.borrow();
1485 mapper(v)
1486 })
1487 },
1488 move |root: MutRoot| {
1489 self.get_mut(root).and_then(|value| {
1490 let v: &V = value.borrow();
1491 mapper(v)
1492 })
1493 },
1494 )
1495 }
1496
1497 fn inspect<F>(
1499 &self,
1500 inspector: F,
1501 ) -> Kp<
1502 R,
1503 V,
1504 Root,
1505 Value,
1506 MutRoot,
1507 MutValue,
1508 impl Fn(Root) -> Option<Value> + '_,
1509 impl Fn(MutRoot) -> Option<MutValue> + '_,
1510 >
1511 where
1512 F: Fn(&V) + Copy + 'static,
1513 V: 'static,
1514 {
1515 Kp::new(
1516 move |root: Root| {
1517 self.get(root).map(|value| {
1518 let v: &V = value.borrow();
1519 inspector(v);
1520 value
1521 })
1522 },
1523 move |root: MutRoot| {
1524 self.get_mut(root).map(|value| {
1525 let v: &V = value.borrow();
1526 inspector(v);
1527 value
1528 })
1529 },
1530 )
1531 }
1532
1533 fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item> + '_
1535 where
1536 F: Fn(&V) -> I + 'static,
1537 V: 'static,
1538 I: IntoIterator<Item = Item>,
1539 Item: 'static,
1540 {
1541 move |root: Root| {
1542 self.get(root)
1543 .map(|value| {
1544 let v: &V = value.borrow();
1545 mapper(v).into_iter().collect()
1546 })
1547 .unwrap_or_else(Vec::new)
1548 }
1549 }
1550
1551 fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc + '_
1553 where
1554 F: Fn(Acc, &V) -> Acc + 'static,
1555 V: 'static,
1556 Acc: Copy + 'static,
1557 {
1558 move |root: Root| {
1559 self.get(root)
1560 .map(|value| {
1561 let v: &V = value.borrow();
1562 folder(init, v)
1563 })
1564 .unwrap_or(init)
1565 }
1566 }
1567
1568 fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
1570 where
1571 F: Fn(&V) -> bool + 'static,
1572 V: 'static,
1573 {
1574 move |root: Root| {
1575 self.get(root)
1576 .map(|value| {
1577 let v: &V = value.borrow();
1578 predicate(v)
1579 })
1580 .unwrap_or(false)
1581 }
1582 }
1583
1584 fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
1586 where
1587 F: Fn(&V) -> bool + 'static,
1588 V: 'static,
1589 {
1590 move |root: Root| {
1591 self.get(root)
1592 .map(|value| {
1593 let v: &V = value.borrow();
1594 predicate(v)
1595 })
1596 .unwrap_or(true)
1597 }
1598 }
1599
1600 fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize> + '_
1602 where
1603 F: Fn(&V) -> usize + 'static,
1604 V: 'static,
1605 {
1606 move |root: Root| {
1607 self.get(root).map(|value| {
1608 let v: &V = value.borrow();
1609 counter(v)
1610 })
1611 }
1612 }
1613
1614 fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item> + '_
1616 where
1617 F: Fn(&V) -> Option<Item> + 'static,
1618 V: 'static,
1619 Item: 'static,
1620 {
1621 move |root: Root| {
1622 self.get(root).and_then(|value| {
1623 let v: &V = value.borrow();
1624 finder(v)
1625 })
1626 }
1627 }
1628
1629 fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output> + '_
1631 where
1632 F: Fn(&V, usize) -> Output + 'static,
1633 V: 'static,
1634 Output: 'static,
1635 {
1636 move |root: Root| {
1637 self.get(root).map(|value| {
1638 let v: &V = value.borrow();
1639 taker(v, n)
1640 })
1641 }
1642 }
1643
1644 fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output> + '_
1646 where
1647 F: Fn(&V, usize) -> Output + 'static,
1648 V: 'static,
1649 Output: 'static,
1650 {
1651 move |root: Root| {
1652 self.get(root).map(|value| {
1653 let v: &V = value.borrow();
1654 skipper(v, n)
1655 })
1656 }
1657 }
1658
1659 fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output> + '_
1661 where
1662 F: Fn(&V) -> Output + 'static,
1663 V: 'static,
1664 Output: 'static,
1665 {
1666 move |root: Root| {
1667 self.get(root).map(|value| {
1668 let v: &V = value.borrow();
1669 partitioner(v)
1670 })
1671 }
1672 }
1673
1674 fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item> + '_
1676 where
1677 F: Fn(&V) -> Option<Item> + 'static,
1678 V: 'static,
1679 Item: 'static,
1680 {
1681 move |root: Root| {
1682 self.get(root).and_then(|value| {
1683 let v: &V = value.borrow();
1684 min_fn(v)
1685 })
1686 }
1687 }
1688
1689 fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item> + '_
1691 where
1692 F: Fn(&V) -> Option<Item> + 'static,
1693 V: 'static,
1694 Item: 'static,
1695 {
1696 move |root: Root| {
1697 self.get(root).and_then(|value| {
1698 let v: &V = value.borrow();
1699 max_fn(v)
1700 })
1701 }
1702 }
1703
1704 fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum> + '_
1706 where
1707 F: Fn(&V) -> Sum + 'static,
1708 V: 'static,
1709 Sum: 'static,
1710 {
1711 move |root: Root| {
1712 self.get(root).map(|value| {
1713 let v: &V = value.borrow();
1714 sum_fn(v)
1715 })
1716 }
1717 }
1718
1719 }
1770
1771impl<R, V, Root, Value, MutRoot, MutValue, G, S> KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1772 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1773where
1774 Root: std::borrow::Borrow<R>,
1775 Value: std::borrow::Borrow<V>,
1776 MutRoot: std::borrow::BorrowMut<R>,
1777 MutValue: std::borrow::BorrowMut<V>,
1778 G: Fn(Root) -> Option<Value>,
1779 S: Fn(MutRoot) -> Option<MutValue>,
1780{
1781 #[inline]
1782 fn get(&self, root: Root) -> Option<Value> {
1783 (self.get)(root)
1784 }
1785
1786 #[inline]
1787 fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1788 (self.set)(root)
1789 }
1790
1791 fn then<SV, SubValue, MutSubValue, G2, S2>(
1792 self,
1793 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1794 ) -> Kp<
1795 R,
1796 SV,
1797 Root,
1798 SubValue,
1799 MutRoot,
1800 MutSubValue,
1801 impl Fn(Root) -> Option<SubValue>,
1802 impl Fn(MutRoot) -> Option<MutSubValue>,
1803 >
1804 where
1805 SubValue: std::borrow::Borrow<SV>,
1806 MutSubValue: std::borrow::BorrowMut<SV>,
1807 G2: Fn(Value) -> Option<SubValue>,
1808 S2: Fn(MutValue) -> Option<MutSubValue>,
1809 V: 'static,
1810 {
1811 Kp::new(
1812 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
1813 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
1814 )
1815 }
1816}
1817
1818impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1819 CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1820 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1821where
1822 Root: std::borrow::Borrow<R>,
1823 Value: std::borrow::Borrow<V>,
1824 MutRoot: std::borrow::BorrowMut<R>,
1825 MutValue: std::borrow::BorrowMut<V>,
1826 G: Fn(Root) -> Option<Value>,
1827 S: Fn(MutRoot) -> Option<MutValue>,
1828{
1829}
1830
1831impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1832 HOFTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1833 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1834where
1835 Root: std::borrow::Borrow<R>,
1836 Value: std::borrow::Borrow<V>,
1837 MutRoot: std::borrow::BorrowMut<R>,
1838 MutValue: std::borrow::BorrowMut<V>,
1839 G: Fn(Root) -> Option<Value>,
1840 S: Fn(MutRoot) -> Option<MutValue>,
1841{
1842}
1843#[derive(Clone)]
1855pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1856where
1857 Root: std::borrow::Borrow<R>,
1858 MutRoot: std::borrow::BorrowMut<R>,
1859 MutValue: std::borrow::BorrowMut<V>,
1860 G: Fn(Root) -> Option<Value>,
1861 S: Fn(MutRoot) -> Option<MutValue>,
1862{
1863 pub(crate) get: G,
1865 pub(crate) set: S,
1867 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
1868}
1869
1870unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Send
1872 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1873where
1874 Root: std::borrow::Borrow<R>,
1875 MutRoot: std::borrow::BorrowMut<R>,
1876 MutValue: std::borrow::BorrowMut<V>,
1877 G: Fn(Root) -> Option<Value> + Send,
1878 S: Fn(MutRoot) -> Option<MutValue> + Send,
1879{
1880}
1881unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Sync
1882 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1883where
1884 Root: std::borrow::Borrow<R>,
1885 MutRoot: std::borrow::BorrowMut<R>,
1886 MutValue: std::borrow::BorrowMut<V>,
1887 G: Fn(Root) -> Option<Value> + Sync,
1888 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1889{
1890}
1891
1892impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1893where
1894 Root: std::borrow::Borrow<R>,
1895 Value: std::borrow::Borrow<V>,
1896 MutRoot: std::borrow::BorrowMut<R>,
1897 MutValue: std::borrow::BorrowMut<V>,
1898 G: Fn(Root) -> Option<Value>,
1899 S: Fn(MutRoot) -> Option<MutValue>,
1900{
1901 pub fn new(get: G, set: S) -> Self {
1902 Self {
1903 get: get,
1904 set: set,
1905 _p: std::marker::PhantomData,
1906 }
1907 }
1908
1909 #[inline]
1910 pub fn get(&self, root: Root) -> Option<Value> {
1911 (self.get)(root)
1912 }
1913
1914 #[inline]
1915 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1916 (self.set)(root)
1917 }
1918
1919 #[inline]
1920 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
1921 self,
1922 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1923 ) -> Kp<
1924 R,
1925 SV,
1926 Root,
1927 SubValue,
1928 MutRoot,
1929 MutSubValue,
1930 impl Fn(Root) -> Option<SubValue>,
1931 impl Fn(MutRoot) -> Option<MutSubValue>,
1932 >
1933 where
1934 SubValue: std::borrow::Borrow<SV>,
1935 MutSubValue: std::borrow::BorrowMut<SV>,
1936 G2: Fn(Value) -> Option<SubValue>,
1937 S2: Fn(MutValue) -> Option<MutSubValue>,
1938 V: 'static,
1939 {
1940 Kp::new(
1941 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
1942 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
1943 )
1944 }
1945
1946}
1947pub fn zip_kps<'a, RootType, Value1, Value2>(
1961 kp1: &'a KpType<'a, RootType, Value1>,
1962 kp2: &'a KpType<'a, RootType, Value2>,
1963) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1964where
1965 RootType: 'a,
1966 Value1: 'a,
1967 Value2: 'a,
1968{
1969 move |root: &'a RootType| {
1970 let val1 = (kp1.get)(root)?;
1971 let val2 = (kp2.get)(root)?;
1972 Some((val1, val2))
1973 }
1974}
1975
1976impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1977where
1978 Root: std::borrow::Borrow<R>,
1979 MutRoot: std::borrow::BorrowMut<R>,
1980 G: Fn(Root) -> Option<Root>,
1981 S: Fn(MutRoot) -> Option<MutRoot>,
1982{
1983 pub fn identity_typed() -> Kp<
1984 R,
1985 R,
1986 Root,
1987 Root,
1988 MutRoot,
1989 MutRoot,
1990 fn(Root) -> Option<Root>,
1991 fn(MutRoot) -> Option<MutRoot>,
1992 > {
1993 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1994 }
1995
1996 pub fn identity<'a>() -> KpType<'a, R, R> {
1997 KpType::new(|r| Some(r), |r| Some(r))
1998 }
1999}
2000
2001pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2010where
2011 Root: std::borrow::Borrow<Enum>,
2012 Value: std::borrow::Borrow<Variant>,
2013 MutRoot: std::borrow::BorrowMut<Enum>,
2014 MutValue: std::borrow::BorrowMut<Variant>,
2015 G: Fn(Root) -> Option<Value>,
2016 S: Fn(MutRoot) -> Option<MutValue>,
2017 E: Fn(Variant) -> Enum,
2018{
2019 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
2020 embedder: E,
2021}
2022
2023unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
2025 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2026where
2027 Root: std::borrow::Borrow<Enum>,
2028 Value: std::borrow::Borrow<Variant>,
2029 MutRoot: std::borrow::BorrowMut<Enum>,
2030 MutValue: std::borrow::BorrowMut<Variant>,
2031 G: Fn(Root) -> Option<Value> + Send,
2032 S: Fn(MutRoot) -> Option<MutValue> + Send,
2033 E: Fn(Variant) -> Enum + Send,
2034{
2035}
2036unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
2037 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2038where
2039 Root: std::borrow::Borrow<Enum>,
2040 Value: std::borrow::Borrow<Variant>,
2041 MutRoot: std::borrow::BorrowMut<Enum>,
2042 MutValue: std::borrow::BorrowMut<Variant>,
2043 G: Fn(Root) -> Option<Value> + Sync,
2044 S: Fn(MutRoot) -> Option<MutValue> + Sync,
2045 E: Fn(Variant) -> Enum + Sync,
2046{
2047}
2048
2049impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2050 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2051where
2052 Root: std::borrow::Borrow<Enum>,
2053 Value: std::borrow::Borrow<Variant>,
2054 MutRoot: std::borrow::BorrowMut<Enum>,
2055 MutValue: std::borrow::BorrowMut<Variant>,
2056 G: Fn(Root) -> Option<Value>,
2057 S: Fn(MutRoot) -> Option<MutValue>,
2058 E: Fn(Variant) -> Enum,
2059{
2060 pub fn new(
2062 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
2063 embedder: E,
2064 ) -> Self {
2065 Self {
2066 extractor,
2067 embedder,
2068 }
2069 }
2070
2071 pub fn get(&self, enum_value: Root) -> Option<Value> {
2073 self.extractor.get(enum_value)
2074 }
2075
2076 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
2078 self.extractor.get_mut(enum_value)
2079 }
2080
2081 pub fn embed(&self, value: Variant) -> Enum {
2083 (self.embedder)(value)
2084 }
2085
2086 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2088 &self.extractor
2089 }
2090
2091 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2093 self.extractor
2094 }
2095
2096 pub fn map<MappedValue, F>(
2107 &self,
2108 mapper: F,
2109 ) -> EnumKp<
2110 Enum,
2111 MappedValue,
2112 Root,
2113 MappedValue,
2114 MutRoot,
2115 MappedValue,
2116 impl Fn(Root) -> Option<MappedValue>,
2117 impl Fn(MutRoot) -> Option<MappedValue>,
2118 impl Fn(MappedValue) -> Enum,
2119 >
2120 where
2121 F: Fn(&Variant) -> MappedValue + Copy + 'static,
2124 Variant: 'static,
2125 MappedValue: 'static,
2126 E: Fn(Variant) -> Enum + Copy + 'static,
2128 {
2129 let mapped_extractor = self.extractor.map(mapper);
2130
2131 let new_embedder = move |_value: MappedValue| -> Enum {
2135 panic!(
2136 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
2137 )
2138 };
2139
2140 EnumKp::new(mapped_extractor, new_embedder)
2141 }
2142
2143 pub fn filter<F>(
2155 &self,
2156 predicate: F,
2157 ) -> EnumKp<
2158 Enum,
2159 Variant,
2160 Root,
2161 Value,
2162 MutRoot,
2163 MutValue,
2164 impl Fn(Root) -> Option<Value>,
2165 impl Fn(MutRoot) -> Option<MutValue>,
2166 E,
2167 >
2168 where
2169 F: Fn(&Variant) -> bool + Copy + 'static,
2172 Variant: 'static,
2173 E: Copy,
2175 {
2176 let filtered_extractor = self.extractor.filter(predicate);
2177 EnumKp::new(filtered_extractor, self.embedder)
2178 }
2179}
2180
2181pub type EnumKpType<'a, Enum, Variant> = EnumKp<
2183 Enum,
2184 Variant,
2185 &'a Enum,
2186 &'a Variant,
2187 &'a mut Enum,
2188 &'a mut Variant,
2189 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2190 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2191 fn(Variant) -> Enum,
2192>;
2193
2194pub fn enum_variant<'a, Enum, Variant>(
2212 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2213 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2214 embedder: fn(Variant) -> Enum,
2215) -> EnumKpType<'a, Enum, Variant> {
2216 EnumKp::new(Kp::new(getter, setter), embedder)
2217}
2218
2219pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
2229 EnumKp::new(
2230 Kp::new(
2231 |r: &Result<T, E>| r.as_ref().ok(),
2232 |r: &mut Result<T, E>| r.as_mut().ok(),
2233 ),
2234 |t: T| Ok(t),
2235 )
2236}
2237
2238pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
2248 EnumKp::new(
2249 Kp::new(
2250 |r: &Result<T, E>| r.as_ref().err(),
2251 |r: &mut Result<T, E>| r.as_mut().err(),
2252 ),
2253 |e: E| Err(e),
2254 )
2255}
2256
2257pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
2267 EnumKp::new(
2268 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
2269 |t: T| Some(t),
2270 )
2271}
2272
2273pub fn variant_of<'a, Enum, Variant>(
2291 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2292 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2293 embedder: fn(Variant) -> Enum,
2294) -> EnumKpType<'a, Enum, Variant> {
2295 enum_variant(getter, setter, embedder)
2296}
2297
2298pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
2311 Kp::new(
2312 |b: &Box<T>| Some(b.as_ref()),
2313 |b: &mut Box<T>| Some(b.as_mut()),
2314 )
2315}
2316
2317pub fn kp_arc<'a, T>() -> Kp<
2328 Arc<T>,
2329 T,
2330 &'a Arc<T>,
2331 &'a T,
2332 &'a mut Arc<T>,
2333 &'a mut T,
2334 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
2335 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
2336> {
2337 Kp::new(
2338 |arc: &Arc<T>| Some(arc.as_ref()),
2339 |arc: &mut Arc<T>| Arc::get_mut(arc),
2340 )
2341}
2342
2343pub fn kp_rc<'a, T>() -> Kp<
2354 std::rc::Rc<T>,
2355 T,
2356 &'a std::rc::Rc<T>,
2357 &'a T,
2358 &'a mut std::rc::Rc<T>,
2359 &'a mut T,
2360 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
2361 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
2362> {
2363 Kp::new(
2364 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
2365 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
2366 )
2367}
2368
2369use std::any::{Any, TypeId};
2372use std::rc::Rc;
2373
2374#[cfg(test)]
2389mod tests {
2390 use super::*;
2391 use std::collections::HashMap;
2392
2393 fn kp_adaptable<T, Root, Value, MutRoot, MutValue, G, S>(kp: T)
2394 where
2395 T: KpTrait<TestKP, String, Root, Value, MutRoot, MutValue, G, S>,
2396 {
2397 }
2400 fn test_kp_trait() {}
2401
2402 #[derive(Debug)]
2403 struct TestKP {
2404 a: String,
2405 b: String,
2406 c: std::sync::Arc<String>,
2407 d: std::sync::Mutex<String>,
2408 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
2409 f: Option<TestKP2>,
2410 g: HashMap<i32, TestKP2>,
2411 }
2412
2413 impl TestKP {
2414 fn new() -> Self {
2415 Self {
2416 a: String::from("a"),
2417 b: String::from("b"),
2418 c: std::sync::Arc::new(String::from("c")),
2419 d: std::sync::Mutex::new(String::from("d")),
2420 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2421 f: Some(TestKP2 {
2422 a: String::from("a3"),
2423 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2424 }),
2425 g: HashMap::new(),
2426 }
2427 }
2428
2429 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2430 KpComposed::from_closures(
2431 move |r: &TestKP| r.g.get(&index),
2432 move |r: &mut TestKP| r.g.get_mut(&index),
2433 )
2434 }
2435
2436 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2439 TestKP2,
2440 String,
2441 Root,
2442 Value,
2443 MutRoot,
2444 MutValue,
2445 impl Fn(Root) -> Option<Value>,
2446 impl Fn(MutRoot) -> Option<MutValue>,
2447 >
2448 where
2449 Root: std::borrow::Borrow<TestKP2>,
2450 MutRoot: std::borrow::BorrowMut<TestKP2>,
2451 Value: std::borrow::Borrow<String> + From<String>,
2452 MutValue: std::borrow::BorrowMut<String> + From<String>,
2453 {
2454 Kp::new(
2455 |r: Root| Some(Value::from(r.borrow().a.clone())),
2456 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2457 )
2458 }
2459
2460 fn c<'a>() -> KpType<'a, TestKP, String> {
2463 KpType::new(
2464 |r: &TestKP| Some(r.c.as_ref()),
2465 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2466 Some(arc_str) => Some(arc_str),
2467 None => None,
2468 },
2469 )
2470 }
2471
2472 fn a<'a>() -> KpType<'a, TestKP, String> {
2473 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2474 }
2475
2476 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2477 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2478 }
2479
2480 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2481 KpType::identity()
2482 }
2483 }
2484
2485 #[derive(Debug)]
2486 struct TestKP2 {
2487 a: String,
2488 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2489 }
2490
2491 impl TestKP2 {
2492 fn new() -> Self {
2493 TestKP2 {
2494 a: String::from("a2"),
2495 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2496 }
2497 }
2498
2499 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2500 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2507 fn(MutRoot) -> Option<MutRoot>,
2508 >
2509 where
2510 Root: std::borrow::Borrow<TestKP2>,
2511 MutRoot: std::borrow::BorrowMut<TestKP2>,
2512 G: Fn(Root) -> Option<Root>,
2513 S: Fn(MutRoot) -> Option<MutRoot>,
2514 {
2515 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2516 }
2517
2518 fn a<'a>() -> KpType<'a, TestKP2, String> {
2519 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2520 }
2521
2522 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2523 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2524 }
2525
2526 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2531 KpType::identity()
2532 }
2533 }
2534
2535 #[derive(Debug)]
2536 struct TestKP3 {
2537 a: String,
2538 b: std::sync::Arc<std::sync::Mutex<String>>,
2539 }
2540
2541 impl TestKP3 {
2542 fn new() -> Self {
2543 TestKP3 {
2544 a: String::from("a2"),
2545 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2546 }
2547 }
2548
2549 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2550 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2557 fn(MutRoot) -> Option<MutRoot>,
2558 >
2559 where
2560 Root: std::borrow::Borrow<TestKP3>,
2561 MutRoot: std::borrow::BorrowMut<TestKP3>,
2562 G: Fn(Root) -> Option<Root>,
2563 S: Fn(MutRoot) -> Option<MutRoot>,
2564 {
2565 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2566 }
2567
2568 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2569 KpType::identity()
2570 }
2571 }
2572
2573 impl TestKP3 {}
2574
2575 impl TestKP {}
2576 #[test]
2577 fn test_a() {
2578 let instance2 = TestKP2::new();
2579 let mut instance = TestKP::new();
2580 let kp = TestKP::identity();
2581 let kp_a = TestKP::a();
2582 let wres = TestKP::f()
2584 .then(TestKP2::a())
2585 .get_mut(&mut instance)
2586 .unwrap();
2587 *wres = String::from("a3 changed successfully");
2588 let res = TestKP::f().then(TestKP2::a()).get(&instance);
2589 println!("{:?}", res);
2590 let res = TestKP::f().then(TestKP2::identity()).get(&instance);
2591 println!("{:?}", res);
2592 let res = kp.get(&instance);
2593 println!("{:?}", res);
2594
2595 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2596 println!("{:?}", new_kp_from_hashmap.get(&instance));
2597 }
2598
2599 #[test]
2678 fn test_enum_kp_result_ok() {
2679 let ok_result: Result<String, i32> = Ok("success".to_string());
2680 let mut err_result: Result<String, i32> = Err(42);
2681
2682 let ok_kp = enum_ok();
2683
2684 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2686 assert_eq!(ok_kp.get(&err_result), None);
2687
2688 let embedded = ok_kp.embed("embedded".to_string());
2690 assert_eq!(embedded, Ok("embedded".to_string()));
2691
2692 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2694 *val = "modified".to_string();
2695 }
2696 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2699 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2700 *val = "modified".to_string();
2701 }
2702 assert_eq!(ok_result2, Ok("modified".to_string()));
2703 }
2704
2705 #[test]
2706 fn test_enum_kp_result_err() {
2707 let ok_result: Result<String, i32> = Ok("success".to_string());
2708 let mut err_result: Result<String, i32> = Err(42);
2709
2710 let err_kp = enum_err();
2711
2712 assert_eq!(err_kp.get(&err_result), Some(&42));
2714 assert_eq!(err_kp.get(&ok_result), None);
2715
2716 let embedded = err_kp.embed(99);
2718 assert_eq!(embedded, Err(99));
2719
2720 if let Some(val) = err_kp.get_mut(&mut err_result) {
2722 *val = 100;
2723 }
2724 assert_eq!(err_result, Err(100));
2725 }
2726
2727 #[test]
2728 fn test_enum_kp_option_some() {
2729 let some_opt = Some("value".to_string());
2730 let mut none_opt: Option<String> = None;
2731
2732 let some_kp = enum_some();
2733
2734 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2736 assert_eq!(some_kp.get(&none_opt), None);
2737
2738 let embedded = some_kp.embed("embedded".to_string());
2740 assert_eq!(embedded, Some("embedded".to_string()));
2741
2742 let mut some_opt2 = Some("original".to_string());
2744 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2745 *val = "modified".to_string();
2746 }
2747 assert_eq!(some_opt2, Some("modified".to_string()));
2748 }
2749
2750 #[test]
2751 fn test_enum_kp_custom_enum() {
2752 #[derive(Debug, PartialEq)]
2753 enum MyEnum {
2754 A(String),
2755 B(i32),
2756 C,
2757 }
2758
2759 let mut enum_a = MyEnum::A("hello".to_string());
2760 let enum_b = MyEnum::B(42);
2761 let enum_c = MyEnum::C;
2762
2763 let kp_a = enum_variant(
2765 |e: &MyEnum| match e {
2766 MyEnum::A(s) => Some(s),
2767 _ => None,
2768 },
2769 |e: &mut MyEnum| match e {
2770 MyEnum::A(s) => Some(s),
2771 _ => None,
2772 },
2773 |s: String| MyEnum::A(s),
2774 );
2775
2776 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2778 assert_eq!(kp_a.get(&enum_b), None);
2779 assert_eq!(kp_a.get(&enum_c), None);
2780
2781 let embedded = kp_a.embed("world".to_string());
2783 assert_eq!(embedded, MyEnum::A("world".to_string()));
2784
2785 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2787 *val = "modified".to_string();
2788 }
2789 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2790 }
2791
2792 #[test]
2793 fn test_container_kp_box() {
2794 let boxed = Box::new("value".to_string());
2795 let mut boxed_mut = Box::new("original".to_string());
2796
2797 let box_kp = kp_box();
2798
2799 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2801
2802 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2804 *val = "modified".to_string();
2805 }
2806 assert_eq!(*boxed_mut, "modified".to_string());
2807 }
2808
2809 #[test]
2810 fn test_container_kp_arc() {
2811 let arc = Arc::new("value".to_string());
2812 let mut arc_mut = Arc::new("original".to_string());
2813
2814 let arc_kp = kp_arc();
2815
2816 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2818
2819 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2821 *val = "modified".to_string();
2822 }
2823 assert_eq!(*arc_mut, "modified".to_string());
2824
2825 let arc_shared = Arc::new("shared".to_string());
2827 let arc_shared2 = Arc::clone(&arc_shared);
2828 let mut arc_shared_mut = arc_shared;
2829 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2830 }
2831
2832 #[test]
2833 fn test_enum_kp_composition() {
2834 #[derive(Debug, PartialEq)]
2836 struct Inner {
2837 value: String,
2838 }
2839
2840 let result: Result<Inner, i32> = Ok(Inner {
2841 value: "nested".to_string(),
2842 });
2843
2844 let inner_kp = KpType::new(
2846 |i: &Inner| Some(&i.value),
2847 |i: &mut Inner| Some(&mut i.value),
2848 );
2849
2850 let ok_kp = enum_ok::<Inner, i32>();
2852 let ok_kp_base = ok_kp.into_kp();
2853 let composed = ok_kp_base.then(inner_kp);
2854
2855 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2856 }
2857
2858 #[test]
2859 fn test_pkp_basic() {
2860 #[derive(Debug)]
2861 struct User {
2862 name: String,
2863 age: i32,
2864 }
2865
2866 let user = User {
2867 name: "Akash".to_string(),
2868 age: 30,
2869 };
2870
2871 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2873 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2874
2875 let name_pkp = PKp::new(name_kp);
2877 let age_pkp = PKp::new(age_kp);
2878
2879 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Akash".to_string()));
2881 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2882
2883 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2885 assert_eq!(age_pkp.get_as::<String>(&user), None);
2886
2887 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2889 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2890 }
2891
2892 #[test]
2893 fn test_pkp_collection() {
2894 #[derive(Debug)]
2895 struct User {
2896 name: String,
2897 age: i32,
2898 }
2899
2900 let user = User {
2901 name: "Bob".to_string(),
2902 age: 25,
2903 };
2904
2905 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2907 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2908
2909 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2910
2911 let name_value = keypaths[0].get_as::<String>(&user);
2913 let age_value = keypaths[1].get_as::<i32>(&user);
2914
2915 assert_eq!(name_value, Some(&"Bob".to_string()));
2916 assert_eq!(age_value, Some(&25));
2917 }
2918
2919 #[test]
2920 fn test_pkp_for_arc() {
2921 #[derive(Debug)]
2922 struct User {
2923 name: String,
2924 }
2925
2926 let user = Arc::new(User {
2927 name: "Charlie".to_string(),
2928 });
2929
2930 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2931 let name_pkp = PKp::new(name_kp);
2932
2933 let arc_pkp = name_pkp.for_arc();
2935
2936 assert_eq!(
2937 arc_pkp.get_as::<String>(&user),
2938 Some(&"Charlie".to_string())
2939 );
2940 }
2941
2942 #[test]
2943 fn test_pkp_for_option() {
2944 #[derive(Debug)]
2945 struct User {
2946 name: String,
2947 }
2948
2949 let some_user = Some(User {
2950 name: "Diana".to_string(),
2951 });
2952 let none_user: Option<User> = None;
2953
2954 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2955 let name_pkp = PKp::new(name_kp);
2956
2957 let opt_pkp = name_pkp.for_option();
2959
2960 assert_eq!(
2961 opt_pkp.get_as::<String>(&some_user),
2962 Some(&"Diana".to_string())
2963 );
2964 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2965 }
2966
2967 #[test]
2968 fn test_akp_basic() {
2969 #[derive(Debug)]
2970 struct User {
2971 name: String,
2972 age: i32,
2973 }
2974
2975 #[derive(Debug)]
2976 struct Product {
2977 title: String,
2978 price: f64,
2979 }
2980
2981 let user = User {
2982 name: "Eve".to_string(),
2983 age: 28,
2984 };
2985
2986 let product = Product {
2987 title: "Book".to_string(),
2988 price: 19.99,
2989 };
2990
2991 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2993 let user_name_akp = AKp::new(user_name_kp);
2994
2995 let product_title_kp = KpType::new(
2996 |p: &Product| Some(&p.title),
2997 |p: &mut Product| Some(&mut p.title),
2998 );
2999 let product_title_akp = AKp::new(product_title_kp);
3000
3001 assert_eq!(
3003 user_name_akp.get_as::<User, String>(&user),
3004 Some(Some(&"Eve".to_string()))
3005 );
3006 assert_eq!(
3007 product_title_akp.get_as::<Product, String>(&product),
3008 Some(Some(&"Book".to_string()))
3009 );
3010
3011 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
3013 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
3014
3015 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
3017 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
3018 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
3019 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
3020 }
3021
3022 #[test]
3023 fn test_akp_heterogeneous_collection() {
3024 #[derive(Debug)]
3025 struct User {
3026 name: String,
3027 }
3028
3029 #[derive(Debug)]
3030 struct Product {
3031 title: String,
3032 }
3033
3034 let user = User {
3035 name: "Frank".to_string(),
3036 };
3037 let product = Product {
3038 title: "Laptop".to_string(),
3039 };
3040
3041 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3043 let product_title_kp = KpType::new(
3044 |p: &Product| Some(&p.title),
3045 |p: &mut Product| Some(&mut p.title),
3046 );
3047
3048 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
3049
3050 let user_any: &dyn Any = &user;
3052 let product_any: &dyn Any = &product;
3053
3054 let user_value = keypaths[0].get(user_any);
3055 let product_value = keypaths[1].get(product_any);
3056
3057 assert!(user_value.is_some());
3058 assert!(product_value.is_some());
3059
3060 assert_eq!(
3062 user_value.and_then(|v| v.downcast_ref::<String>()),
3063 Some(&"Frank".to_string())
3064 );
3065 assert_eq!(
3066 product_value.and_then(|v| v.downcast_ref::<String>()),
3067 Some(&"Laptop".to_string())
3068 );
3069 }
3070
3071 #[test]
3072 fn test_akp_for_option() {
3073 #[derive(Debug)]
3074 struct User {
3075 name: String,
3076 }
3077
3078 let some_user = Some(User {
3079 name: "Grace".to_string(),
3080 });
3081 let none_user: Option<User> = None;
3082
3083 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3084 let name_akp = AKp::new(name_kp);
3085
3086 let opt_akp = name_akp.for_option::<User>();
3088
3089 assert_eq!(
3090 opt_akp.get_as::<Option<User>, String>(&some_user),
3091 Some(Some(&"Grace".to_string()))
3092 );
3093 assert_eq!(
3094 opt_akp.get_as::<Option<User>, String>(&none_user),
3095 Some(None)
3096 );
3097 }
3098
3099 #[test]
3100 fn test_akp_for_result() {
3101 #[derive(Debug)]
3102 struct User {
3103 name: String,
3104 }
3105
3106 let ok_user: Result<User, String> = Ok(User {
3107 name: "Henry".to_string(),
3108 });
3109 let err_user: Result<User, String> = Err("Not found".to_string());
3110
3111 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3112 let name_akp = AKp::new(name_kp);
3113
3114 let result_akp = name_akp.for_result::<User, String>();
3116
3117 assert_eq!(
3118 result_akp.get_as::<Result<User, String>, String>(&ok_user),
3119 Some(Some(&"Henry".to_string()))
3120 );
3121 assert_eq!(
3122 result_akp.get_as::<Result<User, String>, String>(&err_user),
3123 Some(None)
3124 );
3125 }
3126
3127 #[test]
3130 fn test_kp_map() {
3131 #[derive(Debug)]
3132 struct User {
3133 name: String,
3134 age: i32,
3135 }
3136
3137 let user = User {
3138 name: "Akash".to_string(),
3139 age: 30,
3140 };
3141
3142 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3144 let len_kp = name_kp.map(|name: &String| name.len());
3145
3146 assert_eq!(len_kp.get(&user), Some(5));
3147
3148 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3150 let double_age_kp = age_kp.map(|age: &i32| age * 2);
3151
3152 assert_eq!(double_age_kp.get(&user), Some(60));
3153
3154 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
3156 assert_eq!(is_adult_kp.get(&user), Some(true));
3157 }
3158
3159 #[test]
3160 fn test_kp_filter() {
3161 #[derive(Debug)]
3162 struct User {
3163 name: String,
3164 age: i32,
3165 }
3166
3167 let adult = User {
3168 name: "Akash".to_string(),
3169 age: 30,
3170 };
3171
3172 let minor = User {
3173 name: "Bob".to_string(),
3174 age: 15,
3175 };
3176
3177 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3178 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
3179
3180 assert_eq!(adult_age_kp.get(&adult), Some(&30));
3181 assert_eq!(adult_age_kp.get(&minor), None);
3182
3183 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3185 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
3186
3187 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
3188 assert_eq!(short_name_kp.get(&adult), None);
3189 }
3190
3191 #[test]
3192 fn test_kp_map_and_filter() {
3193 #[derive(Debug)]
3194 struct User {
3195 scores: Vec<i32>,
3196 }
3197
3198 let user = User {
3199 scores: vec![85, 92, 78, 95],
3200 };
3201
3202 let scores_kp = KpType::new(
3203 |u: &User| Some(&u.scores),
3204 |u: &mut User| Some(&mut u.scores),
3205 );
3206
3207 let avg_kp =
3209 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3210
3211 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
3213
3214 assert_eq!(high_avg_kp.get(&user), Some(87)); }
3216
3217 #[test]
3218 fn test_enum_kp_map() {
3219 let ok_result: Result<String, i32> = Ok("hello".to_string());
3220 let err_result: Result<String, i32> = Err(42);
3221
3222 let ok_kp = enum_ok::<String, i32>();
3223 let len_kp = ok_kp.map(|s: &String| s.len());
3224
3225 assert_eq!(len_kp.get(&ok_result), Some(5));
3226 assert_eq!(len_kp.get(&err_result), None);
3227
3228 let some_opt = Some(vec![1, 2, 3, 4, 5]);
3230 let none_opt: Option<Vec<i32>> = None;
3231
3232 let some_kp = enum_some::<Vec<i32>>();
3233 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
3234
3235 assert_eq!(count_kp.get(&some_opt), Some(5));
3236 assert_eq!(count_kp.get(&none_opt), None);
3237 }
3238
3239 #[test]
3240 fn test_enum_kp_filter() {
3241 let ok_result1: Result<i32, String> = Ok(42);
3242 let ok_result2: Result<i32, String> = Ok(-5);
3243 let err_result: Result<i32, String> = Err("error".to_string());
3244
3245 let ok_kp = enum_ok::<i32, String>();
3246 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
3247
3248 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
3249 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
3254 let short_str = Some("hi".to_string());
3255
3256 let some_kp = enum_some::<String>();
3257 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
3258
3259 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
3260 assert_eq!(long_kp.get(&short_str), None);
3261 }
3262
3263 #[test]
3264 fn test_pkp_filter() {
3265 #[derive(Debug)]
3266 struct User {
3267 name: String,
3268 age: i32,
3269 }
3270
3271 let adult = User {
3272 name: "Akash".to_string(),
3273 age: 30,
3274 };
3275
3276 let minor = User {
3277 name: "Bob".to_string(),
3278 age: 15,
3279 };
3280
3281 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3282 let age_pkp = PKp::new(age_kp);
3283
3284 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
3286
3287 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
3288 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
3289
3290 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3292 let name_pkp = PKp::new(name_kp);
3293 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
3294
3295 assert_eq!(
3296 short_name_pkp.get_as::<String>(&minor),
3297 Some(&"Bob".to_string())
3298 );
3299 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
3300 }
3301
3302 #[test]
3303 fn test_akp_filter() {
3304 #[derive(Debug)]
3305 struct User {
3306 age: i32,
3307 }
3308
3309 #[derive(Debug)]
3310 struct Product {
3311 price: f64,
3312 }
3313
3314 let adult = User { age: 30 };
3315 let minor = User { age: 15 };
3316 let expensive = Product { price: 99.99 };
3317 let cheap = Product { price: 5.0 };
3318
3319 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3321 let age_akp = AKp::new(age_kp);
3322 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
3323
3324 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
3325 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
3326
3327 let price_kp = KpType::new(
3329 |p: &Product| Some(&p.price),
3330 |p: &mut Product| Some(&mut p.price),
3331 );
3332 let price_akp = AKp::new(price_kp);
3333 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
3334
3335 assert_eq!(
3336 expensive_akp.get_as::<Product, f64>(&expensive),
3337 Some(Some(&99.99))
3338 );
3339 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
3340 }
3341
3342 #[test]
3345 fn test_kp_filter_map() {
3346 #[derive(Debug)]
3347 struct User {
3348 middle_name: Option<String>,
3349 }
3350
3351 let user_with = User {
3352 middle_name: Some("Marie".to_string()),
3353 };
3354 let user_without = User { middle_name: None };
3355
3356 let middle_kp = KpType::new(
3357 |u: &User| Some(&u.middle_name),
3358 |u: &mut User| Some(&mut u.middle_name),
3359 );
3360
3361 let first_char_kp = middle_kp
3362 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
3363
3364 assert_eq!(first_char_kp.get(&user_with), Some('M'));
3365 assert_eq!(first_char_kp.get(&user_without), None);
3366 }
3367
3368 #[test]
3369 fn test_kp_inspect() {
3370 #[derive(Debug)]
3371 struct User {
3372 name: String,
3373 }
3374
3375 let user = User {
3376 name: "Akash".to_string(),
3377 };
3378
3379 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3383
3384 let result = name_kp.get(&user);
3387 assert_eq!(result, Some(&"Akash".to_string()));
3388
3389 }
3392
3393 #[test]
3394 fn test_kp_fold_value() {
3395 #[derive(Debug)]
3396 struct User {
3397 scores: Vec<i32>,
3398 }
3399
3400 let user = User {
3401 scores: vec![85, 92, 78, 95],
3402 };
3403
3404 let scores_kp = KpType::new(
3405 |u: &User| Some(&u.scores),
3406 |u: &mut User| Some(&mut u.scores),
3407 );
3408
3409 let sum_fn =
3411 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
3412
3413 assert_eq!(sum_fn(&user), 350);
3414 }
3415
3416 #[test]
3417 fn test_kp_any_all() {
3418 #[derive(Debug)]
3419 struct User {
3420 scores: Vec<i32>,
3421 }
3422
3423 let user_high = User {
3424 scores: vec![85, 92, 88],
3425 };
3426 let user_mixed = User {
3427 scores: vec![65, 92, 78],
3428 };
3429
3430 let scores_kp = KpType::new(
3431 |u: &User| Some(&u.scores),
3432 |u: &mut User| Some(&mut u.scores),
3433 );
3434
3435 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
3437 assert!(has_high_fn(&user_high));
3438 assert!(has_high_fn(&user_mixed));
3439
3440 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
3442 assert!(all_passing_fn(&user_high));
3443 assert!(!all_passing_fn(&user_mixed));
3444 }
3445
3446 #[test]
3447 fn test_kp_count_items() {
3448 #[derive(Debug)]
3449 struct User {
3450 tags: Vec<String>,
3451 }
3452
3453 let user = User {
3454 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
3455 };
3456
3457 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3458 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
3459
3460 assert_eq!(count_fn(&user), Some(3));
3461 }
3462
3463 #[test]
3464 fn test_kp_find_in() {
3465 #[derive(Debug)]
3466 struct User {
3467 scores: Vec<i32>,
3468 }
3469
3470 let user = User {
3471 scores: vec![85, 92, 78, 95, 88],
3472 };
3473
3474 let scores_kp = KpType::new(
3475 |u: &User| Some(&u.scores),
3476 |u: &mut User| Some(&mut u.scores),
3477 );
3478
3479 let first_high_fn =
3481 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3482
3483 assert_eq!(first_high_fn(&user), Some(92));
3484
3485 let perfect_fn =
3487 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3488
3489 assert_eq!(perfect_fn(&user), None);
3490 }
3491
3492 #[test]
3493 fn test_kp_take_skip() {
3494 #[derive(Debug)]
3495 struct User {
3496 tags: Vec<String>,
3497 }
3498
3499 let user = User {
3500 tags: vec![
3501 "a".to_string(),
3502 "b".to_string(),
3503 "c".to_string(),
3504 "d".to_string(),
3505 ],
3506 };
3507
3508 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3509
3510 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3512 tags.iter().take(n).cloned().collect::<Vec<_>>()
3513 });
3514
3515 let taken = take_fn(&user).unwrap();
3516 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3517
3518 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3520 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3521 });
3522
3523 let skipped = skip_fn(&user).unwrap();
3524 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3525 }
3526
3527 #[test]
3528 fn test_kp_partition() {
3529 #[derive(Debug)]
3530 struct User {
3531 scores: Vec<i32>,
3532 }
3533
3534 let user = User {
3535 scores: vec![85, 92, 65, 95, 72, 58],
3536 };
3537
3538 let scores_kp = KpType::new(
3539 |u: &User| Some(&u.scores),
3540 |u: &mut User| Some(&mut u.scores),
3541 );
3542
3543 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3544 scores.iter().copied().partition(|&s| s >= 70)
3545 });
3546
3547 let (passing, failing) = partition_fn(&user).unwrap();
3548 assert_eq!(passing, vec![85, 92, 95, 72]);
3549 assert_eq!(failing, vec![65, 58]);
3550 }
3551
3552 #[test]
3553 fn test_kp_min_max() {
3554 #[derive(Debug)]
3555 struct User {
3556 scores: Vec<i32>,
3557 }
3558
3559 let user = User {
3560 scores: vec![85, 92, 78, 95, 88],
3561 };
3562
3563 let scores_kp = KpType::new(
3564 |u: &User| Some(&u.scores),
3565 |u: &mut User| Some(&mut u.scores),
3566 );
3567
3568 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3570 assert_eq!(min_fn(&user), Some(78));
3571
3572 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3574 assert_eq!(max_fn(&user), Some(95));
3575 }
3576
3577 #[test]
3578 fn test_kp_sum() {
3579 #[derive(Debug)]
3580 struct User {
3581 scores: Vec<i32>,
3582 }
3583
3584 let user = User {
3585 scores: vec![85, 92, 78],
3586 };
3587
3588 let scores_kp = KpType::new(
3589 |u: &User| Some(&u.scores),
3590 |u: &mut User| Some(&mut u.scores),
3591 );
3592
3593 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3594 assert_eq!(sum_fn(&user), Some(255));
3595
3596 let avg_fn =
3598 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3599 assert_eq!(avg_fn.get(&user), Some(85));
3600 }
3601
3602 #[test]
3603 fn test_kp_chain() {
3604 #[derive(Debug)]
3605 struct User {
3606 profile: Profile,
3607 }
3608
3609 #[derive(Debug)]
3610 struct Profile {
3611 settings: Settings,
3612 }
3613
3614 #[derive(Debug)]
3615 struct Settings {
3616 theme: String,
3617 }
3618
3619 let user = User {
3620 profile: Profile {
3621 settings: Settings {
3622 theme: "dark".to_string(),
3623 },
3624 },
3625 };
3626
3627 let profile_kp = KpType::new(
3628 |u: &User| Some(&u.profile),
3629 |u: &mut User| Some(&mut u.profile),
3630 );
3631 let settings_kp = KpType::new(
3632 |p: &Profile| Some(&p.settings),
3633 |p: &mut Profile| Some(&mut p.settings),
3634 );
3635 let theme_kp = KpType::new(
3636 |s: &Settings| Some(&s.theme),
3637 |s: &mut Settings| Some(&mut s.theme),
3638 );
3639
3640 let profile_settings = profile_kp.then(settings_kp);
3642 let theme_path = profile_settings.then(theme_kp);
3643 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3644 }
3645
3646 #[test]
3647 fn test_kp_zip() {
3648 #[derive(Debug)]
3649 struct User {
3650 name: String,
3651 age: i32,
3652 }
3653
3654 let user = User {
3655 name: "Akash".to_string(),
3656 age: 30,
3657 };
3658
3659 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3660 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3661
3662 let zipped_fn = zip_kps(&name_kp, &age_kp);
3663 let result = zipped_fn(&user);
3664
3665 assert_eq!(result, Some((&"Akash".to_string(), &30)));
3666 }
3667
3668 #[test]
3669 fn test_kp_complex_pipeline() {
3670 #[derive(Debug)]
3671 struct User {
3672 transactions: Vec<Transaction>,
3673 }
3674
3675 #[derive(Debug)]
3676 struct Transaction {
3677 amount: f64,
3678 category: String,
3679 }
3680
3681 let user = User {
3682 transactions: vec![
3683 Transaction {
3684 amount: 50.0,
3685 category: "food".to_string(),
3686 },
3687 Transaction {
3688 amount: 100.0,
3689 category: "transport".to_string(),
3690 },
3691 Transaction {
3692 amount: 25.0,
3693 category: "food".to_string(),
3694 },
3695 Transaction {
3696 amount: 200.0,
3697 category: "shopping".to_string(),
3698 },
3699 ],
3700 };
3701
3702 let txns_kp = KpType::new(
3703 |u: &User| Some(&u.transactions),
3704 |u: &mut User| Some(&mut u.transactions),
3705 );
3706
3707 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3709 txns.iter()
3710 .filter(|t| t.category == "food")
3711 .map(|t| t.amount)
3712 .sum::<f64>()
3713 });
3714
3715 assert_eq!(food_total.get(&user), Some(75.0));
3716
3717 let has_large =
3719 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3720
3721 assert!(has_large(&user));
3722
3723 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3725 assert_eq!(count(&user), Some(4));
3726 }
3727
3728 #[test]
3732 fn test_no_clone_required_for_root() {
3733 use std::sync::Arc;
3734 use std::sync::atomic::{AtomicUsize, Ordering};
3735
3736 struct NonCloneableRoot {
3739 data: Arc<AtomicUsize>,
3740 cached_value: usize,
3741 }
3742
3743 impl NonCloneableRoot {
3744 fn new() -> Self {
3745 Self {
3746 data: Arc::new(AtomicUsize::new(42)),
3747 cached_value: 42,
3748 }
3749 }
3750
3751 fn increment(&mut self) {
3752 self.data.fetch_add(1, Ordering::SeqCst);
3753 self.cached_value = self.data.load(Ordering::SeqCst);
3754 }
3755
3756 fn get_value(&self) -> &usize {
3757 &self.cached_value
3758 }
3759
3760 fn get_value_mut(&mut self) -> &mut usize {
3761 &mut self.cached_value
3762 }
3763 }
3764
3765 let mut root = NonCloneableRoot::new();
3766
3767 let data_kp = KpType::new(
3769 |r: &NonCloneableRoot| Some(r.get_value()),
3770 |r: &mut NonCloneableRoot| {
3771 r.increment();
3772 Some(r.get_value_mut())
3773 },
3774 );
3775
3776 assert_eq!(data_kp.get(&root), Some(&42));
3778
3779 {
3780 let doubled = data_kp.map(|val: &usize| val * 2);
3782 assert_eq!(doubled.get(&root), Some(84));
3783
3784 let filtered = data_kp.filter(|val: &usize| *val > 0);
3786 assert_eq!(filtered.get(&root), Some(&42));
3787 } let value_ref = data_kp.get_mut(&mut root);
3791 assert!(value_ref.is_some());
3792 }
3793
3794 #[test]
3795 fn test_no_clone_required_for_value() {
3796 use std::sync::Arc;
3797 use std::sync::atomic::{AtomicUsize, Ordering};
3798
3799 struct NonCloneableValue {
3801 counter: Arc<AtomicUsize>,
3802 }
3803
3804 impl NonCloneableValue {
3805 fn new(val: usize) -> Self {
3806 Self {
3807 counter: Arc::new(AtomicUsize::new(val)),
3808 }
3809 }
3810
3811 fn get(&self) -> usize {
3812 self.counter.load(Ordering::SeqCst)
3813 }
3814 }
3815
3816 struct Root {
3817 value: NonCloneableValue,
3818 }
3819
3820 let root = Root {
3821 value: NonCloneableValue::new(100),
3822 };
3823
3824 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3826
3827 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3829 assert_eq!(counter_kp.get(&root), Some(100));
3830
3831 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3833 assert!(filtered.get(&root).is_some());
3834 }
3835
3836 #[test]
3837 fn test_static_does_not_leak_memory() {
3838 use std::sync::Arc;
3839 use std::sync::atomic::{AtomicUsize, Ordering};
3840
3841 static CREATED: AtomicUsize = AtomicUsize::new(0);
3843 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3844
3845 struct Tracked {
3846 id: usize,
3847 }
3848
3849 impl Tracked {
3850 fn new() -> Self {
3851 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3852 Self { id }
3853 }
3854 }
3855
3856 impl Drop for Tracked {
3857 fn drop(&mut self) {
3858 DROPPED.fetch_add(1, Ordering::SeqCst);
3859 }
3860 }
3861
3862 struct Root {
3863 data: Tracked,
3864 }
3865
3866 CREATED.store(0, Ordering::SeqCst);
3868 DROPPED.store(0, Ordering::SeqCst);
3869
3870 {
3871 let root = Root {
3872 data: Tracked::new(),
3873 };
3874
3875 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3876
3877 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3879 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3880 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3881
3882 assert_eq!(mapped1.get(&root), Some(0));
3883 assert_eq!(mapped2.get(&root), Some(1));
3884 assert_eq!(mapped3.get(&root), Some(2));
3885
3886 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3888 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3889 }
3890
3891 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3893 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3894
3895 }
3897
3898 #[test]
3899 fn test_references_not_cloned() {
3900 use std::sync::Arc;
3901
3902 struct ExpensiveData {
3904 large_vec: Vec<u8>,
3905 }
3906
3907 impl ExpensiveData {
3908 fn new(size: usize) -> Self {
3909 Self {
3910 large_vec: vec![0u8; size],
3911 }
3912 }
3913
3914 fn size(&self) -> usize {
3915 self.large_vec.len()
3916 }
3917 }
3918
3919 struct Root {
3920 expensive: ExpensiveData,
3921 }
3922
3923 let root = Root {
3924 expensive: ExpensiveData::new(1_000_000), };
3926
3927 let expensive_kp = KpType::new(
3928 |r: &Root| Some(&r.expensive),
3929 |r: &mut Root| Some(&mut r.expensive),
3930 );
3931
3932 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3934 assert_eq!(size_kp.get(&root), Some(1_000_000));
3935
3936 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3938 assert!(large_filter.get(&root).is_some());
3939
3940 }
3942
3943 #[test]
3944 fn test_hof_with_arc_no_extra_clones() {
3945 use std::sync::Arc;
3946
3947 #[derive(Debug)]
3948 struct SharedData {
3949 value: String,
3950 }
3951
3952 struct Root {
3953 shared: Arc<SharedData>,
3954 }
3955
3956 let shared = Arc::new(SharedData {
3957 value: "shared".to_string(),
3958 });
3959
3960 assert_eq!(Arc::strong_count(&shared), 1);
3962
3963 {
3964 let root = Root {
3965 shared: Arc::clone(&shared),
3966 };
3967
3968 assert_eq!(Arc::strong_count(&shared), 2);
3970
3971 let shared_kp = KpType::new(
3972 |r: &Root| Some(&r.shared),
3973 |r: &mut Root| Some(&mut r.shared),
3974 );
3975
3976 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3978
3979 assert_eq!(value_kp.get(&root), Some(6));
3981 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3985 assert!(filtered.get(&root).is_some());
3986 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3991
3992 #[test]
3993 fn test_closure_captures_not_root_values() {
3994 use std::sync::Arc;
3995 use std::sync::atomic::{AtomicUsize, Ordering};
3996
3997 let call_count = Arc::new(AtomicUsize::new(0));
3999 let call_count_clone = Arc::clone(&call_count);
4000
4001 struct Root {
4002 value: i32,
4003 }
4004
4005 let root = Root { value: 42 };
4006
4007 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4008
4009 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
4012 call_count_clone.fetch_add(1, Ordering::SeqCst);
4013 v * 2
4014 });
4015
4016 assert_eq!(doubled(&root), 84);
4018 assert_eq!(doubled(&root), 84);
4019 assert_eq!(doubled(&root), 84);
4020
4021 assert_eq!(call_count.load(Ordering::SeqCst), 3);
4023
4024 }
4026
4027 #[test]
4028 fn test_static_with_borrowed_data() {
4029 struct Root {
4033 data: String,
4034 }
4035
4036 {
4037 let root = Root {
4038 data: "temporary".to_string(),
4039 };
4040
4041 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4042
4043 let len_kp = data_kp.map(|s: &String| s.len());
4045 assert_eq!(len_kp.get(&root), Some(9));
4046
4047 } }
4052
4053 #[test]
4054 fn test_multiple_hof_operations_no_accumulation() {
4055 use std::sync::Arc;
4056 use std::sync::atomic::{AtomicUsize, Ordering};
4057
4058 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
4059
4060 struct Tracked {
4061 id: usize,
4062 }
4063
4064 impl Drop for Tracked {
4065 fn drop(&mut self) {
4066 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4067 }
4068 }
4069
4070 struct Root {
4071 values: Vec<Tracked>,
4072 }
4073
4074 DROP_COUNT.store(0, Ordering::SeqCst);
4075
4076 {
4077 let root = Root {
4078 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
4079 };
4080
4081 let values_kp = KpType::new(
4082 |r: &Root| Some(&r.values),
4083 |r: &mut Root| Some(&mut r.values),
4084 );
4085
4086 let count = values_kp.count_items(|v| v.len());
4088 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
4089 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
4090 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
4091
4092 assert_eq!(count(&root), Some(3));
4093 assert_eq!(sum(&root), Some(6));
4094 assert!(has_2(&root));
4095 assert!(all_positive(&root));
4096
4097 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4099 }
4100
4101 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
4103 }
4104
4105 #[test]
4106 fn test_copy_bound_only_for_function_not_data() {
4107 #[derive(Debug)]
4111 struct NonCopyData {
4112 value: String,
4113 }
4114
4115 struct Root {
4116 data: NonCopyData,
4117 }
4118
4119 let root = Root {
4120 data: NonCopyData {
4121 value: "test".to_string(),
4122 },
4123 };
4124
4125 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4126
4127 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
4130 assert_eq!(len_kp.get(&root), Some(4));
4131
4132 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
4134 assert!(filtered.get(&root).is_some());
4135 }
4136
4137 #[test]
4138 fn test_no_memory_leak_with_cyclic_references() {
4139 use std::sync::atomic::{AtomicUsize, Ordering};
4140 use std::sync::{Arc, Weak};
4141
4142 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
4143
4144 struct Node {
4145 id: usize,
4146 parent: Option<Weak<Node>>,
4147 }
4148
4149 impl Drop for Node {
4150 fn drop(&mut self) {
4151 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4152 }
4153 }
4154
4155 struct Root {
4156 node: Arc<Node>,
4157 }
4158
4159 DROP_COUNT.store(0, Ordering::SeqCst);
4160
4161 {
4162 let root = Root {
4163 node: Arc::new(Node {
4164 id: 1,
4165 parent: None,
4166 }),
4167 };
4168
4169 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
4170
4171 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
4173 assert_eq!(id_kp.get(&root), Some(1));
4174
4175 assert_eq!(Arc::strong_count(&root.node), 1);
4177
4178 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4180 }
4181
4182 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
4184 }
4185
4186 #[test]
4187 fn test_hof_operations_are_zero_cost_abstractions() {
4188 struct Root {
4192 value: i32,
4193 }
4194
4195 let root = Root { value: 10 };
4196
4197 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4198
4199 let direct_result = value_kp.get(&root).map(|v| v * 2);
4201 assert_eq!(direct_result, Some(20));
4202
4203 let mapped_kp = value_kp.map(|v: &i32| v * 2);
4205 let hof_result = mapped_kp.get(&root);
4206 assert_eq!(hof_result, Some(20));
4207
4208 assert_eq!(direct_result, hof_result);
4210 }
4211
4212 #[test]
4213 fn test_complex_closure_captures_allowed() {
4214 use std::sync::Arc;
4215
4216 struct Root {
4218 scores: Vec<i32>,
4219 }
4220
4221 let root = Root {
4222 scores: vec![85, 92, 78, 95, 88],
4223 };
4224
4225 let scores_kp = KpType::new(
4226 |r: &Root| Some(&r.scores),
4227 |r: &mut Root| Some(&mut r.scores),
4228 );
4229
4230 let threshold = 90;
4232 let multiplier = Arc::new(2);
4233
4234 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
4236 let high: i32 = scores
4237 .iter()
4238 .filter(|&&s| s >= threshold)
4239 .map(|&s| s * *multiplier)
4240 .sum();
4241 acc + high
4242 });
4243
4244 assert_eq!(high_scores_doubled(&root), 374);
4246 }
4247
4248 #[test]
4252 fn test_pkp_filter_by_value_type() {
4253 use std::any::TypeId;
4254
4255 #[derive(Debug)]
4256 struct User {
4257 name: String,
4258 age: i32,
4259 score: f64,
4260 active: bool,
4261 }
4262
4263 let user = User {
4264 name: "Akash".to_string(),
4265 age: 30,
4266 score: 95.5,
4267 active: true,
4268 };
4269
4270 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4272 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4273 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
4274 let active_kp = KpType::new(
4275 |u: &User| Some(&u.active),
4276 |u: &mut User| Some(&mut u.active),
4277 );
4278
4279 let all_keypaths: Vec<PKp<User>> = vec![
4281 PKp::new(name_kp),
4282 PKp::new(age_kp),
4283 PKp::new(score_kp),
4284 PKp::new(active_kp),
4285 ];
4286
4287 let string_kps: Vec<_> = all_keypaths
4289 .iter()
4290 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
4291 .collect();
4292
4293 assert_eq!(string_kps.len(), 1);
4294 assert_eq!(
4295 string_kps[0].get_as::<String>(&user),
4296 Some(&"Akash".to_string())
4297 );
4298
4299 let i32_kps: Vec<_> = all_keypaths
4301 .iter()
4302 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
4303 .collect();
4304
4305 assert_eq!(i32_kps.len(), 1);
4306 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
4307
4308 let f64_kps: Vec<_> = all_keypaths
4310 .iter()
4311 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
4312 .collect();
4313
4314 assert_eq!(f64_kps.len(), 1);
4315 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
4316
4317 let bool_kps: Vec<_> = all_keypaths
4319 .iter()
4320 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
4321 .collect();
4322
4323 assert_eq!(bool_kps.len(), 1);
4324 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
4325 }
4326
4327 #[test]
4328 fn test_pkp_filter_by_struct_type() {
4329 use std::any::TypeId;
4330
4331 #[derive(Debug, PartialEq)]
4332 struct Address {
4333 street: String,
4334 city: String,
4335 }
4336
4337 #[derive(Debug)]
4338 struct User {
4339 name: String,
4340 age: i32,
4341 address: Address,
4342 }
4343
4344 let user = User {
4345 name: "Bob".to_string(),
4346 age: 25,
4347 address: Address {
4348 street: "123 Main St".to_string(),
4349 city: "NYC".to_string(),
4350 },
4351 };
4352
4353 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4355 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4356 let address_kp = KpType::new(
4357 |u: &User| Some(&u.address),
4358 |u: &mut User| Some(&mut u.address),
4359 );
4360
4361 let all_keypaths: Vec<PKp<User>> =
4362 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
4363
4364 let struct_kps: Vec<_> = all_keypaths
4366 .iter()
4367 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
4368 .collect();
4369
4370 assert_eq!(struct_kps.len(), 1);
4371 assert_eq!(
4372 struct_kps[0].get_as::<Address>(&user),
4373 Some(&Address {
4374 street: "123 Main St".to_string(),
4375 city: "NYC".to_string(),
4376 })
4377 );
4378
4379 let primitive_kps: Vec<_> = all_keypaths
4381 .iter()
4382 .filter(|pkp| {
4383 pkp.value_type_id() == TypeId::of::<String>()
4384 || pkp.value_type_id() == TypeId::of::<i32>()
4385 })
4386 .collect();
4387
4388 assert_eq!(primitive_kps.len(), 2);
4389 }
4390
4391 #[test]
4392 fn test_pkp_filter_by_arc_type() {
4393 use std::any::TypeId;
4394 use std::sync::Arc;
4395
4396 #[derive(Debug)]
4397 struct User {
4398 name: String,
4399 shared_data: Arc<String>,
4400 shared_number: Arc<i32>,
4401 }
4402
4403 let user = User {
4404 name: "Charlie".to_string(),
4405 shared_data: Arc::new("shared".to_string()),
4406 shared_number: Arc::new(42),
4407 };
4408
4409 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4411 let shared_data_kp = KpType::new(
4412 |u: &User| Some(&u.shared_data),
4413 |u: &mut User| Some(&mut u.shared_data),
4414 );
4415 let shared_number_kp = KpType::new(
4416 |u: &User| Some(&u.shared_number),
4417 |u: &mut User| Some(&mut u.shared_number),
4418 );
4419
4420 let all_keypaths: Vec<PKp<User>> = vec![
4421 PKp::new(name_kp),
4422 PKp::new(shared_data_kp),
4423 PKp::new(shared_number_kp),
4424 ];
4425
4426 let arc_string_kps: Vec<_> = all_keypaths
4428 .iter()
4429 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
4430 .collect();
4431
4432 assert_eq!(arc_string_kps.len(), 1);
4433 assert_eq!(
4434 arc_string_kps[0]
4435 .get_as::<Arc<String>>(&user)
4436 .map(|arc| arc.as_str()),
4437 Some("shared")
4438 );
4439
4440 let arc_i32_kps: Vec<_> = all_keypaths
4442 .iter()
4443 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
4444 .collect();
4445
4446 assert_eq!(arc_i32_kps.len(), 1);
4447 assert_eq!(
4448 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
4449 Some(42)
4450 );
4451
4452 let all_arc_kps: Vec<_> = all_keypaths
4454 .iter()
4455 .filter(|pkp| {
4456 pkp.value_type_id() == TypeId::of::<Arc<String>>()
4457 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
4458 })
4459 .collect();
4460
4461 assert_eq!(all_arc_kps.len(), 2);
4462 }
4463
4464 #[test]
4465 fn test_pkp_filter_by_box_type() {
4466 use std::any::TypeId;
4467
4468 #[derive(Debug)]
4469 struct User {
4470 name: String,
4471 boxed_value: Box<i32>,
4472 boxed_string: Box<String>,
4473 }
4474
4475 let user = User {
4476 name: "Diana".to_string(),
4477 boxed_value: Box::new(100),
4478 boxed_string: Box::new("boxed".to_string()),
4479 };
4480
4481 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4483 let boxed_value_kp = KpType::new(
4484 |u: &User| Some(&u.boxed_value),
4485 |u: &mut User| Some(&mut u.boxed_value),
4486 );
4487 let boxed_string_kp = KpType::new(
4488 |u: &User| Some(&u.boxed_string),
4489 |u: &mut User| Some(&mut u.boxed_string),
4490 );
4491
4492 let all_keypaths: Vec<PKp<User>> = vec![
4493 PKp::new(name_kp),
4494 PKp::new(boxed_value_kp),
4495 PKp::new(boxed_string_kp),
4496 ];
4497
4498 let box_i32_kps: Vec<_> = all_keypaths
4500 .iter()
4501 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4502 .collect();
4503
4504 assert_eq!(box_i32_kps.len(), 1);
4505 assert_eq!(
4506 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4507 Some(100)
4508 );
4509
4510 let box_string_kps: Vec<_> = all_keypaths
4512 .iter()
4513 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4514 .collect();
4515
4516 assert_eq!(box_string_kps.len(), 1);
4517 assert_eq!(
4518 box_string_kps[0]
4519 .get_as::<Box<String>>(&user)
4520 .map(|b| b.as_str()),
4521 Some("boxed")
4522 );
4523 }
4524
4525 #[test]
4526 fn test_akp_filter_by_root_and_value_type() {
4527 use std::any::TypeId;
4528
4529 #[derive(Debug)]
4530 struct User {
4531 name: String,
4532 age: i32,
4533 }
4534
4535 #[derive(Debug)]
4536 struct Product {
4537 title: String,
4538 price: f64,
4539 }
4540
4541 let user = User {
4542 name: "Eve".to_string(),
4543 age: 28,
4544 };
4545
4546 let product = Product {
4547 title: "Book".to_string(),
4548 price: 19.99,
4549 };
4550
4551 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4553 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4554 let product_title_kp = KpType::new(
4555 |p: &Product| Some(&p.title),
4556 |p: &mut Product| Some(&mut p.title),
4557 );
4558 let product_price_kp = KpType::new(
4559 |p: &Product| Some(&p.price),
4560 |p: &mut Product| Some(&mut p.price),
4561 );
4562
4563 let all_keypaths: Vec<AKp> = vec![
4564 AKp::new(user_name_kp),
4565 AKp::new(user_age_kp),
4566 AKp::new(product_title_kp),
4567 AKp::new(product_price_kp),
4568 ];
4569
4570 let user_kps: Vec<_> = all_keypaths
4572 .iter()
4573 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4574 .collect();
4575
4576 assert_eq!(user_kps.len(), 2);
4577
4578 let product_kps: Vec<_> = all_keypaths
4580 .iter()
4581 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4582 .collect();
4583
4584 assert_eq!(product_kps.len(), 2);
4585
4586 let string_value_kps: Vec<_> = all_keypaths
4588 .iter()
4589 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4590 .collect();
4591
4592 assert_eq!(string_value_kps.len(), 2);
4593
4594 let user_string_kps: Vec<_> = all_keypaths
4596 .iter()
4597 .filter(|akp| {
4598 akp.root_type_id() == TypeId::of::<User>()
4599 && akp.value_type_id() == TypeId::of::<String>()
4600 })
4601 .collect();
4602
4603 assert_eq!(user_string_kps.len(), 1);
4604 assert_eq!(
4605 user_string_kps[0].get_as::<User, String>(&user),
4606 Some(Some(&"Eve".to_string()))
4607 );
4608
4609 let product_f64_kps: Vec<_> = all_keypaths
4611 .iter()
4612 .filter(|akp| {
4613 akp.root_type_id() == TypeId::of::<Product>()
4614 && akp.value_type_id() == TypeId::of::<f64>()
4615 })
4616 .collect();
4617
4618 assert_eq!(product_f64_kps.len(), 1);
4619 assert_eq!(
4620 product_f64_kps[0].get_as::<Product, f64>(&product),
4621 Some(Some(&19.99))
4622 );
4623 }
4624
4625 #[test]
4626 fn test_akp_filter_by_arc_root_type() {
4627 use std::any::TypeId;
4628 use std::sync::Arc;
4629
4630 #[derive(Debug)]
4631 struct User {
4632 name: String,
4633 }
4634
4635 #[derive(Debug)]
4636 struct Product {
4637 title: String,
4638 }
4639
4640 let user = User {
4641 name: "Frank".to_string(),
4642 };
4643 let product = Product {
4644 title: "Laptop".to_string(),
4645 };
4646
4647 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4649 let product_title_kp = KpType::new(
4650 |p: &Product| Some(&p.title),
4651 |p: &mut Product| Some(&mut p.title),
4652 );
4653
4654 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4656 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4657
4658 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4659
4660 let arc_user_kps: Vec<_> = all_keypaths
4662 .iter()
4663 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4664 .collect();
4665
4666 assert_eq!(arc_user_kps.len(), 1);
4667
4668 let arc_user = Arc::new(user);
4670 assert_eq!(
4671 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4672 Some(Some(&"Frank".to_string()))
4673 );
4674
4675 let arc_product_kps: Vec<_> = all_keypaths
4677 .iter()
4678 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4679 .collect();
4680
4681 assert_eq!(arc_product_kps.len(), 1);
4682
4683 let arc_product = Arc::new(product);
4685 assert_eq!(
4686 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4687 Some(Some(&"Laptop".to_string()))
4688 );
4689 }
4690
4691 #[test]
4692 fn test_akp_filter_by_box_root_type() {
4693 use std::any::TypeId;
4694
4695 #[derive(Debug)]
4696 struct Config {
4697 setting: String,
4698 }
4699
4700 let config = Config {
4701 setting: "enabled".to_string(),
4702 };
4703
4704 let config_kp1 = KpType::new(
4706 |c: &Config| Some(&c.setting),
4707 |c: &mut Config| Some(&mut c.setting),
4708 );
4709 let config_kp2 = KpType::new(
4710 |c: &Config| Some(&c.setting),
4711 |c: &mut Config| Some(&mut c.setting),
4712 );
4713
4714 let regular_akp = AKp::new(config_kp1);
4716 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4717
4718 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4719
4720 let config_kps: Vec<_> = all_keypaths
4722 .iter()
4723 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4724 .collect();
4725
4726 assert_eq!(config_kps.len(), 1);
4727 assert_eq!(
4728 config_kps[0].get_as::<Config, String>(&config),
4729 Some(Some(&"enabled".to_string()))
4730 );
4731
4732 let box_config_kps: Vec<_> = all_keypaths
4734 .iter()
4735 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4736 .collect();
4737
4738 assert_eq!(box_config_kps.len(), 1);
4739
4740 let box_config = Box::new(Config {
4742 setting: "enabled".to_string(),
4743 });
4744 assert_eq!(
4745 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4746 Some(Some(&"enabled".to_string()))
4747 );
4748 }
4749
4750 #[test]
4751 fn test_mixed_collection_type_filtering() {
4752 use std::any::TypeId;
4753 use std::sync::Arc;
4754
4755 #[derive(Debug)]
4756 struct User {
4757 name: String,
4758 email: String,
4759 }
4760
4761 #[derive(Debug)]
4762 struct Product {
4763 title: String,
4764 sku: String,
4765 }
4766
4767 let user = User {
4768 name: "Grace".to_string(),
4769 email: "grace@example.com".to_string(),
4770 };
4771
4772 let product = Product {
4773 title: "Widget".to_string(),
4774 sku: "WID-001".to_string(),
4775 };
4776
4777 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4779 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4780 let user_email_kp1 =
4781 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4782 let user_email_kp2 =
4783 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4784 let product_title_kp = KpType::new(
4785 |p: &Product| Some(&p.title),
4786 |p: &mut Product| Some(&mut p.title),
4787 );
4788 let product_sku_kp = KpType::new(
4789 |p: &Product| Some(&p.sku),
4790 |p: &mut Product| Some(&mut p.sku),
4791 );
4792
4793 let all_keypaths: Vec<AKp> = vec![
4794 AKp::new(user_name_kp1),
4795 AKp::new(user_email_kp1),
4796 AKp::new(product_title_kp),
4797 AKp::new(product_sku_kp),
4798 AKp::new(user_name_kp2).for_arc::<User>(),
4799 AKp::new(user_email_kp2).for_box::<User>(),
4800 ];
4801
4802 let string_value_kps: Vec<_> = all_keypaths
4804 .iter()
4805 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4806 .collect();
4807
4808 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4812 .iter()
4813 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4814 .collect();
4815
4816 assert_eq!(user_root_kps.len(), 2);
4817
4818 let arc_user_kps: Vec<_> = all_keypaths
4820 .iter()
4821 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4822 .collect();
4823
4824 assert_eq!(arc_user_kps.len(), 1);
4825
4826 let box_user_kps: Vec<_> = all_keypaths
4828 .iter()
4829 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4830 .collect();
4831
4832 assert_eq!(box_user_kps.len(), 1);
4833
4834 let product_kps: Vec<_> = all_keypaths
4836 .iter()
4837 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4838 .collect();
4839
4840 assert_eq!(product_kps.len(), 2);
4841
4842 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4844 assert!(user_value.is_some());
4845 assert!(user_value.unwrap().is_some());
4846 }
4847
4848 #[test]
4853 fn test_kp_with_pin() {
4854 use std::pin::Pin;
4855
4856 #[derive(Debug)]
4860 struct SelfReferential {
4861 value: String,
4862 ptr_to_value: *const String, }
4864
4865 impl SelfReferential {
4866 fn new(s: String) -> Self {
4867 let mut sr = Self {
4868 value: s,
4869 ptr_to_value: std::ptr::null(),
4870 };
4871 sr.ptr_to_value = &sr.value as *const String;
4873 sr
4874 }
4875
4876 fn get_value(&self) -> &str {
4877 &self.value
4878 }
4879 }
4880
4881 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4883 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4884
4885 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4887 |p: &Pin<Box<SelfReferential>>| {
4888 Some(&p.as_ref().get_ref().value)
4890 },
4891 |p: &mut Pin<Box<SelfReferential>>| {
4892 unsafe {
4895 let sr = Pin::get_unchecked_mut(p.as_mut());
4896 Some(&mut sr.value)
4897 }
4898 },
4899 );
4900
4901 let result = kp.get(&pinned);
4903 assert_eq!(result, Some(&"pinned_data".to_string()));
4904
4905 assert_eq!(pinned.get_value(), "pinned_data");
4907 }
4908
4909 #[test]
4910 fn test_kp_with_pin_arc() {
4911 use std::pin::Pin;
4912 use std::sync::Arc;
4913
4914 struct AsyncState {
4915 status: String,
4916 data: Vec<i32>,
4917 }
4918
4919 let state = AsyncState {
4921 status: "ready".to_string(),
4922 data: vec![1, 2, 3, 4, 5],
4923 };
4924
4925 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4926
4927 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4929 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4930 |_: &mut Pin<Arc<AsyncState>>| {
4931 None::<&mut String>
4933 },
4934 );
4935
4936 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4938 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4939 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4940 );
4941
4942 let status = status_kp.get(&pinned_arc);
4943 assert_eq!(status, Some(&"ready".to_string()));
4944
4945 let data = data_kp.get(&pinned_arc);
4946 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4947 }
4948
4949 #[test]
4950 fn test_kp_with_maybe_uninit() {
4951 use std::mem::MaybeUninit;
4952
4953 struct Config {
4957 name: MaybeUninit<String>,
4958 value: MaybeUninit<i32>,
4959 initialized: bool,
4960 }
4961
4962 impl Config {
4963 fn new_uninit() -> Self {
4964 Self {
4965 name: MaybeUninit::uninit(),
4966 value: MaybeUninit::uninit(),
4967 initialized: false,
4968 }
4969 }
4970
4971 fn init(&mut self, name: String, value: i32) {
4972 self.name.write(name);
4973 self.value.write(value);
4974 self.initialized = true;
4975 }
4976
4977 fn get_name(&self) -> Option<&String> {
4978 if self.initialized {
4979 unsafe { Some(self.name.assume_init_ref()) }
4980 } else {
4981 None
4982 }
4983 }
4984
4985 fn get_value(&self) -> Option<&i32> {
4986 if self.initialized {
4987 unsafe { Some(self.value.assume_init_ref()) }
4988 } else {
4989 None
4990 }
4991 }
4992 }
4993
4994 let name_kp: KpType<Config, String> = Kp::new(
4996 |c: &Config| c.get_name(),
4997 |c: &mut Config| {
4998 if c.initialized {
4999 unsafe { Some(c.name.assume_init_mut()) }
5000 } else {
5001 None
5002 }
5003 },
5004 );
5005
5006 let value_kp: KpType<Config, i32> = Kp::new(
5007 |c: &Config| c.get_value(),
5008 |c: &mut Config| {
5009 if c.initialized {
5010 unsafe { Some(c.value.assume_init_mut()) }
5011 } else {
5012 None
5013 }
5014 },
5015 );
5016
5017 let uninit_config = Config::new_uninit();
5019 assert_eq!(name_kp.get(&uninit_config), None);
5020 assert_eq!(value_kp.get(&uninit_config), None);
5021
5022 let mut init_config = Config::new_uninit();
5024 init_config.init("test_config".to_string(), 42);
5025
5026 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
5027 assert_eq!(value_kp.get(&init_config), Some(&42));
5028
5029 if let Some(val) = value_kp.get_mut(&mut init_config) {
5031 *val = 100;
5032 }
5033
5034 assert_eq!(value_kp.get(&init_config), Some(&100));
5035 }
5036
5037 #[test]
5038 fn test_kp_with_weak() {
5039 use std::sync::{Arc, Weak};
5040
5041 #[derive(Debug, Clone)]
5045 struct Node {
5046 value: i32,
5047 }
5048
5049 struct NodeWithParent {
5050 value: i32,
5051 parent: Option<Arc<Node>>, }
5053
5054 let parent = Arc::new(Node { value: 100 });
5055
5056 let child = NodeWithParent {
5057 value: 42,
5058 parent: Some(parent.clone()),
5059 };
5060
5061 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
5063 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
5064 |_: &mut NodeWithParent| None::<&mut i32>,
5065 );
5066
5067 let parent_val = parent_value_kp.get(&child);
5069 assert_eq!(parent_val, Some(&100));
5070 }
5071
5072 #[test]
5073 fn test_kp_with_rc_weak() {
5074 use std::rc::Rc;
5075
5076 struct TreeNode {
5079 value: String,
5080 parent: Option<Rc<TreeNode>>, }
5082
5083 let root = Rc::new(TreeNode {
5084 value: "root".to_string(),
5085 parent: None,
5086 });
5087
5088 let child1 = TreeNode {
5089 value: "child1".to_string(),
5090 parent: Some(root.clone()),
5091 };
5092
5093 let child2 = TreeNode {
5094 value: "child2".to_string(),
5095 parent: Some(root.clone()),
5096 };
5097
5098 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
5100 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
5101 |_: &mut TreeNode| None::<&mut String>,
5102 );
5103
5104 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
5106 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
5107
5108 assert_eq!(parent_name_kp.get(&root), None);
5110 }
5111
5112 #[test]
5113 fn test_kp_with_complex_weak_structure() {
5114 use std::sync::Arc;
5115
5116 struct Cache {
5119 data: String,
5120 backup: Option<Arc<Cache>>, }
5122
5123 let primary = Arc::new(Cache {
5124 data: "primary_data".to_string(),
5125 backup: None,
5126 });
5127
5128 let backup = Arc::new(Cache {
5129 data: "backup_data".to_string(),
5130 backup: Some(primary.clone()),
5131 });
5132
5133 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
5135 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
5136 |_: &mut Arc<Cache>| None::<&mut String>,
5137 );
5138
5139 let data = backup_data_kp.get(&backup);
5141 assert_eq!(data, Some(&"primary_data".to_string()));
5142
5143 let no_backup = backup_data_kp.get(&primary);
5145 assert_eq!(no_backup, None);
5146 }
5147
5148 #[test]
5149 fn test_kp_chain_with_pin_and_arc() {
5150 use std::pin::Pin;
5151 use std::sync::Arc;
5152
5153 struct Outer {
5156 inner: Arc<Inner>,
5157 }
5158
5159 struct Inner {
5160 value: String,
5161 }
5162
5163 let outer = Outer {
5164 inner: Arc::new(Inner {
5165 value: "nested_value".to_string(),
5166 }),
5167 };
5168
5169 let pinned_outer = Box::pin(outer);
5170
5171 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
5173 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
5174 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
5175 );
5176
5177 let to_value: KpType<Arc<Inner>, String> = Kp::new(
5179 |a: &Arc<Inner>| Some(&a.value),
5180 |_: &mut Arc<Inner>| None::<&mut String>,
5181 );
5182
5183 let chained = to_inner.then(to_value);
5185
5186 let result = chained.get(&pinned_outer);
5187 assert_eq!(result, Some(&"nested_value".to_string()));
5188 }
5189
5190 #[test]
5191 fn test_kp_with_maybe_uninit_array() {
5192 use std::mem::MaybeUninit;
5193
5194 struct Buffer {
5198 data: [MaybeUninit<u8>; 10],
5199 len: usize,
5200 }
5201
5202 impl Buffer {
5203 fn new() -> Self {
5204 Self {
5205 data: unsafe { MaybeUninit::uninit().assume_init() },
5206 len: 0,
5207 }
5208 }
5209
5210 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
5211 if self.len >= self.data.len() {
5212 return Err("Buffer full");
5213 }
5214 self.data[self.len].write(byte);
5215 self.len += 1;
5216 Ok(())
5217 }
5218
5219 fn get(&self, idx: usize) -> Option<&u8> {
5220 if idx < self.len {
5221 unsafe { Some(self.data[idx].assume_init_ref()) }
5222 } else {
5223 None
5224 }
5225 }
5226
5227 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
5228 if idx < self.len {
5229 unsafe { Some(self.data[idx].assume_init_mut()) }
5230 } else {
5231 None
5232 }
5233 }
5234 }
5235
5236 let len_kp: KpType<Buffer, usize> =
5238 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
5239
5240 let mut buffer = Buffer::new();
5241
5242 assert_eq!(len_kp.get(&buffer), Some(&0));
5244
5245 buffer.push(1).unwrap();
5247 buffer.push(2).unwrap();
5248 buffer.push(3).unwrap();
5249
5250 assert_eq!(len_kp.get(&buffer), Some(&3));
5252
5253 assert_eq!(buffer.get(0), Some(&1));
5255 assert_eq!(buffer.get(1), Some(&2));
5256 assert_eq!(buffer.get(2), Some(&3));
5257 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
5261 *elem = 20;
5262 }
5263 assert_eq!(buffer.get(1), Some(&20));
5264 }
5265
5266 #[test]
5267 fn test_kp_then_lock_deep_structs() {
5268 use std::sync::{Arc, Mutex};
5269
5270 #[derive(Clone)]
5271 struct Root {
5272 guard: Arc<Mutex<Level1>>,
5273 }
5274 #[derive(Clone)]
5275 struct Level1 {
5276 name: String,
5277 nested: Level2,
5278 }
5279 #[derive(Clone)]
5280 struct Level2 {
5281 count: i32,
5282 }
5283
5284 let root = Root {
5285 guard: Arc::new(Mutex::new(Level1 {
5286 name: "deep".to_string(),
5287 nested: Level2 { count: 42 },
5288 })),
5289 };
5290
5291 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
5292 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
5293
5294 let lock_kp = {
5295 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> = Kp::new(
5296 |g: &Arc<Mutex<Level1>>| Some(g),
5297 |g: &mut Arc<Mutex<Level1>>| Some(g),
5298 );
5299 let next: KpType<Level1, Level1> =
5300 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5301 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5302 };
5303
5304 let chained = kp_to_guard.then_lock(lock_kp);
5305 let level1 = chained.get(&root);
5306 assert!(level1.is_some());
5307 assert_eq!(level1.unwrap().name, "deep");
5308 assert_eq!(level1.unwrap().nested.count, 42);
5309
5310 let mut_root = &mut root.clone();
5311 let mut_level1 = chained.get_mut(mut_root);
5312 assert!(mut_level1.is_some());
5313 mut_level1.unwrap().nested.count = 99;
5314 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
5315 }
5316
5317 #[test]
5318 fn test_kp_then_lock_with_enum() {
5319 use std::sync::{Arc, Mutex};
5320
5321 #[derive(Clone)]
5322 enum Message {
5323 Request(LevelA),
5324 Response(i32),
5325 }
5326 #[derive(Clone)]
5327 struct LevelA {
5328 data: Arc<Mutex<i32>>,
5329 }
5330
5331 struct RootWithEnum {
5332 msg: Arc<Mutex<Message>>,
5333 }
5334
5335 let root = RootWithEnum {
5336 msg: Arc::new(Mutex::new(Message::Request(LevelA {
5337 data: Arc::new(Mutex::new(100)),
5338 }))),
5339 };
5340
5341 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> = Kp::new(
5342 |r: &RootWithEnum| Some(&r.msg),
5343 |r: &mut RootWithEnum| Some(&mut r.msg),
5344 );
5345
5346 let lock_kp_msg = {
5347 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> = Kp::new(
5348 |m: &Arc<Mutex<Message>>| Some(m),
5349 |m: &mut Arc<Mutex<Message>>| Some(m),
5350 );
5351 let next: KpType<Message, Message> =
5352 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
5353 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5354 };
5355
5356 let chained = kp_msg.then_lock(lock_kp_msg);
5357 let msg = chained.get(&root);
5358 assert!(msg.is_some());
5359 match msg.unwrap() {
5360 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
5361 Message::Response(_) => panic!("expected Request"),
5362 }
5363 }
5364
5365 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5366 #[tokio::test]
5367 async fn test_kp_then_async_deep_chain() {
5368 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5369 use std::sync::Arc;
5370
5371 #[derive(Clone)]
5372 struct Root {
5373 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
5374 }
5375 #[derive(Clone)]
5376 struct Level1 {
5377 value: i32,
5378 }
5379
5380 let root = Root {
5381 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
5382 };
5383
5384 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
5385 |r: &Root| Some(&r.tokio_guard),
5386 |r: &mut Root| Some(&mut r.tokio_guard),
5387 );
5388
5389 let async_kp = {
5390 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
5391 Kp::new(
5392 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
5393 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
5394 );
5395 let next: KpType<Level1, Level1> =
5396 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5397 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5398 };
5399
5400 let chained = kp_to_guard.then_async(async_kp);
5401 let level1 = chained.get(&root).await;
5402 assert!(level1.is_some());
5403 assert_eq!(level1.unwrap().value, 7);
5404 }
5405
5406 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5409 #[tokio::test]
5410 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
5411 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5412 use crate::lock::{ArcMutexAccess, LockKp};
5413 use std::sync::{Arc, Mutex};
5414
5415 #[derive(Clone)]
5417 struct Root {
5418 sync_mutex: Arc<Mutex<Level1>>,
5419 }
5420 #[derive(Clone)]
5422 struct Level1 {
5423 inner: Level2,
5424 }
5425 #[derive(Clone)]
5427 struct Level2 {
5428 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
5429 }
5430 #[derive(Clone)]
5432 struct Level3 {
5433 leaf: i32,
5434 }
5435
5436 let mut root = Root {
5437 sync_mutex: Arc::new(Mutex::new(Level1 {
5438 inner: Level2 {
5439 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
5440 },
5441 })),
5442 };
5443
5444 let identity_l1: KpType<Level1, Level1> =
5446 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5447 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
5448 |r: &Root| Some(&r.sync_mutex),
5449 |r: &mut Root| Some(&mut r.sync_mutex),
5450 );
5451 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
5452
5453 let kp_l1_inner: KpType<Level1, Level2> = Kp::new(
5455 |l: &Level1| Some(&l.inner),
5456 |l: &mut Level1| Some(&mut l.inner),
5457 );
5458
5459 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
5461 |l: &Level2| Some(&l.tokio_mutex),
5462 |l: &mut Level2| Some(&mut l.tokio_mutex),
5463 );
5464
5465 let async_l3 = {
5467 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
5468 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
5469 let next: KpType<Level3, Level3> =
5470 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
5471 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5472 };
5473
5474 let kp_l3_leaf: KpType<Level3, i32> = Kp::new(
5476 |l: &Level3| Some(&l.leaf),
5477 |l: &mut Level3| Some(&mut l.leaf),
5478 );
5479
5480 let step1 = lock_root_to_l1.then(kp_l1_inner);
5482 let step2 = step1.then(kp_l2_tokio);
5483 let step3 = step2.then_async(async_l3);
5484 let deep_chain = step3.then(kp_l3_leaf);
5485
5486 let leaf = deep_chain.get(&root).await;
5488 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5489 assert_eq!(leaf, Some(&100));
5490
5491 let mut root_mut = root.clone();
5493 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5494 assert!(leaf_mut.is_some());
5495 *leaf_mut.unwrap() = 99;
5496
5497 let leaf_after = deep_chain.get(&root_mut).await;
5499 assert_eq!(leaf_after, Some(&99));
5500 }
5501}