1use std::sync::{Arc};
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{
1231 fn get_optional(&self, root: Option<Root>) -> Option<Value>;
1233 fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue>;
1239 fn get_or_else<F>(&self, root: Root, f: F) -> Value
1245 where
1246 F: FnOnce() -> Value;
1247 #[inline]
1253 fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
1254 where
1255 F: FnOnce() -> MutValue,;
1256 }
1260
1261pub trait CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1262where
1263 Root: std::borrow::Borrow<R>,
1264 Value: std::borrow::Borrow<V>,
1265 MutRoot: std::borrow::BorrowMut<R>,
1266 MutValue: std::borrow::BorrowMut<V>,
1267 G: Fn(Root) -> Option<Value>,
1268 S: Fn(MutRoot) -> Option<MutValue>,
1269{
1270 fn for_arc<'b>(
1271 &self,
1272 ) -> Kp<
1273 std::sync::Arc<R>,
1274 V,
1275 std::sync::Arc<R>,
1276 Value,
1277 std::sync::Arc<R>,
1278 MutValue,
1279 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1280 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1281 >
1282 where
1283 R: 'b,
1284 V: 'b,
1285 Root: for<'a> From<&'a R>,
1286 MutRoot: for<'a> From<&'a mut R>,;
1287
1288 fn for_box<'a>(
1289 &self,
1290 ) -> Kp<
1291 Box<R>,
1292 V,
1293 Box<R>,
1294 Value,
1295 Box<R>,
1296 MutValue,
1297 impl Fn(Box<R>) -> Option<Value>,
1298 impl Fn(Box<R>) -> Option<MutValue>,
1299 >
1300 where
1301 R: 'a,
1302 V: 'a,
1303 Root: for<'b> From<&'b R>,
1304 MutRoot: for<'b> From<&'b mut R>,;
1305
1306 fn into_set(self) -> impl Fn(MutRoot) -> Option<MutValue>;
1308
1309 fn into_get(self) -> impl Fn(Root) -> Option<Value>;
1311
1312}
1313
1314pub trait HofTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
1315 KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1316where
1317 Root: std::borrow::Borrow<R>,
1318 Value: std::borrow::Borrow<V>,
1319 MutRoot: std::borrow::BorrowMut<R>,
1320 MutValue: std::borrow::BorrowMut<V>,
1321 G: Fn(Root) -> Option<Value>,
1322 S: Fn(MutRoot) -> Option<MutValue>,
1323{
1324 fn map<MappedValue, F>(
1374 &self,
1375 mapper: F,
1376 ) -> Kp<
1377 R,
1378 MappedValue,
1379 Root,
1380 MappedValue,
1381 MutRoot,
1382 MappedValue,
1383 impl Fn(Root) -> Option<MappedValue> + '_,
1384 impl Fn(MutRoot) -> Option<MappedValue> + '_,
1385 >
1386 where
1387 F: Fn(&V) -> MappedValue + Copy + 'static,
1388 V: 'static,
1389 MappedValue: 'static,
1390 {
1391 Kp::new(
1392 move |root: Root| {
1393 self.get(root).map(|value| {
1394 let v: &V = value.borrow();
1395 mapper(v)
1396 })
1397 },
1398 move |root: MutRoot| {
1399 self.get_mut(root).map(|value| {
1400 let v: &V = value.borrow();
1401 mapper(v)
1402 })
1403 },
1404 )
1405 }
1406
1407 fn filter<F>(
1409 &self,
1410 predicate: F,
1411 ) -> Kp<
1412 R,
1413 V,
1414 Root,
1415 Value,
1416 MutRoot,
1417 MutValue,
1418 impl Fn(Root) -> Option<Value> + '_,
1419 impl Fn(MutRoot) -> Option<MutValue> + '_,
1420 >
1421 where
1422 F: Fn(&V) -> bool + Copy + 'static,
1423 V: 'static,
1424 {
1425 Kp::new(
1426 move |root: Root| {
1427 self.get(root).filter(|value| {
1428 let v: &V = value.borrow();
1429 predicate(v)
1430 })
1431 },
1432 move |root: MutRoot| {
1433 self.get_mut(root).filter(|value| {
1434 let v: &V = value.borrow();
1435 predicate(v)
1436 })
1437 },
1438 )
1439 }
1440
1441 fn filter_map<MappedValue, F>(
1443 &self,
1444 mapper: F,
1445 ) -> Kp<
1446 R,
1447 MappedValue,
1448 Root,
1449 MappedValue,
1450 MutRoot,
1451 MappedValue,
1452 impl Fn(Root) -> Option<MappedValue> + '_,
1453 impl Fn(MutRoot) -> Option<MappedValue> + '_,
1454 >
1455 where
1456 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1457 V: 'static,
1458 MappedValue: 'static,
1459 {
1460 Kp::new(
1461 move |root: Root| {
1462 self.get(root).and_then(|value| {
1463 let v: &V = value.borrow();
1464 mapper(v)
1465 })
1466 },
1467 move |root: MutRoot| {
1468 self.get_mut(root).and_then(|value| {
1469 let v: &V = value.borrow();
1470 mapper(v)
1471 })
1472 },
1473 )
1474 }
1475
1476 fn inspect<F>(
1478 &self,
1479 inspector: F,
1480 ) -> Kp<
1481 R,
1482 V,
1483 Root,
1484 Value,
1485 MutRoot,
1486 MutValue,
1487 impl Fn(Root) -> Option<Value> + '_,
1488 impl Fn(MutRoot) -> Option<MutValue> + '_,
1489 >
1490 where
1491 F: Fn(&V) + Copy + 'static,
1492 V: 'static,
1493 {
1494 Kp::new(
1495 move |root: Root| {
1496 self.get(root).map(|value| {
1497 let v: &V = value.borrow();
1498 inspector(v);
1499 value
1500 })
1501 },
1502 move |root: MutRoot| {
1503 self.get_mut(root).map(|value| {
1504 let v: &V = value.borrow();
1505 inspector(v);
1506 value
1507 })
1508 },
1509 )
1510 }
1511
1512 fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item> + '_
1514 where
1515 F: Fn(&V) -> I + 'static,
1516 V: 'static,
1517 I: IntoIterator<Item = Item>,
1518 Item: 'static,
1519 {
1520 move |root: Root| {
1521 self.get(root)
1522 .map(|value| {
1523 let v: &V = value.borrow();
1524 mapper(v).into_iter().collect()
1525 })
1526 .unwrap_or_else(Vec::new)
1527 }
1528 }
1529
1530 fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc + '_
1532 where
1533 F: Fn(Acc, &V) -> Acc + 'static,
1534 V: 'static,
1535 Acc: Copy + 'static,
1536 {
1537 move |root: Root| {
1538 self.get(root)
1539 .map(|value| {
1540 let v: &V = value.borrow();
1541 folder(init, v)
1542 })
1543 .unwrap_or(init)
1544 }
1545 }
1546
1547 fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
1549 where
1550 F: Fn(&V) -> bool + 'static,
1551 V: 'static,
1552 {
1553 move |root: Root| {
1554 self.get(root)
1555 .map(|value| {
1556 let v: &V = value.borrow();
1557 predicate(v)
1558 })
1559 .unwrap_or(false)
1560 }
1561 }
1562
1563 fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
1565 where
1566 F: Fn(&V) -> bool + 'static,
1567 V: 'static,
1568 {
1569 move |root: Root| {
1570 self.get(root)
1571 .map(|value| {
1572 let v: &V = value.borrow();
1573 predicate(v)
1574 })
1575 .unwrap_or(true)
1576 }
1577 }
1578
1579 fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize> + '_
1581 where
1582 F: Fn(&V) -> usize + 'static,
1583 V: 'static,
1584 {
1585 move |root: Root| {
1586 self.get(root).map(|value| {
1587 let v: &V = value.borrow();
1588 counter(v)
1589 })
1590 }
1591 }
1592
1593 fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item> + '_
1595 where
1596 F: Fn(&V) -> Option<Item> + 'static,
1597 V: 'static,
1598 Item: 'static,
1599 {
1600 move |root: Root| {
1601 self.get(root).and_then(|value| {
1602 let v: &V = value.borrow();
1603 finder(v)
1604 })
1605 }
1606 }
1607
1608 fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output> + '_
1610 where
1611 F: Fn(&V, usize) -> Output + 'static,
1612 V: 'static,
1613 Output: 'static,
1614 {
1615 move |root: Root| {
1616 self.get(root).map(|value| {
1617 let v: &V = value.borrow();
1618 taker(v, n)
1619 })
1620 }
1621 }
1622
1623 fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output> + '_
1625 where
1626 F: Fn(&V, usize) -> Output + 'static,
1627 V: 'static,
1628 Output: 'static,
1629 {
1630 move |root: Root| {
1631 self.get(root).map(|value| {
1632 let v: &V = value.borrow();
1633 skipper(v, n)
1634 })
1635 }
1636 }
1637
1638 fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output> + '_
1640 where
1641 F: Fn(&V) -> Output + 'static,
1642 V: 'static,
1643 Output: 'static,
1644 {
1645 move |root: Root| {
1646 self.get(root).map(|value| {
1647 let v: &V = value.borrow();
1648 partitioner(v)
1649 })
1650 }
1651 }
1652
1653 fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item> + '_
1655 where
1656 F: Fn(&V) -> Option<Item> + 'static,
1657 V: 'static,
1658 Item: 'static,
1659 {
1660 move |root: Root| {
1661 self.get(root).and_then(|value| {
1662 let v: &V = value.borrow();
1663 min_fn(v)
1664 })
1665 }
1666 }
1667
1668 fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item> + '_
1670 where
1671 F: Fn(&V) -> Option<Item> + 'static,
1672 V: 'static,
1673 Item: 'static,
1674 {
1675 move |root: Root| {
1676 self.get(root).and_then(|value| {
1677 let v: &V = value.borrow();
1678 max_fn(v)
1679 })
1680 }
1681 }
1682
1683 fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum> + '_
1685 where
1686 F: Fn(&V) -> Sum + 'static,
1687 V: 'static,
1688 Sum: 'static,
1689 {
1690 move |root: Root| {
1691 self.get(root).map(|value| {
1692 let v: &V = value.borrow();
1693 sum_fn(v)
1694 })
1695 }
1696 }
1697
1698 }
1749
1750impl<R, V, Root, Value, MutRoot, MutValue, G, S> KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1751 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1752where
1753 Root: std::borrow::Borrow<R>,
1754 Value: std::borrow::Borrow<V>,
1755 MutRoot: std::borrow::BorrowMut<R>,
1756 MutValue: std::borrow::BorrowMut<V>,
1757 G: Fn(Root) -> Option<Value>,
1758 S: Fn(MutRoot) -> Option<MutValue>,
1759{
1760
1761 fn then<SV, SubValue, MutSubValue, G2, S2>(
1762 self,
1763 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1764 ) -> Kp<
1765 R,
1766 SV,
1767 Root,
1768 SubValue,
1769 MutRoot,
1770 MutSubValue,
1771 impl Fn(Root) -> Option<SubValue>,
1772 impl Fn(MutRoot) -> Option<MutSubValue>,
1773 >
1774 where
1775 SubValue: std::borrow::Borrow<SV>,
1776 MutSubValue: std::borrow::BorrowMut<SV>,
1777 G2: Fn(Value) -> Option<SubValue>,
1778 S2: Fn(MutValue) -> Option<MutSubValue>,
1779 V: 'static,
1780 {
1781 Kp::new(
1782 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
1783 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
1784 )
1785 }
1786
1787 fn get(&self, root: Root) -> Option<Value> {
1788 (self.get)(root)
1789 }
1790
1791 fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1792 (self.set)(root)
1793 }
1794
1795}
1796
1797impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1798 CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1799 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1800where
1801 Root: std::borrow::Borrow<R>,
1802 Value: std::borrow::Borrow<V>,
1803 MutRoot: std::borrow::BorrowMut<R>,
1804 MutValue: std::borrow::BorrowMut<V>,
1805 G: Fn(Root) -> Option<Value>,
1806 S: Fn(MutRoot) -> Option<MutValue>,
1807{
1808 fn for_arc<'b>(
1809 &self,
1810 ) -> Kp<
1811 std::sync::Arc<R>,
1812 V,
1813 std::sync::Arc<R>,
1814 Value,
1815 std::sync::Arc<R>,
1816 MutValue,
1817 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1818 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1819 >
1820 where
1821 R: 'b,
1822 V: 'b,
1823 Root: for<'a> From<&'a R>,
1824 MutRoot: for<'a> From<&'a mut R>,
1825 {
1826 Kp::new(
1827 move |arc_root: std::sync::Arc<R>| {
1828 let r_ref: &R = &*arc_root;
1829 (self.get)(Root::from(r_ref))
1830 },
1831 move |mut arc_root: std::sync::Arc<R>| {
1832 std::sync::Arc::get_mut(&mut arc_root)
1834 .and_then(|r_mut| (self.set)(MutRoot::from(r_mut)))
1835 },
1836 )
1837 }
1838
1839 fn for_box<'a>(
1840 &self,
1841 ) -> Kp<
1842 Box<R>,
1843 V,
1844 Box<R>,
1845 Value,
1846 Box<R>,
1847 MutValue,
1848 impl Fn(Box<R>) -> Option<Value>,
1849 impl Fn(Box<R>) -> Option<MutValue>,
1850 >
1851 where
1852 R: 'a,
1853 V: 'a,
1854 Root: for<'b> From<&'b R>,
1855 MutRoot: for<'b> From<&'b mut R>,
1856 {
1857 Kp::new(
1858 move |r: Box<R>| {
1859 let r_ref: &R = r.as_ref();
1860 (self.get)(Root::from(r_ref))
1861 },
1862 move |mut r: Box<R>| {
1863 (self.set)(MutRoot::from(r.as_mut()))
1865 },
1866 )
1867 }
1868
1869
1870 #[inline]
1872 fn into_set(self) -> impl Fn(MutRoot) -> Option<MutValue> {
1873 self.set
1874 }
1875
1876 #[inline]
1878 fn into_get(self) -> impl Fn(Root) -> Option<Value> {
1879 self.get
1880 }
1881}
1882
1883impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1884 HofTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1885 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1886where
1887 Root: std::borrow::Borrow<R>,
1888 Value: std::borrow::Borrow<V>,
1889 MutRoot: std::borrow::BorrowMut<R>,
1890 MutValue: std::borrow::BorrowMut<V>,
1891 G: Fn(Root) -> Option<Value>,
1892 S: Fn(MutRoot) -> Option<MutValue>,
1893{
1894}
1895
1896impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1897 AccessorTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1898 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1899where
1900 Root: std::borrow::Borrow<R>,
1901 Value: std::borrow::Borrow<V>,
1902 MutRoot: std::borrow::BorrowMut<R>,
1903 MutValue: std::borrow::BorrowMut<V>,
1904 G: Fn(Root) -> Option<Value>,
1905 S: Fn(MutRoot) -> Option<MutValue>,
1906{
1907 #[inline]
1909 fn get_optional(&self, root: Option<Root>) -> Option<Value>
1910 {
1911 root.and_then(|r| (self.get)(r))
1912 }
1913
1914 #[inline]
1916 fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue>
1917 {
1918 root.and_then(|r| (self.set)(r))
1919 }
1920
1921 #[inline]
1923 fn get_or_else<F>(&self, root: Root, f: F) -> Value
1924 where
1925 F: FnOnce() -> Value
1926 {
1927 (self.get)(root).unwrap_or_else(f)
1928 }
1929
1930 #[inline]
1932 fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
1933 where
1934 F: FnOnce() -> MutValue,
1935 {
1936 (self.set)(root).unwrap_or_else(f)
1937 }
1938}
1939
1940#[derive(Clone)]
1952pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1953where
1954 Root: std::borrow::Borrow<R>,
1955 MutRoot: std::borrow::BorrowMut<R>,
1956 MutValue: std::borrow::BorrowMut<V>,
1957 G: Fn(Root) -> Option<Value>,
1958 S: Fn(MutRoot) -> Option<MutValue>,
1959{
1960 pub get: G,
1962 pub set: S,
1964 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
1965}
1966
1967unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Send
1969 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1970where
1971 Root: std::borrow::Borrow<R>,
1972 MutRoot: std::borrow::BorrowMut<R>,
1973 MutValue: std::borrow::BorrowMut<V>,
1974 G: Fn(Root) -> Option<Value> + Send,
1975 S: Fn(MutRoot) -> Option<MutValue> + Send,
1976{
1977}
1978unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Sync
1979 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1980where
1981 Root: std::borrow::Borrow<R>,
1982 MutRoot: std::borrow::BorrowMut<R>,
1983 MutValue: std::borrow::BorrowMut<V>,
1984 G: Fn(Root) -> Option<Value> + Sync,
1985 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1986{
1987}
1988
1989
1990impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1991where
1992 Root: std::borrow::Borrow<R>,
1993 Value: std::borrow::Borrow<V>,
1994 MutRoot: std::borrow::BorrowMut<R>,
1995 MutValue: std::borrow::BorrowMut<V>,
1996 G: Fn(Root) -> Option<Value>,
1997 S: Fn(MutRoot) -> Option<MutValue>,
1998{
1999 pub fn new(get: G, set: S) -> Self {
2000 Self {
2001 get: get,
2002 set: set,
2003 _p: std::marker::PhantomData,
2004 }
2005 }
2006
2007 #[inline]
2018 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
2019 self,
2020 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
2021 ) -> Kp<
2022 R,
2023 SV,
2024 Root,
2025 SubValue,
2026 MutRoot,
2027 MutSubValue,
2028 impl Fn(Root) -> Option<SubValue>,
2029 impl Fn(MutRoot) -> Option<MutSubValue>,
2030 >
2031 where
2032 SubValue: std::borrow::Borrow<SV>,
2033 MutSubValue: std::borrow::BorrowMut<SV>,
2034 G2: Fn(Value) -> Option<SubValue>,
2035 S2: Fn(MutValue) -> Option<MutSubValue>,
2036 V: 'static,
2037 {
2038 Kp::new(
2039 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
2040 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
2041 )
2042 }
2043
2044}
2045pub fn zip_kps<'a, RootType, Value1, Value2>(
2059 kp1: &'a KpType<'a, RootType, Value1>,
2060 kp2: &'a KpType<'a, RootType, Value2>,
2061) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
2062where
2063 RootType: 'a,
2064 Value1: 'a,
2065 Value2: 'a,
2066{
2067 move |root: &'a RootType| {
2068 let val1 = (kp1.get)(root)?;
2069 let val2 = (kp2.get)(root)?;
2070 Some((val1, val2))
2071 }
2072}
2073
2074impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
2075where
2076 Root: std::borrow::Borrow<R>,
2077 MutRoot: std::borrow::BorrowMut<R>,
2078 G: Fn(Root) -> Option<Root>,
2079 S: Fn(MutRoot) -> Option<MutRoot>,
2080{
2081 pub fn identity_typed() -> Kp<
2082 R,
2083 R,
2084 Root,
2085 Root,
2086 MutRoot,
2087 MutRoot,
2088 fn(Root) -> Option<Root>,
2089 fn(MutRoot) -> Option<MutRoot>,
2090 > {
2091 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
2092 }
2093
2094 pub fn identity<'a>() -> KpType<'a, R, R> {
2095 KpType::new(|r| Some(r), |r| Some(r))
2096 }
2097}
2098
2099pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2108where
2109 Root: std::borrow::Borrow<Enum>,
2110 Value: std::borrow::Borrow<Variant>,
2111 MutRoot: std::borrow::BorrowMut<Enum>,
2112 MutValue: std::borrow::BorrowMut<Variant>,
2113 G: Fn(Root) -> Option<Value>,
2114 S: Fn(MutRoot) -> Option<MutValue>,
2115 E: Fn(Variant) -> Enum,
2116{
2117 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
2118 embedder: E,
2119}
2120
2121unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
2123 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2124where
2125 Root: std::borrow::Borrow<Enum>,
2126 Value: std::borrow::Borrow<Variant>,
2127 MutRoot: std::borrow::BorrowMut<Enum>,
2128 MutValue: std::borrow::BorrowMut<Variant>,
2129 G: Fn(Root) -> Option<Value> + Send,
2130 S: Fn(MutRoot) -> Option<MutValue> + Send,
2131 E: Fn(Variant) -> Enum + Send,
2132{
2133}
2134unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
2135 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2136where
2137 Root: std::borrow::Borrow<Enum>,
2138 Value: std::borrow::Borrow<Variant>,
2139 MutRoot: std::borrow::BorrowMut<Enum>,
2140 MutValue: std::borrow::BorrowMut<Variant>,
2141 G: Fn(Root) -> Option<Value> + Sync,
2142 S: Fn(MutRoot) -> Option<MutValue> + Sync,
2143 E: Fn(Variant) -> Enum + Sync,
2144{
2145}
2146
2147impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2148 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2149where
2150 Root: std::borrow::Borrow<Enum>,
2151 Value: std::borrow::Borrow<Variant>,
2152 MutRoot: std::borrow::BorrowMut<Enum>,
2153 MutValue: std::borrow::BorrowMut<Variant>,
2154 G: Fn(Root) -> Option<Value>,
2155 S: Fn(MutRoot) -> Option<MutValue>,
2156 E: Fn(Variant) -> Enum,
2157{
2158 pub fn new(
2160 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
2161 embedder: E,
2162 ) -> Self {
2163 Self {
2164 extractor,
2165 embedder,
2166 }
2167 }
2168
2169 pub fn get(&self, enum_value: Root) -> Option<Value> {
2171 (self.extractor.get)(enum_value)
2172 }
2173
2174 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
2176 (self.extractor.set)(enum_value)
2177 }
2178
2179 pub fn embed(&self, value: Variant) -> Enum {
2181 (self.embedder)(value)
2182 }
2183
2184 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2186 &self.extractor
2187 }
2188
2189 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2191 self.extractor
2192 }
2193
2194 pub fn map<MappedValue, F>(
2205 &self,
2206 mapper: F,
2207 ) -> EnumKp<
2208 Enum,
2209 MappedValue,
2210 Root,
2211 MappedValue,
2212 MutRoot,
2213 MappedValue,
2214 impl Fn(Root) -> Option<MappedValue>,
2215 impl Fn(MutRoot) -> Option<MappedValue>,
2216 impl Fn(MappedValue) -> Enum,
2217 >
2218 where
2219 F: Fn(&Variant) -> MappedValue + Copy + 'static,
2222 Variant: 'static,
2223 MappedValue: 'static,
2224 E: Fn(Variant) -> Enum + Copy + 'static,
2226 {
2227 let mapped_extractor = self.extractor.map(mapper);
2228
2229 let new_embedder = move |_value: MappedValue| -> Enum {
2233 panic!(
2234 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
2235 )
2236 };
2237
2238 EnumKp::new(mapped_extractor, new_embedder)
2239 }
2240
2241 pub fn filter<F>(
2253 &self,
2254 predicate: F,
2255 ) -> EnumKp<
2256 Enum,
2257 Variant,
2258 Root,
2259 Value,
2260 MutRoot,
2261 MutValue,
2262 impl Fn(Root) -> Option<Value>,
2263 impl Fn(MutRoot) -> Option<MutValue>,
2264 E,
2265 >
2266 where
2267 F: Fn(&Variant) -> bool + Copy + 'static,
2270 Variant: 'static,
2271 E: Copy,
2273 {
2274 let filtered_extractor = self.extractor.filter(predicate);
2275 EnumKp::new(filtered_extractor, self.embedder)
2276 }
2277}
2278
2279pub type EnumKpType<'a, Enum, Variant> = EnumKp<
2281 Enum,
2282 Variant,
2283 &'a Enum,
2284 &'a Variant,
2285 &'a mut Enum,
2286 &'a mut Variant,
2287 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2288 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2289 fn(Variant) -> Enum,
2290>;
2291
2292pub fn enum_variant<'a, Enum, Variant>(
2310 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2311 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2312 embedder: fn(Variant) -> Enum,
2313) -> EnumKpType<'a, Enum, Variant> {
2314 EnumKp::new(Kp::new(getter, setter), embedder)
2315}
2316
2317pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
2327 EnumKp::new(
2328 Kp::new(
2329 |r: &Result<T, E>| r.as_ref().ok(),
2330 |r: &mut Result<T, E>| r.as_mut().ok(),
2331 ),
2332 |t: T| Ok(t),
2333 )
2334}
2335
2336pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
2346 EnumKp::new(
2347 Kp::new(
2348 |r: &Result<T, E>| r.as_ref().err(),
2349 |r: &mut Result<T, E>| r.as_mut().err(),
2350 ),
2351 |e: E| Err(e),
2352 )
2353}
2354
2355pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
2365 EnumKp::new(
2366 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
2367 |t: T| Some(t),
2368 )
2369}
2370
2371pub fn variant_of<'a, Enum, Variant>(
2389 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2390 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2391 embedder: fn(Variant) -> Enum,
2392) -> EnumKpType<'a, Enum, Variant> {
2393 enum_variant(getter, setter, embedder)
2394}
2395
2396pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
2409 Kp::new(
2410 |b: &Box<T>| Some(b.as_ref()),
2411 |b: &mut Box<T>| Some(b.as_mut()),
2412 )
2413}
2414
2415pub fn kp_arc<'a, T>() -> Kp<
2426 Arc<T>,
2427 T,
2428 &'a Arc<T>,
2429 &'a T,
2430 &'a mut Arc<T>,
2431 &'a mut T,
2432 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
2433 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
2434> {
2435 Kp::new(
2436 |arc: &Arc<T>| Some(arc.as_ref()),
2437 |arc: &mut Arc<T>| Arc::get_mut(arc),
2438 )
2439}
2440
2441pub fn kp_rc<'a, T>() -> Kp<
2452 std::rc::Rc<T>,
2453 T,
2454 &'a std::rc::Rc<T>,
2455 &'a T,
2456 &'a mut std::rc::Rc<T>,
2457 &'a mut T,
2458 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
2459 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
2460> {
2461 Kp::new(
2462 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
2463 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
2464 )
2465}
2466
2467use std::any::{Any, TypeId};
2470use std::rc::Rc;
2471
2472#[cfg(test)]
2487mod tests {
2488 use super::*;
2489 use std::collections::HashMap;
2490
2491 fn kp_adaptable<T, Root, Value, MutRoot, MutValue, G, S>(kp: T)
2492 where
2493 T: KpTrait<TestKP, String, Root, Value, MutRoot, MutValue, G, S>,
2494 {
2495 }
2498 fn test_kp_trait() {}
2499
2500 #[derive(Debug)]
2501 struct TestKP {
2502 a: String,
2503 b: String,
2504 c: std::sync::Arc<String>,
2505 d: std::sync::Mutex<String>,
2506 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
2507 f: Option<TestKP2>,
2508 g: HashMap<i32, TestKP2>,
2509 }
2510
2511 impl TestKP {
2512 fn new() -> Self {
2513 Self {
2514 a: String::from("a"),
2515 b: String::from("b"),
2516 c: std::sync::Arc::new(String::from("c")),
2517 d: std::sync::Mutex::new(String::from("d")),
2518 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2519 f: Some(TestKP2 {
2520 a: String::from("a3"),
2521 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2522 }),
2523 g: HashMap::new(),
2524 }
2525 }
2526
2527 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2528 KpComposed::from_closures(
2529 move |r: &TestKP| r.g.get(&index),
2530 move |r: &mut TestKP| r.g.get_mut(&index),
2531 )
2532 }
2533
2534 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2537 TestKP2,
2538 String,
2539 Root,
2540 Value,
2541 MutRoot,
2542 MutValue,
2543 impl Fn(Root) -> Option<Value>,
2544 impl Fn(MutRoot) -> Option<MutValue>,
2545 >
2546 where
2547 Root: std::borrow::Borrow<TestKP2>,
2548 MutRoot: std::borrow::BorrowMut<TestKP2>,
2549 Value: std::borrow::Borrow<String> + From<String>,
2550 MutValue: std::borrow::BorrowMut<String> + From<String>,
2551 {
2552 Kp::new(
2553 |r: Root| Some(Value::from(r.borrow().a.clone())),
2554 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2555 )
2556 }
2557
2558 fn c<'a>() -> KpType<'a, TestKP, String> {
2561 KpType::new(
2562 |r: &TestKP| Some(r.c.as_ref()),
2563 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2564 Some(arc_str) => Some(arc_str),
2565 None => None,
2566 },
2567 )
2568 }
2569
2570 fn a<'a>() -> KpType<'a, TestKP, String> {
2571 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2572 }
2573
2574 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2575 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2576 }
2577
2578 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2579 KpType::identity()
2580 }
2581 }
2582
2583 #[derive(Debug)]
2584 struct TestKP2 {
2585 a: String,
2586 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2587 }
2588
2589 impl TestKP2 {
2590 fn new() -> Self {
2591 TestKP2 {
2592 a: String::from("a2"),
2593 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2594 }
2595 }
2596
2597 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2598 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2605 fn(MutRoot) -> Option<MutRoot>,
2606 >
2607 where
2608 Root: std::borrow::Borrow<TestKP2>,
2609 MutRoot: std::borrow::BorrowMut<TestKP2>,
2610 G: Fn(Root) -> Option<Root>,
2611 S: Fn(MutRoot) -> Option<MutRoot>,
2612 {
2613 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2614 }
2615
2616 fn a<'a>() -> KpType<'a, TestKP2, String> {
2617 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2618 }
2619
2620 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2621 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2622 }
2623
2624 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2629 KpType::identity()
2630 }
2631 }
2632
2633 #[derive(Debug)]
2634 struct TestKP3 {
2635 a: String,
2636 b: std::sync::Arc<std::sync::Mutex<String>>,
2637 }
2638
2639 impl TestKP3 {
2640 fn new() -> Self {
2641 TestKP3 {
2642 a: String::from("a2"),
2643 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2644 }
2645 }
2646
2647 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2648 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2655 fn(MutRoot) -> Option<MutRoot>,
2656 >
2657 where
2658 Root: std::borrow::Borrow<TestKP3>,
2659 MutRoot: std::borrow::BorrowMut<TestKP3>,
2660 G: Fn(Root) -> Option<Root>,
2661 S: Fn(MutRoot) -> Option<MutRoot>,
2662 {
2663 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2664 }
2665
2666 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2667 KpType::identity()
2668 }
2669 }
2670
2671 impl TestKP3 {}
2672
2673 impl TestKP {}
2674 #[test]
2675 fn test_a() {
2676 let instance2 = TestKP2::new();
2677 let mut instance = TestKP::new();
2678 let kp = TestKP::identity();
2679 let kp_a = TestKP::a();
2680 let wres = TestKP::f()
2682 .then(TestKP2::a())
2683 .get_mut(&mut instance)
2684 .unwrap();
2685 *wres = String::from("a3 changed successfully");
2686 let res = (TestKP::f().then(TestKP2::a()).get)(&instance);
2687 println!("{:?}", res);
2688 let res = (TestKP::f().then(TestKP2::identity()).get)(&instance);
2689 println!("{:?}", res);
2690 let res = (kp.get)(&instance);
2691 println!("{:?}", res);
2692
2693 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2694 println!("{:?}", (new_kp_from_hashmap.get)(&instance));
2695 }
2696
2697 #[test]
2776 fn test_enum_kp_result_ok() {
2777 let ok_result: Result<String, i32> = Ok("success".to_string());
2778 let mut err_result: Result<String, i32> = Err(42);
2779
2780 let ok_kp = enum_ok();
2781
2782 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2784 assert_eq!(ok_kp.get(&err_result), None);
2785
2786 let embedded = ok_kp.embed("embedded".to_string());
2788 assert_eq!(embedded, Ok("embedded".to_string()));
2789
2790 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2792 *val = "modified".to_string();
2793 }
2794 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2797 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2798 *val = "modified".to_string();
2799 }
2800 assert_eq!(ok_result2, Ok("modified".to_string()));
2801 }
2802
2803 #[test]
2804 fn test_enum_kp_result_err() {
2805 let ok_result: Result<String, i32> = Ok("success".to_string());
2806 let mut err_result: Result<String, i32> = Err(42);
2807
2808 let err_kp = enum_err();
2809
2810 assert_eq!(err_kp.get(&err_result), Some(&42));
2812 assert_eq!(err_kp.get(&ok_result), None);
2813
2814 let embedded = err_kp.embed(99);
2816 assert_eq!(embedded, Err(99));
2817
2818 if let Some(val) = err_kp.get_mut(&mut err_result) {
2820 *val = 100;
2821 }
2822 assert_eq!(err_result, Err(100));
2823 }
2824
2825 #[test]
2826 fn test_enum_kp_option_some() {
2827 let some_opt = Some("value".to_string());
2828 let mut none_opt: Option<String> = None;
2829
2830 let some_kp = enum_some();
2831
2832 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2834 assert_eq!(some_kp.get(&none_opt), None);
2835
2836 let embedded = some_kp.embed("embedded".to_string());
2838 assert_eq!(embedded, Some("embedded".to_string()));
2839
2840 let mut some_opt2 = Some("original".to_string());
2842 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2843 *val = "modified".to_string();
2844 }
2845 assert_eq!(some_opt2, Some("modified".to_string()));
2846 }
2847
2848 #[test]
2849 fn test_enum_kp_custom_enum() {
2850 #[derive(Debug, PartialEq)]
2851 enum MyEnum {
2852 A(String),
2853 B(i32),
2854 C,
2855 }
2856
2857 let mut enum_a = MyEnum::A("hello".to_string());
2858 let enum_b = MyEnum::B(42);
2859 let enum_c = MyEnum::C;
2860
2861 let kp_a = enum_variant(
2863 |e: &MyEnum| match e {
2864 MyEnum::A(s) => Some(s),
2865 _ => None,
2866 },
2867 |e: &mut MyEnum| match e {
2868 MyEnum::A(s) => Some(s),
2869 _ => None,
2870 },
2871 |s: String| MyEnum::A(s),
2872 );
2873
2874 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2876 assert_eq!(kp_a.get(&enum_b), None);
2877 assert_eq!(kp_a.get(&enum_c), None);
2878
2879 let embedded = kp_a.embed("world".to_string());
2881 assert_eq!(embedded, MyEnum::A("world".to_string()));
2882
2883 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2885 *val = "modified".to_string();
2886 }
2887 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2888 }
2889
2890 #[test]
2891 fn test_container_kp_box() {
2892 let boxed = Box::new("value".to_string());
2893 let mut boxed_mut = Box::new("original".to_string());
2894
2895 let box_kp = kp_box();
2896
2897 assert_eq!((box_kp.get)(&boxed), Some(&"value".to_string()));
2899
2900 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2902 *val = "modified".to_string();
2903 }
2904 assert_eq!(*boxed_mut, "modified".to_string());
2905 }
2906
2907 #[test]
2908 fn test_container_kp_arc() {
2909 let arc = Arc::new("value".to_string());
2910 let mut arc_mut = Arc::new("original".to_string());
2911
2912 let arc_kp = kp_arc();
2913
2914 assert_eq!((arc_kp.get)(&arc), Some(&"value".to_string()));
2916
2917 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2919 *val = "modified".to_string();
2920 }
2921 assert_eq!(*arc_mut, "modified".to_string());
2922
2923 let arc_shared = Arc::new("shared".to_string());
2925 let arc_shared2 = Arc::clone(&arc_shared);
2926 let mut arc_shared_mut = arc_shared;
2927 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2928 }
2929
2930 #[test]
2931 fn test_enum_kp_composition() {
2932 #[derive(Debug, PartialEq)]
2934 struct Inner {
2935 value: String,
2936 }
2937
2938 let result: Result<Inner, i32> = Ok(Inner {
2939 value: "nested".to_string(),
2940 });
2941
2942 let inner_kp = KpType::new(
2944 |i: &Inner| Some(&i.value),
2945 |i: &mut Inner| Some(&mut i.value),
2946 );
2947
2948 let ok_kp = enum_ok::<Inner, i32>();
2950 let ok_kp_base = ok_kp.into_kp();
2951 let composed = ok_kp_base.then(inner_kp);
2952
2953 assert_eq!((composed.get)(&result), Some(&"nested".to_string()));
2954 }
2955
2956 #[test]
2957 fn test_pkp_basic() {
2958 #[derive(Debug)]
2959 struct User {
2960 name: String,
2961 age: i32,
2962 }
2963
2964 let user = User {
2965 name: "Akash".to_string(),
2966 age: 30,
2967 };
2968
2969 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2971 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2972
2973 let name_pkp = PKp::new(name_kp);
2975 let age_pkp = PKp::new(age_kp);
2976
2977 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Akash".to_string()));
2979 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2980
2981 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2983 assert_eq!(age_pkp.get_as::<String>(&user), None);
2984
2985 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2987 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2988 }
2989
2990 #[test]
2991 fn test_pkp_collection() {
2992 #[derive(Debug)]
2993 struct User {
2994 name: String,
2995 age: i32,
2996 }
2997
2998 let user = User {
2999 name: "Bob".to_string(),
3000 age: 25,
3001 };
3002
3003 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3005 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3006
3007 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
3008
3009 let name_value = keypaths[0].get_as::<String>(&user);
3011 let age_value = keypaths[1].get_as::<i32>(&user);
3012
3013 assert_eq!(name_value, Some(&"Bob".to_string()));
3014 assert_eq!(age_value, Some(&25));
3015 }
3016
3017 #[test]
3018 fn test_pkp_for_arc() {
3019 #[derive(Debug)]
3020 struct User {
3021 name: String,
3022 }
3023
3024 let user = Arc::new(User {
3025 name: "Charlie".to_string(),
3026 });
3027
3028 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3029 let name_pkp = PKp::new(name_kp);
3030
3031 let arc_pkp = name_pkp.for_arc();
3033
3034 assert_eq!(
3035 arc_pkp.get_as::<String>(&user),
3036 Some(&"Charlie".to_string())
3037 );
3038 }
3039
3040 #[test]
3041 fn test_pkp_for_option() {
3042 #[derive(Debug)]
3043 struct User {
3044 name: String,
3045 }
3046
3047 let some_user = Some(User {
3048 name: "Diana".to_string(),
3049 });
3050 let none_user: Option<User> = None;
3051
3052 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3053 let name_pkp = PKp::new(name_kp);
3054
3055 let opt_pkp = name_pkp.for_option();
3057
3058 assert_eq!(
3059 opt_pkp.get_as::<String>(&some_user),
3060 Some(&"Diana".to_string())
3061 );
3062 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
3063 }
3064
3065 #[test]
3066 fn test_akp_basic() {
3067 #[derive(Debug)]
3068 struct User {
3069 name: String,
3070 age: i32,
3071 }
3072
3073 #[derive(Debug)]
3074 struct Product {
3075 title: String,
3076 price: f64,
3077 }
3078
3079 let user = User {
3080 name: "Eve".to_string(),
3081 age: 28,
3082 };
3083
3084 let product = Product {
3085 title: "Book".to_string(),
3086 price: 19.99,
3087 };
3088
3089 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3091 let user_name_akp = AKp::new(user_name_kp);
3092
3093 let product_title_kp = KpType::new(
3094 |p: &Product| Some(&p.title),
3095 |p: &mut Product| Some(&mut p.title),
3096 );
3097 let product_title_akp = AKp::new(product_title_kp);
3098
3099 assert_eq!(
3101 user_name_akp.get_as::<User, String>(&user),
3102 Some(Some(&"Eve".to_string()))
3103 );
3104 assert_eq!(
3105 product_title_akp.get_as::<Product, String>(&product),
3106 Some(Some(&"Book".to_string()))
3107 );
3108
3109 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
3111 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
3112
3113 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
3115 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
3116 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
3117 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
3118 }
3119
3120 #[test]
3121 fn test_akp_heterogeneous_collection() {
3122 #[derive(Debug)]
3123 struct User {
3124 name: String,
3125 }
3126
3127 #[derive(Debug)]
3128 struct Product {
3129 title: String,
3130 }
3131
3132 let user = User {
3133 name: "Frank".to_string(),
3134 };
3135 let product = Product {
3136 title: "Laptop".to_string(),
3137 };
3138
3139 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3141 let product_title_kp = KpType::new(
3142 |p: &Product| Some(&p.title),
3143 |p: &mut Product| Some(&mut p.title),
3144 );
3145
3146 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
3147
3148 let user_any: &dyn Any = &user;
3150 let product_any: &dyn Any = &product;
3151
3152 let user_value = keypaths[0].get(user_any);
3153 let product_value = keypaths[1].get(product_any);
3154
3155 assert!(user_value.is_some());
3156 assert!(product_value.is_some());
3157
3158 assert_eq!(
3160 user_value.and_then(|v| v.downcast_ref::<String>()),
3161 Some(&"Frank".to_string())
3162 );
3163 assert_eq!(
3164 product_value.and_then(|v| v.downcast_ref::<String>()),
3165 Some(&"Laptop".to_string())
3166 );
3167 }
3168
3169 #[test]
3170 fn test_akp_for_option() {
3171 #[derive(Debug)]
3172 struct User {
3173 name: String,
3174 }
3175
3176 let some_user = Some(User {
3177 name: "Grace".to_string(),
3178 });
3179 let none_user: Option<User> = None;
3180
3181 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3182 let name_akp = AKp::new(name_kp);
3183
3184 let opt_akp = name_akp.for_option::<User>();
3186
3187 assert_eq!(
3188 opt_akp.get_as::<Option<User>, String>(&some_user),
3189 Some(Some(&"Grace".to_string()))
3190 );
3191 assert_eq!(
3192 opt_akp.get_as::<Option<User>, String>(&none_user),
3193 Some(None)
3194 );
3195 }
3196
3197 #[test]
3198 fn test_akp_for_result() {
3199 #[derive(Debug)]
3200 struct User {
3201 name: String,
3202 }
3203
3204 let ok_user: Result<User, String> = Ok(User {
3205 name: "Henry".to_string(),
3206 });
3207 let err_user: Result<User, String> = Err("Not found".to_string());
3208
3209 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3210 let name_akp = AKp::new(name_kp);
3211
3212 let result_akp = name_akp.for_result::<User, String>();
3214
3215 assert_eq!(
3216 result_akp.get_as::<Result<User, String>, String>(&ok_user),
3217 Some(Some(&"Henry".to_string()))
3218 );
3219 assert_eq!(
3220 result_akp.get_as::<Result<User, String>, String>(&err_user),
3221 Some(None)
3222 );
3223 }
3224
3225 #[test]
3228 fn test_kp_map() {
3229 #[derive(Debug)]
3230 struct User {
3231 name: String,
3232 age: i32,
3233 }
3234
3235 let user = User {
3236 name: "Akash".to_string(),
3237 age: 30,
3238 };
3239
3240 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3242 let len_kp = name_kp.map(|name: &String| name.len());
3243
3244 assert_eq!((len_kp.get)(&user), Some(5));
3245
3246 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3248 let double_age_kp = age_kp.map(|age: &i32| age * 2);
3249
3250 assert_eq!((double_age_kp.get)(&user), Some(60));
3251
3252 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
3254 assert_eq!((is_adult_kp.get)(&user), Some(true));
3255 }
3256
3257 #[test]
3258 fn test_kp_filter() {
3259 #[derive(Debug)]
3260 struct User {
3261 name: String,
3262 age: i32,
3263 }
3264
3265 let adult = User {
3266 name: "Akash".to_string(),
3267 age: 30,
3268 };
3269
3270 let minor = User {
3271 name: "Bob".to_string(),
3272 age: 15,
3273 };
3274
3275 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3276 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
3277
3278 assert_eq!((adult_age_kp.get)(&adult), Some(&30));
3279 assert_eq!((adult_age_kp.get)(&minor), None);
3280
3281 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3283 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
3284
3285 assert_eq!((short_name_kp.get)(&minor), Some(&"Bob".to_string()));
3286 assert_eq!((short_name_kp.get)(&adult), None);
3287 }
3288
3289 #[test]
3290 fn test_kp_map_and_filter() {
3291 #[derive(Debug)]
3292 struct User {
3293 scores: Vec<i32>,
3294 }
3295
3296 let user = User {
3297 scores: vec![85, 92, 78, 95],
3298 };
3299
3300 let scores_kp = KpType::new(
3301 |u: &User| Some(&u.scores),
3302 |u: &mut User| Some(&mut u.scores),
3303 );
3304
3305 let avg_kp =
3307 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3308
3309 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
3311
3312 assert_eq!((high_avg_kp.get)(&user), Some(87)); }
3314
3315 #[test]
3316 fn test_enum_kp_map() {
3317 let ok_result: Result<String, i32> = Ok("hello".to_string());
3318 let err_result: Result<String, i32> = Err(42);
3319
3320 let ok_kp = enum_ok::<String, i32>();
3321 let len_kp = ok_kp.map(|s: &String| s.len());
3322
3323 assert_eq!(len_kp.get(&ok_result), Some(5));
3324 assert_eq!(len_kp.get(&err_result), None);
3325
3326 let some_opt = Some(vec![1, 2, 3, 4, 5]);
3328 let none_opt: Option<Vec<i32>> = None;
3329
3330 let some_kp = enum_some::<Vec<i32>>();
3331 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
3332
3333 assert_eq!(count_kp.get(&some_opt), Some(5));
3334 assert_eq!(count_kp.get(&none_opt), None);
3335 }
3336
3337 #[test]
3338 fn test_enum_kp_filter() {
3339 let ok_result1: Result<i32, String> = Ok(42);
3340 let ok_result2: Result<i32, String> = Ok(-5);
3341 let err_result: Result<i32, String> = Err("error".to_string());
3342
3343 let ok_kp = enum_ok::<i32, String>();
3344 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
3345
3346 assert_eq!((positive_kp.extractor.get)(&ok_result1), Some(&42));
3347 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
3352 let short_str = Some("hi".to_string());
3353
3354 let some_kp = enum_some::<String>();
3355 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
3356
3357 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
3358 assert_eq!(long_kp.get(&short_str), None);
3359 }
3360
3361 #[test]
3362 fn test_pkp_filter() {
3363 #[derive(Debug)]
3364 struct User {
3365 name: String,
3366 age: i32,
3367 }
3368
3369 let adult = User {
3370 name: "Akash".to_string(),
3371 age: 30,
3372 };
3373
3374 let minor = User {
3375 name: "Bob".to_string(),
3376 age: 15,
3377 };
3378
3379 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3380 let age_pkp = PKp::new(age_kp);
3381
3382 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
3384
3385 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
3386 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
3387
3388 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3390 let name_pkp = PKp::new(name_kp);
3391 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
3392
3393 assert_eq!(
3394 short_name_pkp.get_as::<String>(&minor),
3395 Some(&"Bob".to_string())
3396 );
3397 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
3398 }
3399
3400 #[test]
3401 fn test_akp_filter() {
3402 #[derive(Debug)]
3403 struct User {
3404 age: i32,
3405 }
3406
3407 #[derive(Debug)]
3408 struct Product {
3409 price: f64,
3410 }
3411
3412 let adult = User { age: 30 };
3413 let minor = User { age: 15 };
3414 let expensive = Product { price: 99.99 };
3415 let cheap = Product { price: 5.0 };
3416
3417 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3419 let age_akp = AKp::new(age_kp);
3420 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
3421
3422 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
3423 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
3424
3425 let price_kp = KpType::new(
3427 |p: &Product| Some(&p.price),
3428 |p: &mut Product| Some(&mut p.price),
3429 );
3430 let price_akp = AKp::new(price_kp);
3431 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
3432
3433 assert_eq!(
3434 expensive_akp.get_as::<Product, f64>(&expensive),
3435 Some(Some(&99.99))
3436 );
3437 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
3438 }
3439
3440 #[test]
3443 fn test_kp_filter_map() {
3444 #[derive(Debug)]
3445 struct User {
3446 middle_name: Option<String>,
3447 }
3448
3449 let user_with = User {
3450 middle_name: Some("Marie".to_string()),
3451 };
3452 let user_without = User { middle_name: None };
3453
3454 let middle_kp = KpType::new(
3455 |u: &User| Some(&u.middle_name),
3456 |u: &mut User| Some(&mut u.middle_name),
3457 );
3458
3459 let first_char_kp = middle_kp
3460 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
3461
3462 assert_eq!((first_char_kp.get)(&user_with), Some('M'));
3463 assert_eq!((first_char_kp.get)(&user_without), None);
3464 }
3465
3466 #[test]
3467 fn test_kp_inspect() {
3468 #[derive(Debug)]
3469 struct User {
3470 name: String,
3471 }
3472
3473 let user = User {
3474 name: "Akash".to_string(),
3475 };
3476
3477 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3481
3482 let result = (name_kp.get)(&user);
3485 assert_eq!(result, Some(&"Akash".to_string()));
3486
3487 }
3490
3491 #[test]
3492 fn test_kp_fold_value() {
3493 #[derive(Debug)]
3494 struct User {
3495 scores: Vec<i32>,
3496 }
3497
3498 let user = User {
3499 scores: vec![85, 92, 78, 95],
3500 };
3501
3502 let scores_kp = KpType::new(
3503 |u: &User| Some(&u.scores),
3504 |u: &mut User| Some(&mut u.scores),
3505 );
3506
3507 let sum_fn =
3509 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
3510
3511 assert_eq!(sum_fn(&user), 350);
3512 }
3513
3514 #[test]
3515 fn test_kp_any_all() {
3516 #[derive(Debug)]
3517 struct User {
3518 scores: Vec<i32>,
3519 }
3520
3521 let user_high = User {
3522 scores: vec![85, 92, 88],
3523 };
3524 let user_mixed = User {
3525 scores: vec![65, 92, 78],
3526 };
3527
3528 let scores_kp = KpType::new(
3529 |u: &User| Some(&u.scores),
3530 |u: &mut User| Some(&mut u.scores),
3531 );
3532
3533 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
3535 assert!(has_high_fn(&user_high));
3536 assert!(has_high_fn(&user_mixed));
3537
3538 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
3540 assert!(all_passing_fn(&user_high));
3541 assert!(!all_passing_fn(&user_mixed));
3542 }
3543
3544 #[test]
3545 fn test_kp_count_items() {
3546 #[derive(Debug)]
3547 struct User {
3548 tags: Vec<String>,
3549 }
3550
3551 let user = User {
3552 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
3553 };
3554
3555 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3556 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
3557
3558 assert_eq!(count_fn(&user), Some(3));
3559 }
3560
3561 #[test]
3562 fn test_kp_find_in() {
3563 #[derive(Debug)]
3564 struct User {
3565 scores: Vec<i32>,
3566 }
3567
3568 let user = User {
3569 scores: vec![85, 92, 78, 95, 88],
3570 };
3571
3572 let scores_kp = KpType::new(
3573 |u: &User| Some(&u.scores),
3574 |u: &mut User| Some(&mut u.scores),
3575 );
3576
3577 let first_high_fn =
3579 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3580
3581 assert_eq!(first_high_fn(&user), Some(92));
3582
3583 let perfect_fn =
3585 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3586
3587 assert_eq!(perfect_fn(&user), None);
3588 }
3589
3590 #[test]
3591 fn test_kp_take_skip() {
3592 #[derive(Debug)]
3593 struct User {
3594 tags: Vec<String>,
3595 }
3596
3597 let user = User {
3598 tags: vec![
3599 "a".to_string(),
3600 "b".to_string(),
3601 "c".to_string(),
3602 "d".to_string(),
3603 ],
3604 };
3605
3606 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3607
3608 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3610 tags.iter().take(n).cloned().collect::<Vec<_>>()
3611 });
3612
3613 let taken = take_fn(&user).unwrap();
3614 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3615
3616 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3618 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3619 });
3620
3621 let skipped = skip_fn(&user).unwrap();
3622 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3623 }
3624
3625 #[test]
3626 fn test_kp_partition() {
3627 #[derive(Debug)]
3628 struct User {
3629 scores: Vec<i32>,
3630 }
3631
3632 let user = User {
3633 scores: vec![85, 92, 65, 95, 72, 58],
3634 };
3635
3636 let scores_kp = KpType::new(
3637 |u: &User| Some(&u.scores),
3638 |u: &mut User| Some(&mut u.scores),
3639 );
3640
3641 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3642 scores.iter().copied().partition(|&s| s >= 70)
3643 });
3644
3645 let (passing, failing) = partition_fn(&user).unwrap();
3646 assert_eq!(passing, vec![85, 92, 95, 72]);
3647 assert_eq!(failing, vec![65, 58]);
3648 }
3649
3650 #[test]
3651 fn test_kp_min_max() {
3652 #[derive(Debug)]
3653 struct User {
3654 scores: Vec<i32>,
3655 }
3656
3657 let user = User {
3658 scores: vec![85, 92, 78, 95, 88],
3659 };
3660
3661 let scores_kp = KpType::new(
3662 |u: &User| Some(&u.scores),
3663 |u: &mut User| Some(&mut u.scores),
3664 );
3665
3666 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3668 assert_eq!(min_fn(&user), Some(78));
3669
3670 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3672 assert_eq!(max_fn(&user), Some(95));
3673 }
3674
3675 #[test]
3676 fn test_kp_sum() {
3677 #[derive(Debug)]
3678 struct User {
3679 scores: Vec<i32>,
3680 }
3681
3682 let user = User {
3683 scores: vec![85, 92, 78],
3684 };
3685
3686 let scores_kp = KpType::new(
3687 |u: &User| Some(&u.scores),
3688 |u: &mut User| Some(&mut u.scores),
3689 );
3690
3691 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3692 assert_eq!(sum_fn(&user), Some(255));
3693
3694 let avg_fn =
3696 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3697 assert_eq!(avg_fn.get(&user), Some(85));
3698 }
3699
3700 #[test]
3701 fn test_kp_chain() {
3702 #[derive(Debug)]
3703 struct User {
3704 profile: Profile,
3705 }
3706
3707 #[derive(Debug)]
3708 struct Profile {
3709 settings: Settings,
3710 }
3711
3712 #[derive(Debug)]
3713 struct Settings {
3714 theme: String,
3715 }
3716
3717 let user = User {
3718 profile: Profile {
3719 settings: Settings {
3720 theme: "dark".to_string(),
3721 },
3722 },
3723 };
3724
3725 let profile_kp = KpType::new(
3726 |u: &User| Some(&u.profile),
3727 |u: &mut User| Some(&mut u.profile),
3728 );
3729 let settings_kp = KpType::new(
3730 |p: &Profile| Some(&p.settings),
3731 |p: &mut Profile| Some(&mut p.settings),
3732 );
3733 let theme_kp = KpType::new(
3734 |s: &Settings| Some(&s.theme),
3735 |s: &mut Settings| Some(&mut s.theme),
3736 );
3737
3738 let profile_settings = profile_kp.then(settings_kp);
3740 let theme_path = profile_settings.then(theme_kp);
3741 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3742 }
3743
3744 #[test]
3745 fn test_kp_zip() {
3746 #[derive(Debug)]
3747 struct User {
3748 name: String,
3749 age: i32,
3750 }
3751
3752 let user = User {
3753 name: "Akash".to_string(),
3754 age: 30,
3755 };
3756
3757 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3758 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3759
3760 let zipped_fn = zip_kps(&name_kp, &age_kp);
3761 let result = zipped_fn(&user);
3762
3763 assert_eq!(result, Some((&"Akash".to_string(), &30)));
3764 }
3765
3766 #[test]
3767 fn test_kp_complex_pipeline() {
3768 #[derive(Debug)]
3769 struct User {
3770 transactions: Vec<Transaction>,
3771 }
3772
3773 #[derive(Debug)]
3774 struct Transaction {
3775 amount: f64,
3776 category: String,
3777 }
3778
3779 let user = User {
3780 transactions: vec![
3781 Transaction {
3782 amount: 50.0,
3783 category: "food".to_string(),
3784 },
3785 Transaction {
3786 amount: 100.0,
3787 category: "transport".to_string(),
3788 },
3789 Transaction {
3790 amount: 25.0,
3791 category: "food".to_string(),
3792 },
3793 Transaction {
3794 amount: 200.0,
3795 category: "shopping".to_string(),
3796 },
3797 ],
3798 };
3799
3800 let txns_kp = KpType::new(
3801 |u: &User| Some(&u.transactions),
3802 |u: &mut User| Some(&mut u.transactions),
3803 );
3804
3805 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3807 txns.iter()
3808 .filter(|t| t.category == "food")
3809 .map(|t| t.amount)
3810 .sum::<f64>()
3811 });
3812
3813 assert_eq!(food_total.get(&user), Some(75.0));
3814
3815 let has_large =
3817 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3818
3819 assert!(has_large(&user));
3820
3821 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3823 assert_eq!(count(&user), Some(4));
3824 }
3825
3826 #[test]
3830 fn test_no_clone_required_for_root() {
3831 use std::sync::Arc;
3832 use std::sync::atomic::{AtomicUsize, Ordering};
3833
3834 struct NonCloneableRoot {
3837 data: Arc<AtomicUsize>,
3838 cached_value: usize,
3839 }
3840
3841 impl NonCloneableRoot {
3842 fn new() -> Self {
3843 Self {
3844 data: Arc::new(AtomicUsize::new(42)),
3845 cached_value: 42,
3846 }
3847 }
3848
3849 fn increment(&mut self) {
3850 self.data.fetch_add(1, Ordering::SeqCst);
3851 self.cached_value = self.data.load(Ordering::SeqCst);
3852 }
3853
3854 fn get_value(&self) -> &usize {
3855 &self.cached_value
3856 }
3857
3858 fn get_value_mut(&mut self) -> &mut usize {
3859 &mut self.cached_value
3860 }
3861 }
3862
3863 let mut root = NonCloneableRoot::new();
3864
3865 let data_kp = KpType::new(
3867 |r: &NonCloneableRoot| Some(r.get_value()),
3868 |r: &mut NonCloneableRoot| {
3869 r.increment();
3870 Some(r.get_value_mut())
3871 },
3872 );
3873
3874 assert_eq!(data_kp.get(&root), Some(&42));
3876
3877 {
3878 let doubled = data_kp.map(|val: &usize| val * 2);
3880 assert_eq!(doubled.get(&root), Some(84));
3881
3882 let filtered = data_kp.filter(|val: &usize| *val > 0);
3884 assert_eq!(filtered.get(&root), Some(&42));
3885 } let value_ref = data_kp.get_mut(&mut root);
3889 assert!(value_ref.is_some());
3890 }
3891
3892 #[test]
3893 fn test_no_clone_required_for_value() {
3894 use std::sync::Arc;
3895 use std::sync::atomic::{AtomicUsize, Ordering};
3896
3897 struct NonCloneableValue {
3899 counter: Arc<AtomicUsize>,
3900 }
3901
3902 impl NonCloneableValue {
3903 fn new(val: usize) -> Self {
3904 Self {
3905 counter: Arc::new(AtomicUsize::new(val)),
3906 }
3907 }
3908
3909 fn get(&self) -> usize {
3910 self.counter.load(Ordering::SeqCst)
3911 }
3912 }
3913
3914 struct Root {
3915 value: NonCloneableValue,
3916 }
3917
3918 let root = Root {
3919 value: NonCloneableValue::new(100),
3920 };
3921
3922 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3924
3925 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3927 assert_eq!(counter_kp.get(&root), Some(100));
3928
3929 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3931 assert!(filtered.get(&root).is_some());
3932 }
3933
3934 #[test]
3935 fn test_static_does_not_leak_memory() {
3936 use std::sync::Arc;
3937 use std::sync::atomic::{AtomicUsize, Ordering};
3938
3939 static CREATED: AtomicUsize = AtomicUsize::new(0);
3941 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3942
3943 struct Tracked {
3944 id: usize,
3945 }
3946
3947 impl Tracked {
3948 fn new() -> Self {
3949 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3950 Self { id }
3951 }
3952 }
3953
3954 impl Drop for Tracked {
3955 fn drop(&mut self) {
3956 DROPPED.fetch_add(1, Ordering::SeqCst);
3957 }
3958 }
3959
3960 struct Root {
3961 data: Tracked,
3962 }
3963
3964 CREATED.store(0, Ordering::SeqCst);
3966 DROPPED.store(0, Ordering::SeqCst);
3967
3968 {
3969 let root = Root {
3970 data: Tracked::new(),
3971 };
3972
3973 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3974
3975 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3977 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3978 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3979
3980 assert_eq!(mapped1.get(&root), Some(0));
3981 assert_eq!(mapped2.get(&root), Some(1));
3982 assert_eq!(mapped3.get(&root), Some(2));
3983
3984 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3986 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3987 }
3988
3989 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3991 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3992
3993 }
3995
3996 #[test]
3997 fn test_references_not_cloned() {
3998 use std::sync::Arc;
3999
4000 struct ExpensiveData {
4002 large_vec: Vec<u8>,
4003 }
4004
4005 impl ExpensiveData {
4006 fn new(size: usize) -> Self {
4007 Self {
4008 large_vec: vec![0u8; size],
4009 }
4010 }
4011
4012 fn size(&self) -> usize {
4013 self.large_vec.len()
4014 }
4015 }
4016
4017 struct Root {
4018 expensive: ExpensiveData,
4019 }
4020
4021 let root = Root {
4022 expensive: ExpensiveData::new(1_000_000), };
4024
4025 let expensive_kp = KpType::new(
4026 |r: &Root| Some(&r.expensive),
4027 |r: &mut Root| Some(&mut r.expensive),
4028 );
4029
4030 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
4032 assert_eq!(size_kp.get(&root), Some(1_000_000));
4033
4034 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
4036 assert!(large_filter.get(&root).is_some());
4037
4038 }
4040
4041 #[test]
4042 fn test_hof_with_arc_no_extra_clones() {
4043 use std::sync::Arc;
4044
4045 #[derive(Debug)]
4046 struct SharedData {
4047 value: String,
4048 }
4049
4050 struct Root {
4051 shared: Arc<SharedData>,
4052 }
4053
4054 let shared = Arc::new(SharedData {
4055 value: "shared".to_string(),
4056 });
4057
4058 assert_eq!(Arc::strong_count(&shared), 1);
4060
4061 {
4062 let root = Root {
4063 shared: Arc::clone(&shared),
4064 };
4065
4066 assert_eq!(Arc::strong_count(&shared), 2);
4068
4069 let shared_kp = KpType::new(
4070 |r: &Root| Some(&r.shared),
4071 |r: &mut Root| Some(&mut r.shared),
4072 );
4073
4074 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
4076
4077 assert_eq!(value_kp.get(&root), Some(6));
4079 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
4083 assert!(filtered.get(&root).is_some());
4084 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
4089
4090 #[test]
4091 fn test_closure_captures_not_root_values() {
4092 use std::sync::Arc;
4093 use std::sync::atomic::{AtomicUsize, Ordering};
4094
4095 let call_count = Arc::new(AtomicUsize::new(0));
4097 let call_count_clone = Arc::clone(&call_count);
4098
4099 struct Root {
4100 value: i32,
4101 }
4102
4103 let root = Root { value: 42 };
4104
4105 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4106
4107 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
4110 call_count_clone.fetch_add(1, Ordering::SeqCst);
4111 v * 2
4112 });
4113
4114 assert_eq!(doubled(&root), 84);
4116 assert_eq!(doubled(&root), 84);
4117 assert_eq!(doubled(&root), 84);
4118
4119 assert_eq!(call_count.load(Ordering::SeqCst), 3);
4121
4122 }
4124
4125 #[test]
4126 fn test_static_with_borrowed_data() {
4127 struct Root {
4131 data: String,
4132 }
4133
4134 {
4135 let root = Root {
4136 data: "temporary".to_string(),
4137 };
4138
4139 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4140
4141 let len_kp = data_kp.map(|s: &String| s.len());
4143 assert_eq!(len_kp.get(&root), Some(9));
4144
4145 } }
4150
4151 #[test]
4152 fn test_multiple_hof_operations_no_accumulation() {
4153 use std::sync::Arc;
4154 use std::sync::atomic::{AtomicUsize, Ordering};
4155
4156 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
4157
4158 struct Tracked {
4159 id: usize,
4160 }
4161
4162 impl Drop for Tracked {
4163 fn drop(&mut self) {
4164 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4165 }
4166 }
4167
4168 struct Root {
4169 values: Vec<Tracked>,
4170 }
4171
4172 DROP_COUNT.store(0, Ordering::SeqCst);
4173
4174 {
4175 let root = Root {
4176 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
4177 };
4178
4179 let values_kp = KpType::new(
4180 |r: &Root| Some(&r.values),
4181 |r: &mut Root| Some(&mut r.values),
4182 );
4183
4184 let count = values_kp.count_items(|v| v.len());
4186 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
4187 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
4188 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
4189
4190 assert_eq!(count(&root), Some(3));
4191 assert_eq!(sum(&root), Some(6));
4192 assert!(has_2(&root));
4193 assert!(all_positive(&root));
4194
4195 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4197 }
4198
4199 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
4201 }
4202
4203 #[test]
4204 fn test_copy_bound_only_for_function_not_data() {
4205 #[derive(Debug)]
4209 struct NonCopyData {
4210 value: String,
4211 }
4212
4213 struct Root {
4214 data: NonCopyData,
4215 }
4216
4217 let root = Root {
4218 data: NonCopyData {
4219 value: "test".to_string(),
4220 },
4221 };
4222
4223 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4224
4225 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
4228 assert_eq!(len_kp.get(&root), Some(4));
4229
4230 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
4232 assert!(filtered.get(&root).is_some());
4233 }
4234
4235 #[test]
4236 fn test_no_memory_leak_with_cyclic_references() {
4237 use std::sync::atomic::{AtomicUsize, Ordering};
4238 use std::sync::{Arc, Weak};
4239
4240 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
4241
4242 struct Node {
4243 id: usize,
4244 parent: Option<Weak<Node>>,
4245 }
4246
4247 impl Drop for Node {
4248 fn drop(&mut self) {
4249 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4250 }
4251 }
4252
4253 struct Root {
4254 node: Arc<Node>,
4255 }
4256
4257 DROP_COUNT.store(0, Ordering::SeqCst);
4258
4259 {
4260 let root = Root {
4261 node: Arc::new(Node {
4262 id: 1,
4263 parent: None,
4264 }),
4265 };
4266
4267 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
4268
4269 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
4271 assert_eq!(id_kp.get(&root), Some(1));
4272
4273 assert_eq!(Arc::strong_count(&root.node), 1);
4275
4276 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4278 }
4279
4280 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
4282 }
4283
4284 #[test]
4285 fn test_hof_operations_are_zero_cost_abstractions() {
4286 struct Root {
4290 value: i32,
4291 }
4292
4293 let root = Root { value: 10 };
4294
4295 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4296
4297 let direct_result = value_kp.get(&root).map(|v| v * 2);
4299 assert_eq!(direct_result, Some(20));
4300
4301 let mapped_kp = value_kp.map(|v: &i32| v * 2);
4303 let hof_result = mapped_kp.get(&root);
4304 assert_eq!(hof_result, Some(20));
4305
4306 assert_eq!(direct_result, hof_result);
4308 }
4309
4310 #[test]
4311 fn test_complex_closure_captures_allowed() {
4312 use std::sync::Arc;
4313
4314 struct Root {
4316 scores: Vec<i32>,
4317 }
4318
4319 let root = Root {
4320 scores: vec![85, 92, 78, 95, 88],
4321 };
4322
4323 let scores_kp = KpType::new(
4324 |r: &Root| Some(&r.scores),
4325 |r: &mut Root| Some(&mut r.scores),
4326 );
4327
4328 let threshold = 90;
4330 let multiplier = Arc::new(2);
4331
4332 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
4334 let high: i32 = scores
4335 .iter()
4336 .filter(|&&s| s >= threshold)
4337 .map(|&s| s * *multiplier)
4338 .sum();
4339 acc + high
4340 });
4341
4342 assert_eq!(high_scores_doubled(&root), 374);
4344 }
4345
4346 #[test]
4350 fn test_pkp_filter_by_value_type() {
4351 use std::any::TypeId;
4352
4353 #[derive(Debug)]
4354 struct User {
4355 name: String,
4356 age: i32,
4357 score: f64,
4358 active: bool,
4359 }
4360
4361 let user = User {
4362 name: "Akash".to_string(),
4363 age: 30,
4364 score: 95.5,
4365 active: true,
4366 };
4367
4368 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4370 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4371 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
4372 let active_kp = KpType::new(
4373 |u: &User| Some(&u.active),
4374 |u: &mut User| Some(&mut u.active),
4375 );
4376
4377 let all_keypaths: Vec<PKp<User>> = vec![
4379 PKp::new(name_kp),
4380 PKp::new(age_kp),
4381 PKp::new(score_kp),
4382 PKp::new(active_kp),
4383 ];
4384
4385 let string_kps: Vec<_> = all_keypaths
4387 .iter()
4388 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
4389 .collect();
4390
4391 assert_eq!(string_kps.len(), 1);
4392 assert_eq!(
4393 string_kps[0].get_as::<String>(&user),
4394 Some(&"Akash".to_string())
4395 );
4396
4397 let i32_kps: Vec<_> = all_keypaths
4399 .iter()
4400 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
4401 .collect();
4402
4403 assert_eq!(i32_kps.len(), 1);
4404 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
4405
4406 let f64_kps: Vec<_> = all_keypaths
4408 .iter()
4409 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
4410 .collect();
4411
4412 assert_eq!(f64_kps.len(), 1);
4413 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
4414
4415 let bool_kps: Vec<_> = all_keypaths
4417 .iter()
4418 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
4419 .collect();
4420
4421 assert_eq!(bool_kps.len(), 1);
4422 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
4423 }
4424
4425 #[test]
4426 fn test_pkp_filter_by_struct_type() {
4427 use std::any::TypeId;
4428
4429 #[derive(Debug, PartialEq)]
4430 struct Address {
4431 street: String,
4432 city: String,
4433 }
4434
4435 #[derive(Debug)]
4436 struct User {
4437 name: String,
4438 age: i32,
4439 address: Address,
4440 }
4441
4442 let user = User {
4443 name: "Bob".to_string(),
4444 age: 25,
4445 address: Address {
4446 street: "123 Main St".to_string(),
4447 city: "NYC".to_string(),
4448 },
4449 };
4450
4451 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4453 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4454 let address_kp = KpType::new(
4455 |u: &User| Some(&u.address),
4456 |u: &mut User| Some(&mut u.address),
4457 );
4458
4459 let all_keypaths: Vec<PKp<User>> =
4460 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
4461
4462 let struct_kps: Vec<_> = all_keypaths
4464 .iter()
4465 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
4466 .collect();
4467
4468 assert_eq!(struct_kps.len(), 1);
4469 assert_eq!(
4470 struct_kps[0].get_as::<Address>(&user),
4471 Some(&Address {
4472 street: "123 Main St".to_string(),
4473 city: "NYC".to_string(),
4474 })
4475 );
4476
4477 let primitive_kps: Vec<_> = all_keypaths
4479 .iter()
4480 .filter(|pkp| {
4481 pkp.value_type_id() == TypeId::of::<String>()
4482 || pkp.value_type_id() == TypeId::of::<i32>()
4483 })
4484 .collect();
4485
4486 assert_eq!(primitive_kps.len(), 2);
4487 }
4488
4489 #[test]
4490 fn test_pkp_filter_by_arc_type() {
4491 use std::any::TypeId;
4492 use std::sync::Arc;
4493
4494 #[derive(Debug)]
4495 struct User {
4496 name: String,
4497 shared_data: Arc<String>,
4498 shared_number: Arc<i32>,
4499 }
4500
4501 let user = User {
4502 name: "Charlie".to_string(),
4503 shared_data: Arc::new("shared".to_string()),
4504 shared_number: Arc::new(42),
4505 };
4506
4507 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4509 let shared_data_kp = KpType::new(
4510 |u: &User| Some(&u.shared_data),
4511 |u: &mut User| Some(&mut u.shared_data),
4512 );
4513 let shared_number_kp = KpType::new(
4514 |u: &User| Some(&u.shared_number),
4515 |u: &mut User| Some(&mut u.shared_number),
4516 );
4517
4518 let all_keypaths: Vec<PKp<User>> = vec![
4519 PKp::new(name_kp),
4520 PKp::new(shared_data_kp),
4521 PKp::new(shared_number_kp),
4522 ];
4523
4524 let arc_string_kps: Vec<_> = all_keypaths
4526 .iter()
4527 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
4528 .collect();
4529
4530 assert_eq!(arc_string_kps.len(), 1);
4531 assert_eq!(
4532 arc_string_kps[0]
4533 .get_as::<Arc<String>>(&user)
4534 .map(|arc| arc.as_str()),
4535 Some("shared")
4536 );
4537
4538 let arc_i32_kps: Vec<_> = all_keypaths
4540 .iter()
4541 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
4542 .collect();
4543
4544 assert_eq!(arc_i32_kps.len(), 1);
4545 assert_eq!(
4546 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
4547 Some(42)
4548 );
4549
4550 let all_arc_kps: Vec<_> = all_keypaths
4552 .iter()
4553 .filter(|pkp| {
4554 pkp.value_type_id() == TypeId::of::<Arc<String>>()
4555 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
4556 })
4557 .collect();
4558
4559 assert_eq!(all_arc_kps.len(), 2);
4560 }
4561
4562 #[test]
4563 fn test_pkp_filter_by_box_type() {
4564 use std::any::TypeId;
4565
4566 #[derive(Debug)]
4567 struct User {
4568 name: String,
4569 boxed_value: Box<i32>,
4570 boxed_string: Box<String>,
4571 }
4572
4573 let user = User {
4574 name: "Diana".to_string(),
4575 boxed_value: Box::new(100),
4576 boxed_string: Box::new("boxed".to_string()),
4577 };
4578
4579 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4581 let boxed_value_kp = KpType::new(
4582 |u: &User| Some(&u.boxed_value),
4583 |u: &mut User| Some(&mut u.boxed_value),
4584 );
4585 let boxed_string_kp = KpType::new(
4586 |u: &User| Some(&u.boxed_string),
4587 |u: &mut User| Some(&mut u.boxed_string),
4588 );
4589
4590 let all_keypaths: Vec<PKp<User>> = vec![
4591 PKp::new(name_kp),
4592 PKp::new(boxed_value_kp),
4593 PKp::new(boxed_string_kp),
4594 ];
4595
4596 let box_i32_kps: Vec<_> = all_keypaths
4598 .iter()
4599 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4600 .collect();
4601
4602 assert_eq!(box_i32_kps.len(), 1);
4603 assert_eq!(
4604 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4605 Some(100)
4606 );
4607
4608 let box_string_kps: Vec<_> = all_keypaths
4610 .iter()
4611 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4612 .collect();
4613
4614 assert_eq!(box_string_kps.len(), 1);
4615 assert_eq!(
4616 box_string_kps[0]
4617 .get_as::<Box<String>>(&user)
4618 .map(|b| b.as_str()),
4619 Some("boxed")
4620 );
4621 }
4622
4623 #[test]
4624 fn test_akp_filter_by_root_and_value_type() {
4625 use std::any::TypeId;
4626
4627 #[derive(Debug)]
4628 struct User {
4629 name: String,
4630 age: i32,
4631 }
4632
4633 #[derive(Debug)]
4634 struct Product {
4635 title: String,
4636 price: f64,
4637 }
4638
4639 let user = User {
4640 name: "Eve".to_string(),
4641 age: 28,
4642 };
4643
4644 let product = Product {
4645 title: "Book".to_string(),
4646 price: 19.99,
4647 };
4648
4649 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4651 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4652 let product_title_kp = KpType::new(
4653 |p: &Product| Some(&p.title),
4654 |p: &mut Product| Some(&mut p.title),
4655 );
4656 let product_price_kp = KpType::new(
4657 |p: &Product| Some(&p.price),
4658 |p: &mut Product| Some(&mut p.price),
4659 );
4660
4661 let all_keypaths: Vec<AKp> = vec![
4662 AKp::new(user_name_kp),
4663 AKp::new(user_age_kp),
4664 AKp::new(product_title_kp),
4665 AKp::new(product_price_kp),
4666 ];
4667
4668 let user_kps: Vec<_> = all_keypaths
4670 .iter()
4671 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4672 .collect();
4673
4674 assert_eq!(user_kps.len(), 2);
4675
4676 let product_kps: Vec<_> = all_keypaths
4678 .iter()
4679 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4680 .collect();
4681
4682 assert_eq!(product_kps.len(), 2);
4683
4684 let string_value_kps: Vec<_> = all_keypaths
4686 .iter()
4687 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4688 .collect();
4689
4690 assert_eq!(string_value_kps.len(), 2);
4691
4692 let user_string_kps: Vec<_> = all_keypaths
4694 .iter()
4695 .filter(|akp| {
4696 akp.root_type_id() == TypeId::of::<User>()
4697 && akp.value_type_id() == TypeId::of::<String>()
4698 })
4699 .collect();
4700
4701 assert_eq!(user_string_kps.len(), 1);
4702 assert_eq!(
4703 user_string_kps[0].get_as::<User, String>(&user),
4704 Some(Some(&"Eve".to_string()))
4705 );
4706
4707 let product_f64_kps: Vec<_> = all_keypaths
4709 .iter()
4710 .filter(|akp| {
4711 akp.root_type_id() == TypeId::of::<Product>()
4712 && akp.value_type_id() == TypeId::of::<f64>()
4713 })
4714 .collect();
4715
4716 assert_eq!(product_f64_kps.len(), 1);
4717 assert_eq!(
4718 product_f64_kps[0].get_as::<Product, f64>(&product),
4719 Some(Some(&19.99))
4720 );
4721 }
4722
4723 #[test]
4724 fn test_akp_filter_by_arc_root_type() {
4725 use std::any::TypeId;
4726 use std::sync::Arc;
4727
4728 #[derive(Debug)]
4729 struct User {
4730 name: String,
4731 }
4732
4733 #[derive(Debug)]
4734 struct Product {
4735 title: String,
4736 }
4737
4738 let user = User {
4739 name: "Frank".to_string(),
4740 };
4741 let product = Product {
4742 title: "Laptop".to_string(),
4743 };
4744
4745 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4747 let product_title_kp = KpType::new(
4748 |p: &Product| Some(&p.title),
4749 |p: &mut Product| Some(&mut p.title),
4750 );
4751
4752 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4754 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4755
4756 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4757
4758 let arc_user_kps: Vec<_> = all_keypaths
4760 .iter()
4761 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4762 .collect();
4763
4764 assert_eq!(arc_user_kps.len(), 1);
4765
4766 let arc_user = Arc::new(user);
4768 assert_eq!(
4769 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4770 Some(Some(&"Frank".to_string()))
4771 );
4772
4773 let arc_product_kps: Vec<_> = all_keypaths
4775 .iter()
4776 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4777 .collect();
4778
4779 assert_eq!(arc_product_kps.len(), 1);
4780
4781 let arc_product = Arc::new(product);
4783 assert_eq!(
4784 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4785 Some(Some(&"Laptop".to_string()))
4786 );
4787 }
4788
4789 #[test]
4790 fn test_akp_filter_by_box_root_type() {
4791 use std::any::TypeId;
4792
4793 #[derive(Debug)]
4794 struct Config {
4795 setting: String,
4796 }
4797
4798 let config = Config {
4799 setting: "enabled".to_string(),
4800 };
4801
4802 let config_kp1 = KpType::new(
4804 |c: &Config| Some(&c.setting),
4805 |c: &mut Config| Some(&mut c.setting),
4806 );
4807 let config_kp2 = KpType::new(
4808 |c: &Config| Some(&c.setting),
4809 |c: &mut Config| Some(&mut c.setting),
4810 );
4811
4812 let regular_akp = AKp::new(config_kp1);
4814 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4815
4816 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4817
4818 let config_kps: Vec<_> = all_keypaths
4820 .iter()
4821 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4822 .collect();
4823
4824 assert_eq!(config_kps.len(), 1);
4825 assert_eq!(
4826 config_kps[0].get_as::<Config, String>(&config),
4827 Some(Some(&"enabled".to_string()))
4828 );
4829
4830 let box_config_kps: Vec<_> = all_keypaths
4832 .iter()
4833 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4834 .collect();
4835
4836 assert_eq!(box_config_kps.len(), 1);
4837
4838 let box_config = Box::new(Config {
4840 setting: "enabled".to_string(),
4841 });
4842 assert_eq!(
4843 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4844 Some(Some(&"enabled".to_string()))
4845 );
4846 }
4847
4848 #[test]
4849 fn test_mixed_collection_type_filtering() {
4850 use std::any::TypeId;
4851 use std::sync::Arc;
4852
4853 #[derive(Debug)]
4854 struct User {
4855 name: String,
4856 email: String,
4857 }
4858
4859 #[derive(Debug)]
4860 struct Product {
4861 title: String,
4862 sku: String,
4863 }
4864
4865 let user = User {
4866 name: "Grace".to_string(),
4867 email: "grace@example.com".to_string(),
4868 };
4869
4870 let product = Product {
4871 title: "Widget".to_string(),
4872 sku: "WID-001".to_string(),
4873 };
4874
4875 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4877 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4878 let user_email_kp1 =
4879 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4880 let user_email_kp2 =
4881 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4882 let product_title_kp = KpType::new(
4883 |p: &Product| Some(&p.title),
4884 |p: &mut Product| Some(&mut p.title),
4885 );
4886 let product_sku_kp = KpType::new(
4887 |p: &Product| Some(&p.sku),
4888 |p: &mut Product| Some(&mut p.sku),
4889 );
4890
4891 let all_keypaths: Vec<AKp> = vec![
4892 AKp::new(user_name_kp1),
4893 AKp::new(user_email_kp1),
4894 AKp::new(product_title_kp),
4895 AKp::new(product_sku_kp),
4896 AKp::new(user_name_kp2).for_arc::<User>(),
4897 AKp::new(user_email_kp2).for_box::<User>(),
4898 ];
4899
4900 let string_value_kps: Vec<_> = all_keypaths
4902 .iter()
4903 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4904 .collect();
4905
4906 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4910 .iter()
4911 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4912 .collect();
4913
4914 assert_eq!(user_root_kps.len(), 2);
4915
4916 let arc_user_kps: Vec<_> = all_keypaths
4918 .iter()
4919 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4920 .collect();
4921
4922 assert_eq!(arc_user_kps.len(), 1);
4923
4924 let box_user_kps: Vec<_> = all_keypaths
4926 .iter()
4927 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4928 .collect();
4929
4930 assert_eq!(box_user_kps.len(), 1);
4931
4932 let product_kps: Vec<_> = all_keypaths
4934 .iter()
4935 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4936 .collect();
4937
4938 assert_eq!(product_kps.len(), 2);
4939
4940 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4942 assert!(user_value.is_some());
4943 assert!(user_value.unwrap().is_some());
4944 }
4945
4946 #[test]
4951 fn test_kp_with_pin() {
4952 use std::pin::Pin;
4953
4954 #[derive(Debug)]
4958 struct SelfReferential {
4959 value: String,
4960 ptr_to_value: *const String, }
4962
4963 impl SelfReferential {
4964 fn new(s: String) -> Self {
4965 let mut sr = Self {
4966 value: s,
4967 ptr_to_value: std::ptr::null(),
4968 };
4969 sr.ptr_to_value = &sr.value as *const String;
4971 sr
4972 }
4973
4974 fn get_value(&self) -> &str {
4975 &self.value
4976 }
4977 }
4978
4979 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4981 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4982
4983 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4985 |p: &Pin<Box<SelfReferential>>| {
4986 Some(&p.as_ref().get_ref().value)
4988 },
4989 |p: &mut Pin<Box<SelfReferential>>| {
4990 unsafe {
4993 let sr = Pin::get_unchecked_mut(p.as_mut());
4994 Some(&mut sr.value)
4995 }
4996 },
4997 );
4998
4999 let result = kp.get(&pinned);
5001 assert_eq!(result, Some(&"pinned_data".to_string()));
5002
5003 assert_eq!(pinned.get_value(), "pinned_data");
5005 }
5006
5007 #[test]
5008 fn test_kp_with_pin_arc() {
5009 use std::pin::Pin;
5010 use std::sync::Arc;
5011
5012 struct AsyncState {
5013 status: String,
5014 data: Vec<i32>,
5015 }
5016
5017 let state = AsyncState {
5019 status: "ready".to_string(),
5020 data: vec![1, 2, 3, 4, 5],
5021 };
5022
5023 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
5024
5025 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
5027 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
5028 |_: &mut Pin<Arc<AsyncState>>| {
5029 None::<&mut String>
5031 },
5032 );
5033
5034 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
5036 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
5037 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
5038 );
5039
5040 let status = status_kp.get(&pinned_arc);
5041 assert_eq!(status, Some(&"ready".to_string()));
5042
5043 let data = data_kp.get(&pinned_arc);
5044 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
5045 }
5046
5047 #[test]
5048 fn test_kp_with_maybe_uninit() {
5049 use std::mem::MaybeUninit;
5050
5051 struct Config {
5055 name: MaybeUninit<String>,
5056 value: MaybeUninit<i32>,
5057 initialized: bool,
5058 }
5059
5060 impl Config {
5061 fn new_uninit() -> Self {
5062 Self {
5063 name: MaybeUninit::uninit(),
5064 value: MaybeUninit::uninit(),
5065 initialized: false,
5066 }
5067 }
5068
5069 fn init(&mut self, name: String, value: i32) {
5070 self.name.write(name);
5071 self.value.write(value);
5072 self.initialized = true;
5073 }
5074
5075 fn get_name(&self) -> Option<&String> {
5076 if self.initialized {
5077 unsafe { Some(self.name.assume_init_ref()) }
5078 } else {
5079 None
5080 }
5081 }
5082
5083 fn get_value(&self) -> Option<&i32> {
5084 if self.initialized {
5085 unsafe { Some(self.value.assume_init_ref()) }
5086 } else {
5087 None
5088 }
5089 }
5090 }
5091
5092 let name_kp: KpType<Config, String> = Kp::new(
5094 |c: &Config| c.get_name(),
5095 |c: &mut Config| {
5096 if c.initialized {
5097 unsafe { Some(c.name.assume_init_mut()) }
5098 } else {
5099 None
5100 }
5101 },
5102 );
5103
5104 let value_kp: KpType<Config, i32> = Kp::new(
5105 |c: &Config| c.get_value(),
5106 |c: &mut Config| {
5107 if c.initialized {
5108 unsafe { Some(c.value.assume_init_mut()) }
5109 } else {
5110 None
5111 }
5112 },
5113 );
5114
5115 let uninit_config = Config::new_uninit();
5117 assert_eq!(name_kp.get(&uninit_config), None);
5118 assert_eq!(value_kp.get(&uninit_config), None);
5119
5120 let mut init_config = Config::new_uninit();
5122 init_config.init("test_config".to_string(), 42);
5123
5124 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
5125 assert_eq!(value_kp.get(&init_config), Some(&42));
5126
5127 if let Some(val) = value_kp.get_mut(&mut init_config) {
5129 *val = 100;
5130 }
5131
5132 assert_eq!(value_kp.get(&init_config), Some(&100));
5133 }
5134
5135 #[test]
5136 fn test_kp_with_weak() {
5137 use std::sync::{Arc, Weak};
5138
5139 #[derive(Debug, Clone)]
5143 struct Node {
5144 value: i32,
5145 }
5146
5147 struct NodeWithParent {
5148 value: i32,
5149 parent: Option<Arc<Node>>, }
5151
5152 let parent = Arc::new(Node { value: 100 });
5153
5154 let child = NodeWithParent {
5155 value: 42,
5156 parent: Some(parent.clone()),
5157 };
5158
5159 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
5161 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
5162 |_: &mut NodeWithParent| None::<&mut i32>,
5163 );
5164
5165 let parent_val = parent_value_kp.get(&child);
5167 assert_eq!(parent_val, Some(&100));
5168 }
5169
5170 #[test]
5171 fn test_kp_with_rc_weak() {
5172 use std::rc::Rc;
5173
5174 struct TreeNode {
5177 value: String,
5178 parent: Option<Rc<TreeNode>>, }
5180
5181 let root = Rc::new(TreeNode {
5182 value: "root".to_string(),
5183 parent: None,
5184 });
5185
5186 let child1 = TreeNode {
5187 value: "child1".to_string(),
5188 parent: Some(root.clone()),
5189 };
5190
5191 let child2 = TreeNode {
5192 value: "child2".to_string(),
5193 parent: Some(root.clone()),
5194 };
5195
5196 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
5198 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
5199 |_: &mut TreeNode| None::<&mut String>,
5200 );
5201
5202 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
5204 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
5205
5206 assert_eq!(parent_name_kp.get(&root), None);
5208 }
5209
5210 #[test]
5211 fn test_kp_with_complex_weak_structure() {
5212 use std::sync::Arc;
5213
5214 struct Cache {
5217 data: String,
5218 backup: Option<Arc<Cache>>, }
5220
5221 let primary = Arc::new(Cache {
5222 data: "primary_data".to_string(),
5223 backup: None,
5224 });
5225
5226 let backup = Arc::new(Cache {
5227 data: "backup_data".to_string(),
5228 backup: Some(primary.clone()),
5229 });
5230
5231 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
5233 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
5234 |_: &mut Arc<Cache>| None::<&mut String>,
5235 );
5236
5237 let data = backup_data_kp.get(&backup);
5239 assert_eq!(data, Some(&"primary_data".to_string()));
5240
5241 let no_backup = backup_data_kp.get(&primary);
5243 assert_eq!(no_backup, None);
5244 }
5245
5246 #[test]
5247 fn test_kp_chain_with_pin_and_arc() {
5248 use std::pin::Pin;
5249 use std::sync::Arc;
5250
5251 struct Outer {
5254 inner: Arc<Inner>,
5255 }
5256
5257 struct Inner {
5258 value: String,
5259 }
5260
5261 let outer = Outer {
5262 inner: Arc::new(Inner {
5263 value: "nested_value".to_string(),
5264 }),
5265 };
5266
5267 let pinned_outer = Box::pin(outer);
5268
5269 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
5271 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
5272 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
5273 );
5274
5275 let to_value: KpType<Arc<Inner>, String> = Kp::new(
5277 |a: &Arc<Inner>| Some(&a.value),
5278 |_: &mut Arc<Inner>| None::<&mut String>,
5279 );
5280
5281 let chained = to_inner.then(to_value);
5283
5284 let result = chained.get(&pinned_outer);
5285 assert_eq!(result, Some(&"nested_value".to_string()));
5286 }
5287
5288 #[test]
5289 fn test_kp_with_maybe_uninit_array() {
5290 use std::mem::MaybeUninit;
5291
5292 struct Buffer {
5296 data: [MaybeUninit<u8>; 10],
5297 len: usize,
5298 }
5299
5300 impl Buffer {
5301 fn new() -> Self {
5302 Self {
5303 data: unsafe { MaybeUninit::uninit().assume_init() },
5304 len: 0,
5305 }
5306 }
5307
5308 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
5309 if self.len >= self.data.len() {
5310 return Err("Buffer full");
5311 }
5312 self.data[self.len].write(byte);
5313 self.len += 1;
5314 Ok(())
5315 }
5316
5317 fn get(&self, idx: usize) -> Option<&u8> {
5318 if idx < self.len {
5319 unsafe { Some(self.data[idx].assume_init_ref()) }
5320 } else {
5321 None
5322 }
5323 }
5324
5325 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
5326 if idx < self.len {
5327 unsafe { Some(self.data[idx].assume_init_mut()) }
5328 } else {
5329 None
5330 }
5331 }
5332 }
5333
5334 let len_kp: KpType<Buffer, usize> =
5336 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
5337
5338 let mut buffer = Buffer::new();
5339
5340 assert_eq!(len_kp.get(&buffer), Some(&0));
5342
5343 buffer.push(1).unwrap();
5345 buffer.push(2).unwrap();
5346 buffer.push(3).unwrap();
5347
5348 assert_eq!(len_kp.get(&buffer), Some(&3));
5350
5351 assert_eq!(buffer.get(0), Some(&1));
5353 assert_eq!(buffer.get(1), Some(&2));
5354 assert_eq!(buffer.get(2), Some(&3));
5355 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
5359 *elem = 20;
5360 }
5361 assert_eq!(buffer.get(1), Some(&20));
5362 }
5363
5364 #[test]
5365 fn test_kp_then_lock_deep_structs() {
5366 use std::sync::{Arc, Mutex};
5367
5368 #[derive(Clone)]
5369 struct Root {
5370 guard: Arc<Mutex<Level1>>,
5371 }
5372 #[derive(Clone)]
5373 struct Level1 {
5374 name: String,
5375 nested: Level2,
5376 }
5377 #[derive(Clone)]
5378 struct Level2 {
5379 count: i32,
5380 }
5381
5382 let root = Root {
5383 guard: Arc::new(Mutex::new(Level1 {
5384 name: "deep".to_string(),
5385 nested: Level2 { count: 42 },
5386 })),
5387 };
5388
5389 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
5390 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
5391
5392 let lock_kp = {
5393 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> = Kp::new(
5394 |g: &Arc<Mutex<Level1>>| Some(g),
5395 |g: &mut Arc<Mutex<Level1>>| Some(g),
5396 );
5397 let next: KpType<Level1, Level1> =
5398 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5399 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5400 };
5401
5402 let chained = kp_to_guard.then_lock(lock_kp);
5403 let level1 = chained.get(&root);
5404 assert!(level1.is_some());
5405 assert_eq!(level1.unwrap().name, "deep");
5406 assert_eq!(level1.unwrap().nested.count, 42);
5407
5408 let mut_root = &mut root.clone();
5409 let mut_level1 = chained.get_mut(mut_root);
5410 assert!(mut_level1.is_some());
5411 mut_level1.unwrap().nested.count = 99;
5412 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
5413 }
5414
5415 #[test]
5416 fn test_kp_then_lock_with_enum() {
5417 use std::sync::{Arc, Mutex};
5418
5419 #[derive(Clone)]
5420 enum Message {
5421 Request(LevelA),
5422 Response(i32),
5423 }
5424 #[derive(Clone)]
5425 struct LevelA {
5426 data: Arc<Mutex<i32>>,
5427 }
5428
5429 struct RootWithEnum {
5430 msg: Arc<Mutex<Message>>,
5431 }
5432
5433 let root = RootWithEnum {
5434 msg: Arc::new(Mutex::new(Message::Request(LevelA {
5435 data: Arc::new(Mutex::new(100)),
5436 }))),
5437 };
5438
5439 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> = Kp::new(
5440 |r: &RootWithEnum| Some(&r.msg),
5441 |r: &mut RootWithEnum| Some(&mut r.msg),
5442 );
5443
5444 let lock_kp_msg = {
5445 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> = Kp::new(
5446 |m: &Arc<Mutex<Message>>| Some(m),
5447 |m: &mut Arc<Mutex<Message>>| Some(m),
5448 );
5449 let next: KpType<Message, Message> =
5450 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
5451 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5452 };
5453
5454 let chained = kp_msg.then_lock(lock_kp_msg);
5455 let msg = chained.get(&root);
5456 assert!(msg.is_some());
5457 match msg.unwrap() {
5458 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
5459 Message::Response(_) => panic!("expected Request"),
5460 }
5461 }
5462
5463 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5464 #[tokio::test]
5465 async fn test_kp_then_async_deep_chain() {
5466 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5467 use std::sync::Arc;
5468
5469 #[derive(Clone)]
5470 struct Root {
5471 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
5472 }
5473 #[derive(Clone)]
5474 struct Level1 {
5475 value: i32,
5476 }
5477
5478 let root = Root {
5479 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
5480 };
5481
5482 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
5483 |r: &Root| Some(&r.tokio_guard),
5484 |r: &mut Root| Some(&mut r.tokio_guard),
5485 );
5486
5487 let async_kp = {
5488 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
5489 Kp::new(
5490 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
5491 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
5492 );
5493 let next: KpType<Level1, Level1> =
5494 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5495 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5496 };
5497
5498 let chained = kp_to_guard.then_async(async_kp);
5499 let level1 = chained.get(&root).await;
5500 assert!(level1.is_some());
5501 assert_eq!(level1.unwrap().value, 7);
5502 }
5503
5504 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5507 #[tokio::test]
5508 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
5509 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5510 use crate::lock::{ArcMutexAccess, LockKp};
5511 use std::sync::{Arc, Mutex};
5512
5513 #[derive(Clone)]
5515 struct Root {
5516 sync_mutex: Arc<Mutex<Level1>>,
5517 }
5518 #[derive(Clone)]
5520 struct Level1 {
5521 inner: Level2,
5522 }
5523 #[derive(Clone)]
5525 struct Level2 {
5526 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
5527 }
5528 #[derive(Clone)]
5530 struct Level3 {
5531 leaf: i32,
5532 }
5533
5534 let mut root = Root {
5535 sync_mutex: Arc::new(Mutex::new(Level1 {
5536 inner: Level2 {
5537 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
5538 },
5539 })),
5540 };
5541
5542 let identity_l1: KpType<Level1, Level1> =
5544 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5545 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
5546 |r: &Root| Some(&r.sync_mutex),
5547 |r: &mut Root| Some(&mut r.sync_mutex),
5548 );
5549 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
5550
5551 let kp_l1_inner: KpType<Level1, Level2> = Kp::new(
5553 |l: &Level1| Some(&l.inner),
5554 |l: &mut Level1| Some(&mut l.inner),
5555 );
5556
5557 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
5559 |l: &Level2| Some(&l.tokio_mutex),
5560 |l: &mut Level2| Some(&mut l.tokio_mutex),
5561 );
5562
5563 let async_l3 = {
5565 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
5566 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
5567 let next: KpType<Level3, Level3> =
5568 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
5569 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5570 };
5571
5572 let kp_l3_leaf: KpType<Level3, i32> = Kp::new(
5574 |l: &Level3| Some(&l.leaf),
5575 |l: &mut Level3| Some(&mut l.leaf),
5576 );
5577
5578 let step1 = lock_root_to_l1.then(kp_l1_inner);
5580 let step2 = step1.then(kp_l2_tokio);
5581 let step3 = step2.then_async(async_l3);
5582 let deep_chain = step3.then(kp_l3_leaf);
5583
5584 let leaf = deep_chain.get(&root).await;
5586 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5587 assert_eq!(leaf, Some(&100));
5588
5589 let mut root_mut = root.clone();
5591 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5592 assert!(leaf_mut.is_some());
5593 *leaf_mut.unwrap() = 99;
5594
5595 let leaf_after = deep_chain.get(&root_mut).await;
5597 assert_eq!(leaf_after, Some(&99));
5598 }
5599}