1use std::sync::{Arc, Mutex};
14
15pub mod lock;
17pub use lock::{
18 ArcMutexAccess, ArcRwLockAccess, LockAccess, LockKp, LockKpType, RcRefCellAccess,
19 StdMutexAccess, StdRwLockAccess,
20};
21
22#[cfg(feature = "parking_lot")]
23pub use lock::{
24 DirectParkingLotMutexAccess, DirectParkingLotRwLockAccess, ParkingLotMutexAccess,
25 ParkingLotRwLockAccess,
26};
27
28pub mod async_lock;
30
31
32
33#[cfg(feature = "pin_project")]
78pub mod pin;
79
80pub trait KeyPathValueTarget {
84 type Target: Sized;
85}
86impl<T> KeyPathValueTarget for &T {
87 type Target = T;
88}
89impl<T> KeyPathValueTarget for &mut T {
90 type Target = T;
91}
92
93#[macro_export]
95macro_rules! keypath {
96 { $root:ident . $field:ident } => { $root::$field() };
97 { $root:ident . $field:ident . $($ty:ident . $f:ident).+ } => {
98 $root::$field() $(.then($ty::$f()))+
99 };
100 ($root:ident . $field:ident) => { $root::$field() };
101 ($root:ident . $field:ident . $($ty:ident . $f:ident).+) => {
102 $root::$field() $(.then($ty::$f()))+
103 };
104}
105
106#[macro_export]
110macro_rules! get_or {
111 ($kp:expr, $root:expr, $default:expr) => {
112 $kp.get($root).unwrap_or($default)
113 };
114 ($root:expr => $($path:tt)*, $default:expr) => {
115 $crate::get_or!($crate::keypath!($($path)*), $root, $default)
116 };
117}
118
119#[macro_export]
124macro_rules! get_or_else {
125 ($kp:expr, $root:expr, $closure:expr) => {
126 $kp.get($root).map(|r| r.clone()).unwrap_or_else($closure)
127 };
128 ($root:expr => ($($path:tt)*), $closure:expr) => {
129 $crate::get_or_else!($crate::keypath!($($path)*), $root, $closure)
130 };
131}
132
133pub type KpValue<'a, R, V> = Kp<
135 R,
136 V,
137 &'a R,
138 V, &'a mut R,
140 V, for<'b> fn(&'b R) -> Option<V>,
142 for<'b> fn(&'b mut R) -> Option<V>,
143>;
144
145pub type KpOwned<R, V> = Kp<
147 R,
148 V,
149 R,
150 V, R,
152 V, fn(R) -> Option<V>,
154 fn(R) -> Option<V>,
155>;
156
157pub type KpRoot<R> = Kp<
159 R,
160 R,
161 R,
162 R, R,
164 R, fn(R) -> Option<R>,
166 fn(R) -> Option<R>,
167>;
168
169pub type KpVoid = Kp<
171 (),
172 (),
173 (),
174 (),
175 (),
176 (),
177 fn() -> Option<()>,
178 fn() -> Option<()>,
179>;
180
181
182
183
184pub type KpDynamic<R, V> = Kp<
185 R,
186 V,
187 &'static R,
188 &'static V,
189 &'static mut R,
190 &'static mut V,
191 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
192 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
193>;
194
195pub type KpBox<'a, R, V> = Kp<
196R, V,
197&'a R, &'a V,
198&'a mut R, &'a mut V,
199Box<dyn Fn(&'a R) -> Option<&'a V> + 'a>,
200Box<dyn Fn(&'a mut R) -> Option<&'a mut V> + 'a>,
201>;
202
203pub type KpArc<'a, R, V> = Kp<
204 R, V,
205 &'a R, &'a V,
206 &'a mut R, &'a mut V,
207 Arc<dyn Fn(&'a R) -> Option<&'a V> + Send + Sync + 'a>,
208 Arc<dyn Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync + 'a>,
209>;
210
211
212pub type KpType<'a, R, V> = Kp<
213 R,
214 V,
215 &'a R,
216 &'a V,
217 &'a mut R,
218 &'a mut V,
219 for<'b> fn(&'b R) -> Option<&'b V>,
220 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
221>;
222
223pub type KpOptionRefCellType<'a, R, V> = Kp<
226 R,
227 V,
228 &'a R,
229 std::cell::Ref<'a, V>,
230 &'a mut R,
231 std::cell::RefMut<'a, V>,
232 for<'b> fn(&'b R) -> Option<std::cell::Ref<'b, V>>,
233 for<'b> fn(&'b mut R) -> Option<std::cell::RefMut<'b, V>>,
234>;
235
236impl<'a, R, V> KpType<'a, R, V>
237where
238 'a: 'static,
239{
240 #[inline]
243 pub fn to_dynamic(self) -> KpDynamic<R, V> {
244 self.into()
245 }
246}
247
248impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V>
249where
250 'a: 'static,
251 R: 'static,
252 V: 'static,
253{
254 #[inline]
255 fn from(kp: KpType<'a, R, V>) -> Self {
256 let get_fn = kp.get;
257 let set_fn = kp.set;
258 Kp::new(
259 Box::new(move |t: &R| get_fn(t)),
260 Box::new(move |t: &mut R| set_fn(t)),
261 )
262 }
263}
264
265pub type KpComposed<R, V> = Kp<
301 R,
302 V,
303 &'static R,
304 &'static V,
305 &'static mut R,
306 &'static mut V,
307 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
308 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
309>;
310
311impl<R, V> Kp<
312 R,
313 V,
314 &'static R,
315 &'static V,
316 &'static mut R,
317 &'static mut V,
318 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
319 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
320> {
321 pub fn from_closures<G, S>(get: G, set: S) -> Self
324 where
325 G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
326 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
327 {
328 Self::new(Box::new(get), Box::new(set))
329 }
330}
331
332pub struct AKp {
333 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
334 root_type_id: TypeId,
335 value_type_id: TypeId,
336}
337
338impl AKp {
339 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
341 where
342 R: Any + 'static,
343 V: Any + 'static,
344 {
345 let root_type_id = TypeId::of::<R>();
346 let value_type_id = TypeId::of::<V>();
347 let getter_fn = keypath.get;
348
349 Self {
350 getter: Rc::new(move |any: &dyn Any| {
351 if let Some(root) = any.downcast_ref::<R>() {
352 getter_fn(root).map(|value: &V| value as &dyn Any)
353 } else {
354 None
355 }
356 }),
357 root_type_id,
358 value_type_id,
359 }
360 }
361
362 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
364 where
365 R: Any + 'static,
366 V: Any + 'static,
367 {
368 Self::new(keypath)
369 }
370
371 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
373 (self.getter)(root)
374 }
375
376 pub fn root_type_id(&self) -> TypeId {
378 self.root_type_id
379 }
380
381 pub fn value_type_id(&self) -> TypeId {
383 self.value_type_id
384 }
385
386 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
388 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
389 {
390 Some(
391 self.get(root as &dyn Any)
392 .and_then(|any| any.downcast_ref::<Value>()),
393 )
394 } else {
395 None
396 }
397 }
398
399 pub fn kind_name(&self) -> String {
401 format!("{:?}", self.value_type_id)
402 }
403
404 pub fn root_kind_name(&self) -> String {
406 format!("{:?}", self.root_type_id)
407 }
408
409 pub fn for_arc<Root>(&self) -> AKp
411 where
412 Root: Any + 'static,
413 {
414 let value_type_id = self.value_type_id;
415 let getter = self.getter.clone();
416
417 AKp {
418 getter: Rc::new(move |any: &dyn Any| {
419 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
420 getter(arc.as_ref() as &dyn Any)
421 } else {
422 None
423 }
424 }),
425 root_type_id: TypeId::of::<Arc<Root>>(),
426 value_type_id,
427 }
428 }
429
430 pub fn for_box<Root>(&self) -> AKp
432 where
433 Root: Any + 'static,
434 {
435 let value_type_id = self.value_type_id;
436 let getter = self.getter.clone();
437
438 AKp {
439 getter: Rc::new(move |any: &dyn Any| {
440 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
441 getter(boxed.as_ref() as &dyn Any)
442 } else {
443 None
444 }
445 }),
446 root_type_id: TypeId::of::<Box<Root>>(),
447 value_type_id,
448 }
449 }
450
451 pub fn for_rc<Root>(&self) -> AKp
453 where
454 Root: Any + 'static,
455 {
456 let value_type_id = self.value_type_id;
457 let getter = self.getter.clone();
458
459 AKp {
460 getter: Rc::new(move |any: &dyn Any| {
461 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
462 getter(rc.as_ref() as &dyn Any)
463 } else {
464 None
465 }
466 }),
467 root_type_id: TypeId::of::<Rc<Root>>(),
468 value_type_id,
469 }
470 }
471
472 pub fn for_option<Root>(&self) -> AKp
474 where
475 Root: Any + 'static,
476 {
477 let value_type_id = self.value_type_id;
478 let getter = self.getter.clone();
479
480 AKp {
481 getter: Rc::new(move |any: &dyn Any| {
482 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
483 opt.as_ref().and_then(|root| getter(root as &dyn Any))
484 } else {
485 None
486 }
487 }),
488 root_type_id: TypeId::of::<Option<Root>>(),
489 value_type_id,
490 }
491 }
492
493 pub fn for_result<Root, E>(&self) -> AKp
495 where
496 Root: Any + 'static,
497 E: Any + 'static,
498 {
499 let value_type_id = self.value_type_id;
500 let getter = self.getter.clone();
501
502 AKp {
503 getter: Rc::new(move |any: &dyn Any| {
504 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
505 result
506 .as_ref()
507 .ok()
508 .and_then(|root| getter(root as &dyn Any))
509 } else {
510 None
511 }
512 }),
513 root_type_id: TypeId::of::<Result<Root, E>>(),
514 value_type_id,
515 }
516 }
517
518 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
531 where
532 Root: Any + 'static,
533 OrigValue: Any + 'static,
534 MappedValue: Any + 'static,
535 F: Fn(&OrigValue) -> MappedValue + 'static,
536 {
537 let orig_root_type_id = self.root_type_id;
538 let orig_value_type_id = self.value_type_id;
539 let getter = self.getter.clone();
540 let mapped_type_id = TypeId::of::<MappedValue>();
541
542 AKp {
543 getter: Rc::new(move |any_root: &dyn Any| {
544 if any_root.type_id() == orig_root_type_id {
546 getter(any_root).and_then(|any_value| {
547 if orig_value_type_id == TypeId::of::<OrigValue>() {
549 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
550 let mapped = mapper(orig_val);
551 Box::leak(Box::new(mapped)) as &dyn Any
553 })
554 } else {
555 None
556 }
557 })
558 } else {
559 None
560 }
561 }),
562 root_type_id: orig_root_type_id,
563 value_type_id: mapped_type_id,
564 }
565 }
566
567 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
580 where
581 Root: Any + 'static,
582 Value: Any + 'static,
583 F: Fn(&Value) -> bool + 'static,
584 {
585 let orig_root_type_id = self.root_type_id;
586 let orig_value_type_id = self.value_type_id;
587 let getter = self.getter.clone();
588
589 AKp {
590 getter: Rc::new(move |any_root: &dyn Any| {
591 if any_root.type_id() == orig_root_type_id {
593 getter(any_root).filter(|any_value| {
594 if orig_value_type_id == TypeId::of::<Value>() {
596 any_value
597 .downcast_ref::<Value>()
598 .map(|val| predicate(val))
599 .unwrap_or(false)
600 } else {
601 false
602 }
603 })
604 } else {
605 None
606 }
607 }),
608 root_type_id: orig_root_type_id,
609 value_type_id: orig_value_type_id,
610 }
611 }
612}
613pub struct PKp<Root> {
614 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
615 value_type_id: TypeId,
616 _phantom: std::marker::PhantomData<Root>,
617}
618
619impl<Root> PKp<Root>
620where
621 Root: 'static,
622{
623 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
625 where
626 V: Any + 'static,
627 {
628 let value_type_id = TypeId::of::<V>();
629 let getter_fn = keypath.get;
630
631 Self {
632 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
633 value_type_id,
634 _phantom: std::marker::PhantomData,
635 }
636 }
637
638 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
640 where
641 V: Any + 'static,
642 {
643 Self::new(keypath)
644 }
645
646 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
648 (self.getter)(root)
649 }
650
651 pub fn value_type_id(&self) -> TypeId {
653 self.value_type_id
654 }
655
656 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
658 if self.value_type_id == TypeId::of::<Value>() {
659 self.get(root).and_then(|any| any.downcast_ref::<Value>())
660 } else {
661 None
662 }
663 }
664
665 pub fn kind_name(&self) -> String {
667 format!("{:?}", self.value_type_id)
668 }
669
670 pub fn for_arc(&self) -> PKp<Arc<Root>> {
672 let getter = self.getter.clone();
673 let value_type_id = self.value_type_id;
674
675 PKp {
676 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
677 value_type_id,
678 _phantom: std::marker::PhantomData,
679 }
680 }
681
682 pub fn for_box(&self) -> PKp<Box<Root>> {
684 let getter = self.getter.clone();
685 let value_type_id = self.value_type_id;
686
687 PKp {
688 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
689 value_type_id,
690 _phantom: std::marker::PhantomData,
691 }
692 }
693
694 pub fn for_rc(&self) -> PKp<Rc<Root>> {
696 let getter = self.getter.clone();
697 let value_type_id = self.value_type_id;
698
699 PKp {
700 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
701 value_type_id,
702 _phantom: std::marker::PhantomData,
703 }
704 }
705
706 pub fn for_option(&self) -> PKp<Option<Root>> {
708 let getter = self.getter.clone();
709 let value_type_id = self.value_type_id;
710
711 PKp {
712 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
713 value_type_id,
714 _phantom: std::marker::PhantomData,
715 }
716 }
717
718 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
720 where
721 E: 'static,
722 {
723 let getter = self.getter.clone();
724 let value_type_id = self.value_type_id;
725
726 PKp {
727 getter: Rc::new(move |result: &Result<Root, E>| {
728 result.as_ref().ok().and_then(|root| getter(root))
729 }),
730 value_type_id,
731 _phantom: std::marker::PhantomData,
732 }
733 }
734
735 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
749 where
750 OrigValue: Any + 'static,
751 MappedValue: Any + 'static,
752 F: Fn(&OrigValue) -> MappedValue + 'static,
753 {
754 let orig_type_id = self.value_type_id;
755 let getter = self.getter.clone();
756 let mapped_type_id = TypeId::of::<MappedValue>();
757
758 PKp {
759 getter: Rc::new(move |root: &Root| {
760 getter(root).and_then(|any_value| {
761 if orig_type_id == TypeId::of::<OrigValue>() {
763 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
764 let mapped = mapper(orig_val);
765 Box::leak(Box::new(mapped)) as &dyn Any
768 })
769 } else {
770 None
771 }
772 })
773 }),
774 value_type_id: mapped_type_id,
775 _phantom: std::marker::PhantomData,
776 }
777 }
778
779 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
793 where
794 Value: Any + 'static,
795 F: Fn(&Value) -> bool + 'static,
796 {
797 let orig_type_id = self.value_type_id;
798 let getter = self.getter.clone();
799
800 PKp {
801 getter: Rc::new(move |root: &Root| {
802 getter(root).filter(|any_value| {
803 if orig_type_id == TypeId::of::<Value>() {
805 any_value
806 .downcast_ref::<Value>()
807 .map(|val| predicate(val))
808 .unwrap_or(false)
809 } else {
810 false
811 }
812 })
813 }),
814 value_type_id: orig_type_id,
815 _phantom: std::marker::PhantomData,
816 }
817 }
818}
819
820#[derive(Clone)]
834pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
835where
836 Root: std::borrow::Borrow<R>,
837 MutRoot: std::borrow::BorrowMut<R>,
838 MutValue: std::borrow::BorrowMut<V>,
839 G: Fn(Root) -> Option<Value>,
840 S: Fn(MutRoot) -> Option<MutValue>,
841{
842 pub(crate) get: G,
844 pub(crate) set: S,
846 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
847}
848
849unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Send for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
851where
852 Root: std::borrow::Borrow<R>,
853 MutRoot: std::borrow::BorrowMut<R>,
854 MutValue: std::borrow::BorrowMut<V>,
855 G: Fn(Root) -> Option<Value> + Send,
856 S: Fn(MutRoot) -> Option<MutValue> + Send,
857{
858}
859unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Sync for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
860where
861 Root: std::borrow::Borrow<R>,
862 MutRoot: std::borrow::BorrowMut<R>,
863 MutValue: std::borrow::BorrowMut<V>,
864 G: Fn(Root) -> Option<Value> + Sync,
865 S: Fn(MutRoot) -> Option<MutValue> + Sync,
866{
867}
868
869impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
870where
871 Root: std::borrow::Borrow<R>,
872 Value: std::borrow::Borrow<V>,
873 MutRoot: std::borrow::BorrowMut<R>,
874 MutValue: std::borrow::BorrowMut<V>,
875 G: Fn(Root) -> Option<Value>,
876 S: Fn(MutRoot) -> Option<MutValue>,
877{
878 pub fn new(get: G, set: S) -> Self {
879 Self {
880 get: get,
881 set: set,
882 _p: std::marker::PhantomData,
883 }
884 }
885
886 pub const fn new_const(get: G, set: S) -> Self {
887 Self {
888 get: get,
889 set: set,
890 _p: std::marker::PhantomData,
891 }
892 }
893
894
895 #[inline]
896 pub fn get(&self, root: Root) -> Option<Value> {
897 (self.get)(root)
898 }
899 #[inline]
900 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
901 (self.set)(root)
902 }
903
904 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
905 self,
906 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
907 ) -> Kp<
908 R,
909 SV,
910 Root,
911 SubValue,
912 MutRoot,
913 MutSubValue,
914 impl Fn(Root) -> Option<SubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
915 impl Fn(MutRoot) -> Option<MutSubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
916 >
917 where
918 SubValue: std::borrow::Borrow<SV>,
919 MutSubValue: std::borrow::BorrowMut<SV>,
920 G2: Fn(Value) -> Option<SubValue>,
921 S2: Fn(MutValue) -> Option<MutSubValue>,
922 V: 'static,
923 {
924 Kp::new(
925 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
926 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
927 )
928 }
929
930 pub fn then_lock<
932 Lock,
933 Mid,
934 V2,
935 LockValue,
936 MidValue,
937 Value2,
938 MutLock,
939 MutMid,
940 MutValue2,
941 G1,
942 S1,
943 L,
944 G2,
945 S2,
946 >(
947 self,
948 lock_kp: crate::lock::LockKp<
949 V,
950 Lock,
951 Mid,
952 V2,
953 Value,
954 LockValue,
955 MidValue,
956 Value2,
957 MutValue,
958 MutLock,
959 MutMid,
960 MutValue2,
961 G1,
962 S1,
963 L,
964 G2,
965 S2,
966 >,
967 ) -> crate::lock::KpThenLockKp<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, Self, crate::lock::LockKp<V, Lock, Mid, V2, Value, LockValue, MidValue, Value2, MutValue, MutLock, MutMid, MutValue2, G1, S1, L, G2, S2>>
968 where
969 V: 'static + Clone,
970 V2: 'static,
971 Value: std::borrow::Borrow<V>,
972 Value2: std::borrow::Borrow<V2>,
973 MutValue: std::borrow::BorrowMut<V>,
974 MutValue2: std::borrow::BorrowMut<V2>,
975 LockValue: std::borrow::Borrow<Lock>,
976 MidValue: std::borrow::Borrow<Mid>,
977 MutLock: std::borrow::BorrowMut<Lock>,
978 MutMid: std::borrow::BorrowMut<Mid>,
979 G1: Fn(Value) -> Option<LockValue>,
980 S1: Fn(MutValue) -> Option<MutLock>,
981 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
982 G2: Fn(MidValue) -> Option<Value2>,
983 S2: Fn(MutMid) -> Option<MutValue2>,
984 {
985 crate::lock::KpThenLockKp {
986 first: self,
987 second: lock_kp,
988 _p: std::marker::PhantomData,
989 }
990 }
991
992 #[cfg(feature = "pin_project")]
995 pub fn then_pin_future<Struct, Output, L>(
996 self,
997 pin_fut: L,
998 ) -> crate::pin::KpThenPinFuture<
999 R,
1000 Struct,
1001 Output,
1002 Root,
1003 MutRoot,
1004 Value,
1005 MutValue,
1006 Self,
1007 L,
1008 >
1009 where
1010 V: 'static,
1011 Struct: Unpin + 'static,
1012 Output: 'static,
1013 Value: std::borrow::Borrow<Struct>,
1014 MutValue: std::borrow::BorrowMut<Struct>,
1015 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
1016 {
1017 crate::pin::KpThenPinFuture {
1018 first: self,
1019 second: pin_fut,
1020 _p: std::marker::PhantomData,
1021 }
1022 }
1023
1024 pub fn then_async<AsyncKp>(
1027 self,
1028 async_kp: AsyncKp,
1029 ) -> crate::async_lock::KpThenAsyncKeyPath<
1030 R,
1031 V,
1032 <AsyncKp::Value as KeyPathValueTarget>::Target,
1033 Root,
1034 Value,
1035 AsyncKp::Value,
1036 MutRoot,
1037 MutValue,
1038 AsyncKp::MutValue,
1039 Self,
1040 AsyncKp,
1041 >
1042 where
1043 V: 'static,
1044 Value: std::borrow::Borrow<V>,
1045 MutValue: std::borrow::BorrowMut<V>,
1046 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
1047 AsyncKp::Value: KeyPathValueTarget
1048 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1049 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1050 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
1051 {
1052 crate::async_lock::KpThenAsyncKeyPath {
1053 first: self,
1054 second: async_kp,
1055 _p: std::marker::PhantomData,
1056 }
1057 }
1058
1059 pub fn map<MappedValue, F>(
1072 &self,
1073 mapper: F,
1074 ) -> Kp<
1075 R,
1076 MappedValue,
1077 Root,
1078 MappedValue,
1079 MutRoot,
1080 MappedValue,
1081 impl Fn(Root) -> Option<MappedValue>,
1082 impl Fn(MutRoot) -> Option<MappedValue>,
1083 >
1084 where
1085 F: Fn(&V) -> MappedValue + Copy + 'static,
1088 V: 'static,
1089 MappedValue: 'static,
1090 {
1091 Kp::new(
1092 move |root: Root| {
1093 (&self.get)(root).map(|value| {
1094 let v: &V = value.borrow();
1095 mapper(v)
1096 })
1097 },
1098 move |root: MutRoot| {
1099 (&self.set)(root).map(|value| {
1100 let v: &V = value.borrow();
1101 mapper(v)
1102 })
1103 },
1104 )
1105 }
1106
1107 pub fn filter<F>(
1120 &self,
1121 predicate: F,
1122 ) -> Kp<
1123 R,
1124 V,
1125 Root,
1126 Value,
1127 MutRoot,
1128 MutValue,
1129 impl Fn(Root) -> Option<Value>,
1130 impl Fn(MutRoot) -> Option<MutValue>,
1131 >
1132 where
1133 F: Fn(&V) -> bool + Copy + 'static,
1136 V: 'static,
1137 {
1138 Kp::new(
1139 move |root: Root| {
1140 (&self.get)(root).filter(|value| {
1141 let v: &V = value.borrow();
1142 predicate(v)
1143 })
1144 },
1145 move |root: MutRoot| {
1146 (&self.set)(root).filter(|value| {
1147 let v: &V = value.borrow();
1148 predicate(v)
1149 })
1150 },
1151 )
1152 }
1153
1154 pub fn filter_map<MappedValue, F>(
1167 &self,
1168 mapper: F,
1169 ) -> Kp<
1170 R,
1171 MappedValue,
1172 Root,
1173 MappedValue,
1174 MutRoot,
1175 MappedValue,
1176 impl Fn(Root) -> Option<MappedValue>,
1177 impl Fn(MutRoot) -> Option<MappedValue>,
1178 >
1179 where
1180 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1183 V: 'static,
1184 MappedValue: 'static,
1185 {
1186 Kp::new(
1187 move |root: Root| {
1188 (&self.get)(root).and_then(|value| {
1189 let v: &V = value.borrow();
1190 mapper(v)
1191 })
1192 },
1193 move |root: MutRoot| {
1194 (&self.set)(root).and_then(|value| {
1195 let v: &V = value.borrow();
1196 mapper(v)
1197 })
1198 },
1199 )
1200 }
1201
1202 pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
1214 where
1215 F: Fn(&V) -> I + 'static,
1218 V: 'static,
1219 I: IntoIterator<Item = Item>,
1220 Item: 'static,
1221 {
1222 move |root: Root| {
1223 (&self.get)(root)
1224 .map(|value| {
1225 let v: &V = value.borrow();
1226 mapper(v).into_iter().collect()
1227 })
1228 .unwrap_or_else(Vec::new)
1229 }
1230 }
1231
1232 pub fn inspect<F>(
1243 &self,
1244 inspector: F,
1245 ) -> Kp<
1246 R,
1247 V,
1248 Root,
1249 Value,
1250 MutRoot,
1251 MutValue,
1252 impl Fn(Root) -> Option<Value>,
1253 impl Fn(MutRoot) -> Option<MutValue>,
1254 >
1255 where
1256 F: Fn(&V) + Copy + 'static,
1259 V: 'static,
1260 {
1261 Kp::new(
1262 move |root: Root| {
1263 (&self.get)(root).map(|value| {
1264 let v: &V = value.borrow();
1265 inspector(v);
1266 value
1267 })
1268 },
1269 move |root: MutRoot| {
1270 (&self.set)(root).map(|value| {
1271 let v: &V = value.borrow();
1272 inspector(v);
1273 value
1274 })
1275 },
1276 )
1277 }
1278
1279 pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
1293 where
1294 F: Fn(Acc, &V) -> Acc + 'static,
1297 V: 'static,
1298 Acc: Copy + 'static,
1300 {
1301 move |root: Root| {
1302 (&self.get)(root)
1303 .map(|value| {
1304 let v: &V = value.borrow();
1305 folder(init, v)
1306 })
1307 .unwrap_or(init)
1308 }
1309 }
1310
1311 pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1323 where
1324 F: Fn(&V) -> bool + 'static,
1327 V: 'static,
1328 {
1329 move |root: Root| {
1330 (&self.get)(root)
1331 .map(|value| {
1332 let v: &V = value.borrow();
1333 predicate(v)
1334 })
1335 .unwrap_or(false)
1336 }
1337 }
1338
1339 pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1351 where
1352 F: Fn(&V) -> bool + 'static,
1355 V: 'static,
1356 {
1357 move |root: Root| {
1358 (&self.get)(root)
1359 .map(|value| {
1360 let v: &V = value.borrow();
1361 predicate(v)
1362 })
1363 .unwrap_or(true)
1364 }
1365 }
1366
1367 pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
1379 where
1380 F: Fn(&V) -> usize + 'static,
1383 V: 'static,
1384 {
1385 move |root: Root| {
1386 (&self.get)(root).map(|value| {
1387 let v: &V = value.borrow();
1388 counter(v)
1389 })
1390 }
1391 }
1392
1393 pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
1407 where
1408 F: Fn(&V) -> Option<Item> + 'static,
1411 V: 'static,
1412 Item: 'static,
1413 {
1414 move |root: Root| {
1415 (&self.get)(root).and_then(|value| {
1416 let v: &V = value.borrow();
1417 finder(v)
1418 })
1419 }
1420 }
1421
1422 pub fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output>
1433 where
1434 F: Fn(&V, usize) -> Output + 'static,
1437 V: 'static,
1438 Output: 'static,
1439 {
1440 move |root: Root| {
1441 (&self.get)(root).map(|value| {
1442 let v: &V = value.borrow();
1443 taker(v, n)
1444 })
1445 }
1446 }
1447
1448 pub fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output>
1459 where
1460 F: Fn(&V, usize) -> Output + 'static,
1463 V: 'static,
1464 Output: 'static,
1465 {
1466 move |root: Root| {
1467 (&self.get)(root).map(|value| {
1468 let v: &V = value.borrow();
1469 skipper(v, n)
1470 })
1471 }
1472 }
1473
1474 pub fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output>
1487 where
1488 F: Fn(&V) -> Output + 'static,
1491 V: 'static,
1492 Output: 'static,
1493 {
1494 move |root: Root| {
1495 (&self.get)(root).map(|value| {
1496 let v: &V = value.borrow();
1497 partitioner(v)
1498 })
1499 }
1500 }
1501
1502 pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
1514 where
1515 F: Fn(&V) -> Option<Item> + 'static,
1518 V: 'static,
1519 Item: 'static,
1520 {
1521 move |root: Root| {
1522 (&self.get)(root).and_then(|value| {
1523 let v: &V = value.borrow();
1524 min_fn(v)
1525 })
1526 }
1527 }
1528
1529 pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
1541 where
1542 F: Fn(&V) -> Option<Item> + 'static,
1545 V: 'static,
1546 Item: 'static,
1547 {
1548 move |root: Root| {
1549 (&self.get)(root).and_then(|value| {
1550 let v: &V = value.borrow();
1551 max_fn(v)
1552 })
1553 }
1554 }
1555
1556 pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
1568 where
1569 F: Fn(&V) -> Sum + 'static,
1572 V: 'static,
1573 Sum: 'static,
1574 {
1575 move |root: Root| {
1576 (&self.get)(root).map(|value| {
1577 let v: &V = value.borrow();
1578 sum_fn(v)
1579 })
1580 }
1581 }
1582
1583 pub fn chain<SV, SubValue, MutSubValue, G2, S2>(
1586 self,
1587 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1588 ) -> Kp<
1589 R,
1590 SV,
1591 Root,
1592 SubValue,
1593 MutRoot,
1594 MutSubValue,
1595 impl Fn(Root) -> Option<SubValue>,
1596 impl Fn(MutRoot) -> Option<MutSubValue>,
1597 >
1598 where
1599 SubValue: std::borrow::Borrow<SV>,
1600 MutSubValue: std::borrow::BorrowMut<SV>,
1601 G2: Fn(Value) -> Option<SubValue>,
1602 S2: Fn(MutValue) -> Option<MutSubValue>,
1603 V: 'static,
1604 {
1605 self.then(next)
1606 }
1607
1608 pub fn for_arc<'b>(
1609 &self,
1610 ) -> Kp<
1611 std::sync::Arc<R>,
1612 V,
1613 std::sync::Arc<R>,
1614 Value,
1615 std::sync::Arc<R>,
1616 MutValue,
1617 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1618 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1619 >
1620 where
1621 R: 'b,
1622 V: 'b,
1623 Root: for<'a> From<&'a R>,
1624 MutRoot: for<'a> From<&'a mut R>,
1625 {
1626 Kp::new(
1627 move |arc_root: std::sync::Arc<R>| {
1628 let r_ref: &R = &*arc_root;
1629 (&self.get)(Root::from(r_ref))
1630 },
1631 move |mut arc_root: std::sync::Arc<R>| {
1632 std::sync::Arc::get_mut(&mut arc_root)
1634 .and_then(|r_mut| (&self.set)(MutRoot::from(r_mut)))
1635 },
1636 )
1637 }
1638
1639 pub fn for_box<'a>(
1640 &self,
1641 ) -> Kp<
1642 Box<R>,
1643 V,
1644 Box<R>,
1645 Value,
1646 Box<R>,
1647 MutValue,
1648 impl Fn(Box<R>) -> Option<Value>,
1649 impl Fn(Box<R>) -> Option<MutValue>,
1650 >
1651 where
1652 R: 'a,
1653 V: 'a,
1654 Root: for<'b> From<&'b R>,
1655 MutRoot: for<'b> From<&'b mut R>,
1656 {
1657 Kp::new(
1658 move |r: Box<R>| {
1659 let r_ref: &R = r.as_ref();
1660 (&self.get)(Root::from(r_ref))
1661 },
1662 move |mut r: Box<R>| {
1663 (self.set)(MutRoot::from(r.as_mut()))
1665 },
1666 )
1667 }
1668}
1669
1670pub fn zip_kps<'a, RootType, Value1, Value2>(
1684 kp1: &'a KpType<'a, RootType, Value1>,
1685 kp2: &'a KpType<'a, RootType, Value2>,
1686) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1687where
1688 RootType: 'a,
1689 Value1: 'a,
1690 Value2: 'a,
1691{
1692 move |root: &'a RootType| {
1693 let val1 = (kp1.get)(root)?;
1694 let val2 = (kp2.get)(root)?;
1695 Some((val1, val2))
1696 }
1697}
1698
1699impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1700where
1701 Root: std::borrow::Borrow<R>,
1702 MutRoot: std::borrow::BorrowMut<R>,
1703 G: Fn(Root) -> Option<Root>,
1704 S: Fn(MutRoot) -> Option<MutRoot>,
1705{
1706 pub fn identity_typed() -> Kp<
1707 R,
1708 R,
1709 Root,
1710 Root,
1711 MutRoot,
1712 MutRoot,
1713 fn(Root) -> Option<Root>,
1714 fn(MutRoot) -> Option<MutRoot>,
1715 > {
1716 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1717 }
1718
1719 pub fn identity<'a>() -> KpType<'a, R, R> {
1720 KpType::new(|r| Some(r), |r| Some(r))
1721 }
1722}
1723
1724pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1733where
1734 Root: std::borrow::Borrow<Enum>,
1735 Value: std::borrow::Borrow<Variant>,
1736 MutRoot: std::borrow::BorrowMut<Enum>,
1737 MutValue: std::borrow::BorrowMut<Variant>,
1738 G: Fn(Root) -> Option<Value>,
1739 S: Fn(MutRoot) -> Option<MutValue>,
1740 E: Fn(Variant) -> Enum,
1741{
1742 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1743 embedder: E,
1744}
1745
1746unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1748 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1749where
1750 Root: std::borrow::Borrow<Enum>,
1751 Value: std::borrow::Borrow<Variant>,
1752 MutRoot: std::borrow::BorrowMut<Enum>,
1753 MutValue: std::borrow::BorrowMut<Variant>,
1754 G: Fn(Root) -> Option<Value> + Send,
1755 S: Fn(MutRoot) -> Option<MutValue> + Send,
1756 E: Fn(Variant) -> Enum + Send,
1757{
1758}
1759unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1760 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1761where
1762 Root: std::borrow::Borrow<Enum>,
1763 Value: std::borrow::Borrow<Variant>,
1764 MutRoot: std::borrow::BorrowMut<Enum>,
1765 MutValue: std::borrow::BorrowMut<Variant>,
1766 G: Fn(Root) -> Option<Value> + Sync,
1767 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1768 E: Fn(Variant) -> Enum + Sync,
1769{
1770}
1771
1772impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1773 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1774where
1775 Root: std::borrow::Borrow<Enum>,
1776 Value: std::borrow::Borrow<Variant>,
1777 MutRoot: std::borrow::BorrowMut<Enum>,
1778 MutValue: std::borrow::BorrowMut<Variant>,
1779 G: Fn(Root) -> Option<Value>,
1780 S: Fn(MutRoot) -> Option<MutValue>,
1781 E: Fn(Variant) -> Enum,
1782{
1783 pub fn new(
1785 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1786 embedder: E,
1787 ) -> Self {
1788 Self {
1789 extractor,
1790 embedder,
1791 }
1792 }
1793
1794 pub fn get(&self, enum_value: Root) -> Option<Value> {
1796 self.extractor.get(enum_value)
1797 }
1798
1799 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1801 self.extractor.get_mut(enum_value)
1802 }
1803
1804 pub fn embed(&self, value: Variant) -> Enum {
1806 (self.embedder)(value)
1807 }
1808
1809 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1811 &self.extractor
1812 }
1813
1814 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1816 self.extractor
1817 }
1818
1819 pub fn map<MappedValue, F>(
1830 &self,
1831 mapper: F,
1832 ) -> EnumKp<
1833 Enum,
1834 MappedValue,
1835 Root,
1836 MappedValue,
1837 MutRoot,
1838 MappedValue,
1839 impl Fn(Root) -> Option<MappedValue>,
1840 impl Fn(MutRoot) -> Option<MappedValue>,
1841 impl Fn(MappedValue) -> Enum,
1842 >
1843 where
1844 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1847 Variant: 'static,
1848 MappedValue: 'static,
1849 E: Fn(Variant) -> Enum + Copy + 'static,
1851 {
1852 let mapped_extractor = self.extractor.map(mapper);
1853
1854 let new_embedder = move |_value: MappedValue| -> Enum {
1858 panic!(
1859 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1860 )
1861 };
1862
1863 EnumKp::new(mapped_extractor, new_embedder)
1864 }
1865
1866 pub fn filter<F>(
1878 &self,
1879 predicate: F,
1880 ) -> EnumKp<
1881 Enum,
1882 Variant,
1883 Root,
1884 Value,
1885 MutRoot,
1886 MutValue,
1887 impl Fn(Root) -> Option<Value>,
1888 impl Fn(MutRoot) -> Option<MutValue>,
1889 E,
1890 >
1891 where
1892 F: Fn(&Variant) -> bool + Copy + 'static,
1895 Variant: 'static,
1896 E: Copy,
1898 {
1899 let filtered_extractor = self.extractor.filter(predicate);
1900 EnumKp::new(filtered_extractor, self.embedder)
1901 }
1902}
1903
1904pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1906 Enum,
1907 Variant,
1908 &'a Enum,
1909 &'a Variant,
1910 &'a mut Enum,
1911 &'a mut Variant,
1912 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1913 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1914 fn(Variant) -> Enum,
1915>;
1916
1917pub fn enum_variant<'a, Enum, Variant>(
1935 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1936 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1937 embedder: fn(Variant) -> Enum,
1938) -> EnumKpType<'a, Enum, Variant> {
1939 EnumKp::new(Kp::new(getter, setter), embedder)
1940}
1941
1942pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1952 EnumKp::new(
1953 Kp::new(
1954 |r: &Result<T, E>| r.as_ref().ok(),
1955 |r: &mut Result<T, E>| r.as_mut().ok(),
1956 ),
1957 |t: T| Ok(t),
1958 )
1959}
1960
1961pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1971 EnumKp::new(
1972 Kp::new(
1973 |r: &Result<T, E>| r.as_ref().err(),
1974 |r: &mut Result<T, E>| r.as_mut().err(),
1975 ),
1976 |e: E| Err(e),
1977 )
1978}
1979
1980pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1990 EnumKp::new(
1991 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1992 |t: T| Some(t),
1993 )
1994}
1995
1996pub fn variant_of<'a, Enum, Variant>(
2014 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2015 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2016 embedder: fn(Variant) -> Enum,
2017) -> EnumKpType<'a, Enum, Variant> {
2018 enum_variant(getter, setter, embedder)
2019}
2020
2021pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
2034 Kp::new(
2035 |b: &Box<T>| Some(b.as_ref()),
2036 |b: &mut Box<T>| Some(b.as_mut()),
2037 )
2038}
2039
2040pub fn kp_arc<'a, T>() -> Kp<
2051 Arc<T>,
2052 T,
2053 &'a Arc<T>,
2054 &'a T,
2055 &'a mut Arc<T>,
2056 &'a mut T,
2057 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
2058 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
2059> {
2060 Kp::new(
2061 |arc: &Arc<T>| Some(arc.as_ref()),
2062 |arc: &mut Arc<T>| Arc::get_mut(arc),
2063 )
2064}
2065
2066pub fn kp_rc<'a, T>() -> Kp<
2077 std::rc::Rc<T>,
2078 T,
2079 &'a std::rc::Rc<T>,
2080 &'a T,
2081 &'a mut std::rc::Rc<T>,
2082 &'a mut T,
2083 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
2084 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
2085> {
2086 Kp::new(
2087 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
2088 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
2089 )
2090}
2091
2092use std::any::{Any, TypeId};
2095use std::rc::Rc;
2096
2097#[cfg(test)]
2112mod tests {
2113 use super::*;
2114 use std::collections::HashMap;
2115
2116 #[derive(Debug)]
2117 struct TestKP {
2118 a: String,
2119 b: String,
2120 c: std::sync::Arc<String>,
2121 d: std::sync::Mutex<String>,
2122 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
2123 f: Option<TestKP2>,
2124 g: HashMap<i32, TestKP2>,
2125 }
2126
2127 impl TestKP {
2128 fn new() -> Self {
2129 Self {
2130 a: String::from("a"),
2131 b: String::from("b"),
2132 c: std::sync::Arc::new(String::from("c")),
2133 d: std::sync::Mutex::new(String::from("d")),
2134 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2135 f: Some(TestKP2 {
2136 a: String::from("a3"),
2137 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2138 }),
2139 g: HashMap::new(),
2140 }
2141 }
2142
2143 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2144 KpComposed::from_closures(
2145 move |r: &TestKP| r.g.get(&index),
2146 move |r: &mut TestKP| r.g.get_mut(&index),
2147 )
2148 }
2149
2150 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2153 TestKP2,
2154 String,
2155 Root,
2156 Value,
2157 MutRoot,
2158 MutValue,
2159 impl Fn(Root) -> Option<Value>,
2160 impl Fn(MutRoot) -> Option<MutValue>,
2161 >
2162 where
2163 Root: std::borrow::Borrow<TestKP2>,
2164 MutRoot: std::borrow::BorrowMut<TestKP2>,
2165 Value: std::borrow::Borrow<String> + From<String>,
2166 MutValue: std::borrow::BorrowMut<String> + From<String>,
2167 {
2168 Kp::new(
2169 |r: Root| Some(Value::from(r.borrow().a.clone())),
2170 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2171 )
2172 }
2173
2174 fn c<'a>() -> KpType<'a, TestKP, String> {
2177 KpType::new(
2178 |r: &TestKP| Some(r.c.as_ref()),
2179 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2180 Some(arc_str) => Some(arc_str),
2181 None => None,
2182 },
2183 )
2184 }
2185
2186 fn a<'a>() -> KpType<'a, TestKP, String> {
2187 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2188 }
2189
2190 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2191 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2192 }
2193
2194 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2195 KpType::identity()
2196 }
2197 }
2198
2199 #[derive(Debug)]
2200 struct TestKP2 {
2201 a: String,
2202 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2203 }
2204
2205 impl TestKP2 {
2206 fn new() -> Self {
2207 TestKP2 {
2208 a: String::from("a2"),
2209 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2210 }
2211 }
2212
2213 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2214 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2221 fn(MutRoot) -> Option<MutRoot>,
2222 >
2223 where
2224 Root: std::borrow::Borrow<TestKP2>,
2225 MutRoot: std::borrow::BorrowMut<TestKP2>,
2226 G: Fn(Root) -> Option<Root>,
2227 S: Fn(MutRoot) -> Option<MutRoot>,
2228 {
2229 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2230 }
2231
2232 fn a<'a>() -> KpType<'a, TestKP2, String> {
2233 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2234 }
2235
2236 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2237 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2238 }
2239
2240 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2245 KpType::identity()
2246 }
2247 }
2248
2249 #[derive(Debug)]
2250 struct TestKP3 {
2251 a: String,
2252 b: std::sync::Arc<std::sync::Mutex<String>>,
2253 }
2254
2255 impl TestKP3 {
2256 fn new() -> Self {
2257 TestKP3 {
2258 a: String::from("a2"),
2259 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2260 }
2261 }
2262
2263 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2264 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2271 fn(MutRoot) -> Option<MutRoot>,
2272 >
2273 where
2274 Root: std::borrow::Borrow<TestKP3>,
2275 MutRoot: std::borrow::BorrowMut<TestKP3>,
2276 G: Fn(Root) -> Option<Root>,
2277 S: Fn(MutRoot) -> Option<MutRoot>,
2278 {
2279 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2280 }
2281
2282 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2283 KpType::identity()
2284 }
2285 }
2286
2287 impl TestKP3 {}
2288
2289 impl TestKP {}
2290 #[test]
2291 fn test_a() {
2292 let instance2 = TestKP2::new();
2293 let mut instance = TestKP::new();
2294 let kp = TestKP::identity();
2295 let kp_a = TestKP::a();
2296 let wres = TestKP::f().then(TestKP2::a()).get_mut(&mut instance).unwrap();
2298 *wres = String::from("a3 changed successfully");
2299 let res = TestKP::f().then(TestKP2::a()).get(&instance);
2300 println!("{:?}", res);
2301 let res = TestKP::f().then(TestKP2::identity()).get(&instance);
2302 println!("{:?}", res);
2303 let res = kp.get(&instance);
2304 println!("{:?}", res);
2305
2306 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2307 println!("{:?}", new_kp_from_hashmap.get(&instance));
2308 }
2309
2310 #[test]
2389 fn test_enum_kp_result_ok() {
2390 let ok_result: Result<String, i32> = Ok("success".to_string());
2391 let mut err_result: Result<String, i32> = Err(42);
2392
2393 let ok_kp = enum_ok();
2394
2395 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2397 assert_eq!(ok_kp.get(&err_result), None);
2398
2399 let embedded = ok_kp.embed("embedded".to_string());
2401 assert_eq!(embedded, Ok("embedded".to_string()));
2402
2403 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2405 *val = "modified".to_string();
2406 }
2407 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2410 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2411 *val = "modified".to_string();
2412 }
2413 assert_eq!(ok_result2, Ok("modified".to_string()));
2414 }
2415
2416 #[test]
2417 fn test_enum_kp_result_err() {
2418 let ok_result: Result<String, i32> = Ok("success".to_string());
2419 let mut err_result: Result<String, i32> = Err(42);
2420
2421 let err_kp = enum_err();
2422
2423 assert_eq!(err_kp.get(&err_result), Some(&42));
2425 assert_eq!(err_kp.get(&ok_result), None);
2426
2427 let embedded = err_kp.embed(99);
2429 assert_eq!(embedded, Err(99));
2430
2431 if let Some(val) = err_kp.get_mut(&mut err_result) {
2433 *val = 100;
2434 }
2435 assert_eq!(err_result, Err(100));
2436 }
2437
2438 #[test]
2439 fn test_enum_kp_option_some() {
2440 let some_opt = Some("value".to_string());
2441 let mut none_opt: Option<String> = None;
2442
2443 let some_kp = enum_some();
2444
2445 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2447 assert_eq!(some_kp.get(&none_opt), None);
2448
2449 let embedded = some_kp.embed("embedded".to_string());
2451 assert_eq!(embedded, Some("embedded".to_string()));
2452
2453 let mut some_opt2 = Some("original".to_string());
2455 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2456 *val = "modified".to_string();
2457 }
2458 assert_eq!(some_opt2, Some("modified".to_string()));
2459 }
2460
2461 #[test]
2462 fn test_enum_kp_custom_enum() {
2463 #[derive(Debug, PartialEq)]
2464 enum MyEnum {
2465 A(String),
2466 B(i32),
2467 C,
2468 }
2469
2470 let mut enum_a = MyEnum::A("hello".to_string());
2471 let enum_b = MyEnum::B(42);
2472 let enum_c = MyEnum::C;
2473
2474 let kp_a = enum_variant(
2476 |e: &MyEnum| match e {
2477 MyEnum::A(s) => Some(s),
2478 _ => None,
2479 },
2480 |e: &mut MyEnum| match e {
2481 MyEnum::A(s) => Some(s),
2482 _ => None,
2483 },
2484 |s: String| MyEnum::A(s),
2485 );
2486
2487 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2489 assert_eq!(kp_a.get(&enum_b), None);
2490 assert_eq!(kp_a.get(&enum_c), None);
2491
2492 let embedded = kp_a.embed("world".to_string());
2494 assert_eq!(embedded, MyEnum::A("world".to_string()));
2495
2496 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2498 *val = "modified".to_string();
2499 }
2500 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2501 }
2502
2503 #[test]
2504 fn test_container_kp_box() {
2505 let boxed = Box::new("value".to_string());
2506 let mut boxed_mut = Box::new("original".to_string());
2507
2508 let box_kp = kp_box();
2509
2510 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2512
2513 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2515 *val = "modified".to_string();
2516 }
2517 assert_eq!(*boxed_mut, "modified".to_string());
2518 }
2519
2520 #[test]
2521 fn test_container_kp_arc() {
2522 let arc = Arc::new("value".to_string());
2523 let mut arc_mut = Arc::new("original".to_string());
2524
2525 let arc_kp = kp_arc();
2526
2527 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2529
2530 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2532 *val = "modified".to_string();
2533 }
2534 assert_eq!(*arc_mut, "modified".to_string());
2535
2536 let arc_shared = Arc::new("shared".to_string());
2538 let arc_shared2 = Arc::clone(&arc_shared);
2539 let mut arc_shared_mut = arc_shared;
2540 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2541 }
2542
2543 #[test]
2544 fn test_enum_kp_composition() {
2545 #[derive(Debug, PartialEq)]
2547 struct Inner {
2548 value: String,
2549 }
2550
2551 let result: Result<Inner, i32> = Ok(Inner {
2552 value: "nested".to_string(),
2553 });
2554
2555 let inner_kp = KpType::new(
2557 |i: &Inner| Some(&i.value),
2558 |i: &mut Inner| Some(&mut i.value),
2559 );
2560
2561 let ok_kp = enum_ok::<Inner, i32>();
2563 let ok_kp_base = ok_kp.into_kp();
2564 let composed = ok_kp_base.then(inner_kp);
2565
2566 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2567 }
2568
2569 #[test]
2570 fn test_pkp_basic() {
2571 #[derive(Debug)]
2572 struct User {
2573 name: String,
2574 age: i32,
2575 }
2576
2577 let user = User {
2578 name: "Alice".to_string(),
2579 age: 30,
2580 };
2581
2582 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2584 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2585
2586 let name_pkp = PKp::new(name_kp);
2588 let age_pkp = PKp::new(age_kp);
2589
2590 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2592 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2593
2594 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2596 assert_eq!(age_pkp.get_as::<String>(&user), None);
2597
2598 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2600 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2601 }
2602
2603 #[test]
2604 fn test_pkp_collection() {
2605 #[derive(Debug)]
2606 struct User {
2607 name: String,
2608 age: i32,
2609 }
2610
2611 let user = User {
2612 name: "Bob".to_string(),
2613 age: 25,
2614 };
2615
2616 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2618 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2619
2620 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2621
2622 let name_value = keypaths[0].get_as::<String>(&user);
2624 let age_value = keypaths[1].get_as::<i32>(&user);
2625
2626 assert_eq!(name_value, Some(&"Bob".to_string()));
2627 assert_eq!(age_value, Some(&25));
2628 }
2629
2630 #[test]
2631 fn test_pkp_for_arc() {
2632 #[derive(Debug)]
2633 struct User {
2634 name: String,
2635 }
2636
2637 let user = Arc::new(User {
2638 name: "Charlie".to_string(),
2639 });
2640
2641 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2642 let name_pkp = PKp::new(name_kp);
2643
2644 let arc_pkp = name_pkp.for_arc();
2646
2647 assert_eq!(
2648 arc_pkp.get_as::<String>(&user),
2649 Some(&"Charlie".to_string())
2650 );
2651 }
2652
2653 #[test]
2654 fn test_pkp_for_option() {
2655 #[derive(Debug)]
2656 struct User {
2657 name: String,
2658 }
2659
2660 let some_user = Some(User {
2661 name: "Diana".to_string(),
2662 });
2663 let none_user: Option<User> = None;
2664
2665 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2666 let name_pkp = PKp::new(name_kp);
2667
2668 let opt_pkp = name_pkp.for_option();
2670
2671 assert_eq!(
2672 opt_pkp.get_as::<String>(&some_user),
2673 Some(&"Diana".to_string())
2674 );
2675 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2676 }
2677
2678 #[test]
2679 fn test_akp_basic() {
2680 #[derive(Debug)]
2681 struct User {
2682 name: String,
2683 age: i32,
2684 }
2685
2686 #[derive(Debug)]
2687 struct Product {
2688 title: String,
2689 price: f64,
2690 }
2691
2692 let user = User {
2693 name: "Eve".to_string(),
2694 age: 28,
2695 };
2696
2697 let product = Product {
2698 title: "Book".to_string(),
2699 price: 19.99,
2700 };
2701
2702 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2704 let user_name_akp = AKp::new(user_name_kp);
2705
2706 let product_title_kp = KpType::new(
2707 |p: &Product| Some(&p.title),
2708 |p: &mut Product| Some(&mut p.title),
2709 );
2710 let product_title_akp = AKp::new(product_title_kp);
2711
2712 assert_eq!(
2714 user_name_akp.get_as::<User, String>(&user),
2715 Some(Some(&"Eve".to_string()))
2716 );
2717 assert_eq!(
2718 product_title_akp.get_as::<Product, String>(&product),
2719 Some(Some(&"Book".to_string()))
2720 );
2721
2722 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2724 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2725
2726 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2728 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2729 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2730 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2731 }
2732
2733 #[test]
2734 fn test_akp_heterogeneous_collection() {
2735 #[derive(Debug)]
2736 struct User {
2737 name: String,
2738 }
2739
2740 #[derive(Debug)]
2741 struct Product {
2742 title: String,
2743 }
2744
2745 let user = User {
2746 name: "Frank".to_string(),
2747 };
2748 let product = Product {
2749 title: "Laptop".to_string(),
2750 };
2751
2752 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2754 let product_title_kp = KpType::new(
2755 |p: &Product| Some(&p.title),
2756 |p: &mut Product| Some(&mut p.title),
2757 );
2758
2759 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2760
2761 let user_any: &dyn Any = &user;
2763 let product_any: &dyn Any = &product;
2764
2765 let user_value = keypaths[0].get(user_any);
2766 let product_value = keypaths[1].get(product_any);
2767
2768 assert!(user_value.is_some());
2769 assert!(product_value.is_some());
2770
2771 assert_eq!(
2773 user_value.and_then(|v| v.downcast_ref::<String>()),
2774 Some(&"Frank".to_string())
2775 );
2776 assert_eq!(
2777 product_value.and_then(|v| v.downcast_ref::<String>()),
2778 Some(&"Laptop".to_string())
2779 );
2780 }
2781
2782 #[test]
2783 fn test_akp_for_option() {
2784 #[derive(Debug)]
2785 struct User {
2786 name: String,
2787 }
2788
2789 let some_user = Some(User {
2790 name: "Grace".to_string(),
2791 });
2792 let none_user: Option<User> = None;
2793
2794 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2795 let name_akp = AKp::new(name_kp);
2796
2797 let opt_akp = name_akp.for_option::<User>();
2799
2800 assert_eq!(
2801 opt_akp.get_as::<Option<User>, String>(&some_user),
2802 Some(Some(&"Grace".to_string()))
2803 );
2804 assert_eq!(
2805 opt_akp.get_as::<Option<User>, String>(&none_user),
2806 Some(None)
2807 );
2808 }
2809
2810 #[test]
2811 fn test_akp_for_result() {
2812 #[derive(Debug)]
2813 struct User {
2814 name: String,
2815 }
2816
2817 let ok_user: Result<User, String> = Ok(User {
2818 name: "Henry".to_string(),
2819 });
2820 let err_user: Result<User, String> = Err("Not found".to_string());
2821
2822 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2823 let name_akp = AKp::new(name_kp);
2824
2825 let result_akp = name_akp.for_result::<User, String>();
2827
2828 assert_eq!(
2829 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2830 Some(Some(&"Henry".to_string()))
2831 );
2832 assert_eq!(
2833 result_akp.get_as::<Result<User, String>, String>(&err_user),
2834 Some(None)
2835 );
2836 }
2837
2838 #[test]
2841 fn test_kp_map() {
2842 #[derive(Debug)]
2843 struct User {
2844 name: String,
2845 age: i32,
2846 }
2847
2848 let user = User {
2849 name: "Alice".to_string(),
2850 age: 30,
2851 };
2852
2853 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2855 let len_kp = name_kp.map(|name: &String| name.len());
2856
2857 assert_eq!(len_kp.get(&user), Some(5));
2858
2859 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2861 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2862
2863 assert_eq!(double_age_kp.get(&user), Some(60));
2864
2865 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2867 assert_eq!(is_adult_kp.get(&user), Some(true));
2868 }
2869
2870 #[test]
2871 fn test_kp_filter() {
2872 #[derive(Debug)]
2873 struct User {
2874 name: String,
2875 age: i32,
2876 }
2877
2878 let adult = User {
2879 name: "Alice".to_string(),
2880 age: 30,
2881 };
2882
2883 let minor = User {
2884 name: "Bob".to_string(),
2885 age: 15,
2886 };
2887
2888 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2889 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2890
2891 assert_eq!(adult_age_kp.get(&adult), Some(&30));
2892 assert_eq!(adult_age_kp.get(&minor), None);
2893
2894 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2896 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2897
2898 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2899 assert_eq!(short_name_kp.get(&adult), None);
2900 }
2901
2902 #[test]
2903 fn test_kp_map_and_filter() {
2904 #[derive(Debug)]
2905 struct User {
2906 scores: Vec<i32>,
2907 }
2908
2909 let user = User {
2910 scores: vec![85, 92, 78, 95],
2911 };
2912
2913 let scores_kp = KpType::new(
2914 |u: &User| Some(&u.scores),
2915 |u: &mut User| Some(&mut u.scores),
2916 );
2917
2918 let avg_kp =
2920 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2921
2922 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2924
2925 assert_eq!(high_avg_kp.get(&user), Some(87)); }
2927
2928 #[test]
2929 fn test_enum_kp_map() {
2930 let ok_result: Result<String, i32> = Ok("hello".to_string());
2931 let err_result: Result<String, i32> = Err(42);
2932
2933 let ok_kp = enum_ok::<String, i32>();
2934 let len_kp = ok_kp.map(|s: &String| s.len());
2935
2936 assert_eq!(len_kp.get(&ok_result), Some(5));
2937 assert_eq!(len_kp.get(&err_result), None);
2938
2939 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2941 let none_opt: Option<Vec<i32>> = None;
2942
2943 let some_kp = enum_some::<Vec<i32>>();
2944 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2945
2946 assert_eq!(count_kp.get(&some_opt), Some(5));
2947 assert_eq!(count_kp.get(&none_opt), None);
2948 }
2949
2950 #[test]
2951 fn test_enum_kp_filter() {
2952 let ok_result1: Result<i32, String> = Ok(42);
2953 let ok_result2: Result<i32, String> = Ok(-5);
2954 let err_result: Result<i32, String> = Err("error".to_string());
2955
2956 let ok_kp = enum_ok::<i32, String>();
2957 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2958
2959 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2960 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2965 let short_str = Some("hi".to_string());
2966
2967 let some_kp = enum_some::<String>();
2968 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2969
2970 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2971 assert_eq!(long_kp.get(&short_str), None);
2972 }
2973
2974 #[test]
2975 fn test_pkp_filter() {
2976 #[derive(Debug)]
2977 struct User {
2978 name: String,
2979 age: i32,
2980 }
2981
2982 let adult = User {
2983 name: "Alice".to_string(),
2984 age: 30,
2985 };
2986
2987 let minor = User {
2988 name: "Bob".to_string(),
2989 age: 15,
2990 };
2991
2992 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2993 let age_pkp = PKp::new(age_kp);
2994
2995 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2997
2998 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2999 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
3000
3001 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3003 let name_pkp = PKp::new(name_kp);
3004 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
3005
3006 assert_eq!(
3007 short_name_pkp.get_as::<String>(&minor),
3008 Some(&"Bob".to_string())
3009 );
3010 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
3011 }
3012
3013 #[test]
3014 fn test_akp_filter() {
3015 #[derive(Debug)]
3016 struct User {
3017 age: i32,
3018 }
3019
3020 #[derive(Debug)]
3021 struct Product {
3022 price: f64,
3023 }
3024
3025 let adult = User { age: 30 };
3026 let minor = User { age: 15 };
3027 let expensive = Product { price: 99.99 };
3028 let cheap = Product { price: 5.0 };
3029
3030 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3032 let age_akp = AKp::new(age_kp);
3033 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
3034
3035 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
3036 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
3037
3038 let price_kp = KpType::new(
3040 |p: &Product| Some(&p.price),
3041 |p: &mut Product| Some(&mut p.price),
3042 );
3043 let price_akp = AKp::new(price_kp);
3044 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
3045
3046 assert_eq!(
3047 expensive_akp.get_as::<Product, f64>(&expensive),
3048 Some(Some(&99.99))
3049 );
3050 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
3051 }
3052
3053 #[test]
3056 fn test_kp_filter_map() {
3057 #[derive(Debug)]
3058 struct User {
3059 middle_name: Option<String>,
3060 }
3061
3062 let user_with = User {
3063 middle_name: Some("Marie".to_string()),
3064 };
3065 let user_without = User { middle_name: None };
3066
3067 let middle_kp = KpType::new(
3068 |u: &User| Some(&u.middle_name),
3069 |u: &mut User| Some(&mut u.middle_name),
3070 );
3071
3072 let first_char_kp = middle_kp
3073 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
3074
3075 assert_eq!(first_char_kp.get(&user_with), Some('M'));
3076 assert_eq!(first_char_kp.get(&user_without), None);
3077 }
3078
3079 #[test]
3080 fn test_kp_inspect() {
3081 #[derive(Debug)]
3082 struct User {
3083 name: String,
3084 }
3085
3086 let user = User {
3087 name: "Alice".to_string(),
3088 };
3089
3090 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3094
3095 let result = name_kp.get(&user);
3098 assert_eq!(result, Some(&"Alice".to_string()));
3099
3100 }
3103
3104 #[test]
3105 fn test_kp_fold_value() {
3106 #[derive(Debug)]
3107 struct User {
3108 scores: Vec<i32>,
3109 }
3110
3111 let user = User {
3112 scores: vec![85, 92, 78, 95],
3113 };
3114
3115 let scores_kp = KpType::new(
3116 |u: &User| Some(&u.scores),
3117 |u: &mut User| Some(&mut u.scores),
3118 );
3119
3120 let sum_fn =
3122 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
3123
3124 assert_eq!(sum_fn(&user), 350);
3125 }
3126
3127 #[test]
3128 fn test_kp_any_all() {
3129 #[derive(Debug)]
3130 struct User {
3131 scores: Vec<i32>,
3132 }
3133
3134 let user_high = User {
3135 scores: vec![85, 92, 88],
3136 };
3137 let user_mixed = User {
3138 scores: vec![65, 92, 78],
3139 };
3140
3141 let scores_kp = KpType::new(
3142 |u: &User| Some(&u.scores),
3143 |u: &mut User| Some(&mut u.scores),
3144 );
3145
3146 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
3148 assert!(has_high_fn(&user_high));
3149 assert!(has_high_fn(&user_mixed));
3150
3151 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
3153 assert!(all_passing_fn(&user_high));
3154 assert!(!all_passing_fn(&user_mixed));
3155 }
3156
3157 #[test]
3158 fn test_kp_count_items() {
3159 #[derive(Debug)]
3160 struct User {
3161 tags: Vec<String>,
3162 }
3163
3164 let user = User {
3165 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
3166 };
3167
3168 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3169 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
3170
3171 assert_eq!(count_fn(&user), Some(3));
3172 }
3173
3174 #[test]
3175 fn test_kp_find_in() {
3176 #[derive(Debug)]
3177 struct User {
3178 scores: Vec<i32>,
3179 }
3180
3181 let user = User {
3182 scores: vec![85, 92, 78, 95, 88],
3183 };
3184
3185 let scores_kp = KpType::new(
3186 |u: &User| Some(&u.scores),
3187 |u: &mut User| Some(&mut u.scores),
3188 );
3189
3190 let first_high_fn =
3192 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3193
3194 assert_eq!(first_high_fn(&user), Some(92));
3195
3196 let perfect_fn =
3198 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3199
3200 assert_eq!(perfect_fn(&user), None);
3201 }
3202
3203 #[test]
3204 fn test_kp_take_skip() {
3205 #[derive(Debug)]
3206 struct User {
3207 tags: Vec<String>,
3208 }
3209
3210 let user = User {
3211 tags: vec![
3212 "a".to_string(),
3213 "b".to_string(),
3214 "c".to_string(),
3215 "d".to_string(),
3216 ],
3217 };
3218
3219 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3220
3221 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3223 tags.iter().take(n).cloned().collect::<Vec<_>>()
3224 });
3225
3226 let taken = take_fn(&user).unwrap();
3227 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3228
3229 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3231 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3232 });
3233
3234 let skipped = skip_fn(&user).unwrap();
3235 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3236 }
3237
3238 #[test]
3239 fn test_kp_partition() {
3240 #[derive(Debug)]
3241 struct User {
3242 scores: Vec<i32>,
3243 }
3244
3245 let user = User {
3246 scores: vec![85, 92, 65, 95, 72, 58],
3247 };
3248
3249 let scores_kp = KpType::new(
3250 |u: &User| Some(&u.scores),
3251 |u: &mut User| Some(&mut u.scores),
3252 );
3253
3254 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3255 scores.iter().copied().partition(|&s| s >= 70)
3256 });
3257
3258 let (passing, failing) = partition_fn(&user).unwrap();
3259 assert_eq!(passing, vec![85, 92, 95, 72]);
3260 assert_eq!(failing, vec![65, 58]);
3261 }
3262
3263 #[test]
3264 fn test_kp_min_max() {
3265 #[derive(Debug)]
3266 struct User {
3267 scores: Vec<i32>,
3268 }
3269
3270 let user = User {
3271 scores: vec![85, 92, 78, 95, 88],
3272 };
3273
3274 let scores_kp = KpType::new(
3275 |u: &User| Some(&u.scores),
3276 |u: &mut User| Some(&mut u.scores),
3277 );
3278
3279 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3281 assert_eq!(min_fn(&user), Some(78));
3282
3283 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3285 assert_eq!(max_fn(&user), Some(95));
3286 }
3287
3288 #[test]
3289 fn test_kp_sum() {
3290 #[derive(Debug)]
3291 struct User {
3292 scores: Vec<i32>,
3293 }
3294
3295 let user = User {
3296 scores: vec![85, 92, 78],
3297 };
3298
3299 let scores_kp = KpType::new(
3300 |u: &User| Some(&u.scores),
3301 |u: &mut User| Some(&mut u.scores),
3302 );
3303
3304 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3305 assert_eq!(sum_fn(&user), Some(255));
3306
3307 let avg_fn =
3309 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3310 assert_eq!(avg_fn.get(&user), Some(85));
3311 }
3312
3313 #[test]
3314 fn test_kp_chain() {
3315 #[derive(Debug)]
3316 struct User {
3317 profile: Profile,
3318 }
3319
3320 #[derive(Debug)]
3321 struct Profile {
3322 settings: Settings,
3323 }
3324
3325 #[derive(Debug)]
3326 struct Settings {
3327 theme: String,
3328 }
3329
3330 let user = User {
3331 profile: Profile {
3332 settings: Settings {
3333 theme: "dark".to_string(),
3334 },
3335 },
3336 };
3337
3338 let profile_kp = KpType::new(
3339 |u: &User| Some(&u.profile),
3340 |u: &mut User| Some(&mut u.profile),
3341 );
3342 let settings_kp = KpType::new(
3343 |p: &Profile| Some(&p.settings),
3344 |p: &mut Profile| Some(&mut p.settings),
3345 );
3346 let theme_kp = KpType::new(
3347 |s: &Settings| Some(&s.theme),
3348 |s: &mut Settings| Some(&mut s.theme),
3349 );
3350
3351 let profile_settings = profile_kp.chain(settings_kp);
3353 let theme_path = profile_settings.chain(theme_kp);
3354 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3355 }
3356
3357 #[test]
3358 fn test_kp_zip() {
3359 #[derive(Debug)]
3360 struct User {
3361 name: String,
3362 age: i32,
3363 }
3364
3365 let user = User {
3366 name: "Alice".to_string(),
3367 age: 30,
3368 };
3369
3370 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3371 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3372
3373 let zipped_fn = zip_kps(&name_kp, &age_kp);
3374 let result = zipped_fn(&user);
3375
3376 assert_eq!(result, Some((&"Alice".to_string(), &30)));
3377 }
3378
3379 #[test]
3380 fn test_kp_complex_pipeline() {
3381 #[derive(Debug)]
3382 struct User {
3383 transactions: Vec<Transaction>,
3384 }
3385
3386 #[derive(Debug)]
3387 struct Transaction {
3388 amount: f64,
3389 category: String,
3390 }
3391
3392 let user = User {
3393 transactions: vec![
3394 Transaction {
3395 amount: 50.0,
3396 category: "food".to_string(),
3397 },
3398 Transaction {
3399 amount: 100.0,
3400 category: "transport".to_string(),
3401 },
3402 Transaction {
3403 amount: 25.0,
3404 category: "food".to_string(),
3405 },
3406 Transaction {
3407 amount: 200.0,
3408 category: "shopping".to_string(),
3409 },
3410 ],
3411 };
3412
3413 let txns_kp = KpType::new(
3414 |u: &User| Some(&u.transactions),
3415 |u: &mut User| Some(&mut u.transactions),
3416 );
3417
3418 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3420 txns.iter()
3421 .filter(|t| t.category == "food")
3422 .map(|t| t.amount)
3423 .sum::<f64>()
3424 });
3425
3426 assert_eq!(food_total.get(&user), Some(75.0));
3427
3428 let has_large =
3430 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3431
3432 assert!(has_large(&user));
3433
3434 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3436 assert_eq!(count(&user), Some(4));
3437 }
3438
3439 #[test]
3443 fn test_no_clone_required_for_root() {
3444 use std::sync::Arc;
3445 use std::sync::atomic::{AtomicUsize, Ordering};
3446
3447 struct NonCloneableRoot {
3450 data: Arc<AtomicUsize>,
3451 cached_value: usize,
3452 }
3453
3454 impl NonCloneableRoot {
3455 fn new() -> Self {
3456 Self {
3457 data: Arc::new(AtomicUsize::new(42)),
3458 cached_value: 42,
3459 }
3460 }
3461
3462 fn increment(&mut self) {
3463 self.data.fetch_add(1, Ordering::SeqCst);
3464 self.cached_value = self.data.load(Ordering::SeqCst);
3465 }
3466
3467 fn get_value(&self) -> &usize {
3468 &self.cached_value
3469 }
3470
3471 fn get_value_mut(&mut self) -> &mut usize {
3472 &mut self.cached_value
3473 }
3474 }
3475
3476 let mut root = NonCloneableRoot::new();
3477
3478 let data_kp = KpType::new(
3480 |r: &NonCloneableRoot| Some(r.get_value()),
3481 |r: &mut NonCloneableRoot| {
3482 r.increment();
3483 Some(r.get_value_mut())
3484 },
3485 );
3486
3487 assert_eq!(data_kp.get(&root), Some(&42));
3489
3490 {
3491 let doubled = data_kp.map(|val: &usize| val * 2);
3493 assert_eq!(doubled.get(&root), Some(84));
3494
3495 let filtered = data_kp.filter(|val: &usize| *val > 0);
3497 assert_eq!(filtered.get(&root), Some(&42));
3498 } let value_ref = data_kp.get_mut(&mut root);
3502 assert!(value_ref.is_some());
3503 }
3504
3505 #[test]
3506 fn test_no_clone_required_for_value() {
3507 use std::sync::Arc;
3508 use std::sync::atomic::{AtomicUsize, Ordering};
3509
3510 struct NonCloneableValue {
3512 counter: Arc<AtomicUsize>,
3513 }
3514
3515 impl NonCloneableValue {
3516 fn new(val: usize) -> Self {
3517 Self {
3518 counter: Arc::new(AtomicUsize::new(val)),
3519 }
3520 }
3521
3522 fn get(&self) -> usize {
3523 self.counter.load(Ordering::SeqCst)
3524 }
3525 }
3526
3527 struct Root {
3528 value: NonCloneableValue,
3529 }
3530
3531 let root = Root {
3532 value: NonCloneableValue::new(100),
3533 };
3534
3535 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3537
3538 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3540 assert_eq!(counter_kp.get(&root), Some(100));
3541
3542 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3544 assert!(filtered.get(&root).is_some());
3545 }
3546
3547 #[test]
3548 fn test_static_does_not_leak_memory() {
3549 use std::sync::Arc;
3550 use std::sync::atomic::{AtomicUsize, Ordering};
3551
3552 static CREATED: AtomicUsize = AtomicUsize::new(0);
3554 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3555
3556 struct Tracked {
3557 id: usize,
3558 }
3559
3560 impl Tracked {
3561 fn new() -> Self {
3562 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3563 Self { id }
3564 }
3565 }
3566
3567 impl Drop for Tracked {
3568 fn drop(&mut self) {
3569 DROPPED.fetch_add(1, Ordering::SeqCst);
3570 }
3571 }
3572
3573 struct Root {
3574 data: Tracked,
3575 }
3576
3577 CREATED.store(0, Ordering::SeqCst);
3579 DROPPED.store(0, Ordering::SeqCst);
3580
3581 {
3582 let root = Root {
3583 data: Tracked::new(),
3584 };
3585
3586 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3587
3588 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3590 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3591 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3592
3593 assert_eq!(mapped1.get(&root), Some(0));
3594 assert_eq!(mapped2.get(&root), Some(1));
3595 assert_eq!(mapped3.get(&root), Some(2));
3596
3597 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3599 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3600 }
3601
3602 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3604 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3605
3606 }
3608
3609 #[test]
3610 fn test_references_not_cloned() {
3611 use std::sync::Arc;
3612
3613 struct ExpensiveData {
3615 large_vec: Vec<u8>,
3616 }
3617
3618 impl ExpensiveData {
3619 fn new(size: usize) -> Self {
3620 Self {
3621 large_vec: vec![0u8; size],
3622 }
3623 }
3624
3625 fn size(&self) -> usize {
3626 self.large_vec.len()
3627 }
3628 }
3629
3630 struct Root {
3631 expensive: ExpensiveData,
3632 }
3633
3634 let root = Root {
3635 expensive: ExpensiveData::new(1_000_000), };
3637
3638 let expensive_kp = KpType::new(
3639 |r: &Root| Some(&r.expensive),
3640 |r: &mut Root| Some(&mut r.expensive),
3641 );
3642
3643 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3645 assert_eq!(size_kp.get(&root), Some(1_000_000));
3646
3647 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3649 assert!(large_filter.get(&root).is_some());
3650
3651 }
3653
3654 #[test]
3655 fn test_hof_with_arc_no_extra_clones() {
3656 use std::sync::Arc;
3657
3658 #[derive(Debug)]
3659 struct SharedData {
3660 value: String,
3661 }
3662
3663 struct Root {
3664 shared: Arc<SharedData>,
3665 }
3666
3667 let shared = Arc::new(SharedData {
3668 value: "shared".to_string(),
3669 });
3670
3671 assert_eq!(Arc::strong_count(&shared), 1);
3673
3674 {
3675 let root = Root {
3676 shared: Arc::clone(&shared),
3677 };
3678
3679 assert_eq!(Arc::strong_count(&shared), 2);
3681
3682 let shared_kp = KpType::new(
3683 |r: &Root| Some(&r.shared),
3684 |r: &mut Root| Some(&mut r.shared),
3685 );
3686
3687 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3689
3690 assert_eq!(value_kp.get(&root), Some(6));
3692 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3696 assert!(filtered.get(&root).is_some());
3697 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3702
3703 #[test]
3704 fn test_closure_captures_not_root_values() {
3705 use std::sync::Arc;
3706 use std::sync::atomic::{AtomicUsize, Ordering};
3707
3708 let call_count = Arc::new(AtomicUsize::new(0));
3710 let call_count_clone = Arc::clone(&call_count);
3711
3712 struct Root {
3713 value: i32,
3714 }
3715
3716 let root = Root { value: 42 };
3717
3718 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3719
3720 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3723 call_count_clone.fetch_add(1, Ordering::SeqCst);
3724 v * 2
3725 });
3726
3727 assert_eq!(doubled(&root), 84);
3729 assert_eq!(doubled(&root), 84);
3730 assert_eq!(doubled(&root), 84);
3731
3732 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3734
3735 }
3737
3738 #[test]
3739 fn test_static_with_borrowed_data() {
3740 struct Root {
3744 data: String,
3745 }
3746
3747 {
3748 let root = Root {
3749 data: "temporary".to_string(),
3750 };
3751
3752 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3753
3754 let len_kp = data_kp.map(|s: &String| s.len());
3756 assert_eq!(len_kp.get(&root), Some(9));
3757
3758 } }
3763
3764 #[test]
3765 fn test_multiple_hof_operations_no_accumulation() {
3766 use std::sync::Arc;
3767 use std::sync::atomic::{AtomicUsize, Ordering};
3768
3769 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3770
3771 struct Tracked {
3772 id: usize,
3773 }
3774
3775 impl Drop for Tracked {
3776 fn drop(&mut self) {
3777 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3778 }
3779 }
3780
3781 struct Root {
3782 values: Vec<Tracked>,
3783 }
3784
3785 DROP_COUNT.store(0, Ordering::SeqCst);
3786
3787 {
3788 let root = Root {
3789 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3790 };
3791
3792 let values_kp = KpType::new(
3793 |r: &Root| Some(&r.values),
3794 |r: &mut Root| Some(&mut r.values),
3795 );
3796
3797 let count = values_kp.count_items(|v| v.len());
3799 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3800 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3801 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3802
3803 assert_eq!(count(&root), Some(3));
3804 assert_eq!(sum(&root), Some(6));
3805 assert!(has_2(&root));
3806 assert!(all_positive(&root));
3807
3808 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3810 }
3811
3812 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3814 }
3815
3816 #[test]
3817 fn test_copy_bound_only_for_function_not_data() {
3818 #[derive(Debug)]
3822 struct NonCopyData {
3823 value: String,
3824 }
3825
3826 struct Root {
3827 data: NonCopyData,
3828 }
3829
3830 let root = Root {
3831 data: NonCopyData {
3832 value: "test".to_string(),
3833 },
3834 };
3835
3836 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3837
3838 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3841 assert_eq!(len_kp.get(&root), Some(4));
3842
3843 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3845 assert!(filtered.get(&root).is_some());
3846 }
3847
3848 #[test]
3849 fn test_no_memory_leak_with_cyclic_references() {
3850 use std::sync::atomic::{AtomicUsize, Ordering};
3851 use std::sync::{Arc, Weak};
3852
3853 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3854
3855 struct Node {
3856 id: usize,
3857 parent: Option<Weak<Node>>,
3858 }
3859
3860 impl Drop for Node {
3861 fn drop(&mut self) {
3862 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3863 }
3864 }
3865
3866 struct Root {
3867 node: Arc<Node>,
3868 }
3869
3870 DROP_COUNT.store(0, Ordering::SeqCst);
3871
3872 {
3873 let root = Root {
3874 node: Arc::new(Node {
3875 id: 1,
3876 parent: None,
3877 }),
3878 };
3879
3880 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3881
3882 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3884 assert_eq!(id_kp.get(&root), Some(1));
3885
3886 assert_eq!(Arc::strong_count(&root.node), 1);
3888
3889 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3891 }
3892
3893 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3895 }
3896
3897 #[test]
3898 fn test_hof_operations_are_zero_cost_abstractions() {
3899 struct Root {
3903 value: i32,
3904 }
3905
3906 let root = Root { value: 10 };
3907
3908 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3909
3910 let direct_result = value_kp.get(&root).map(|v| v * 2);
3912 assert_eq!(direct_result, Some(20));
3913
3914 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3916 let hof_result = mapped_kp.get(&root);
3917 assert_eq!(hof_result, Some(20));
3918
3919 assert_eq!(direct_result, hof_result);
3921 }
3922
3923 #[test]
3924 fn test_complex_closure_captures_allowed() {
3925 use std::sync::Arc;
3926
3927 struct Root {
3929 scores: Vec<i32>,
3930 }
3931
3932 let root = Root {
3933 scores: vec![85, 92, 78, 95, 88],
3934 };
3935
3936 let scores_kp = KpType::new(
3937 |r: &Root| Some(&r.scores),
3938 |r: &mut Root| Some(&mut r.scores),
3939 );
3940
3941 let threshold = 90;
3943 let multiplier = Arc::new(2);
3944
3945 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3947 let high: i32 = scores
3948 .iter()
3949 .filter(|&&s| s >= threshold)
3950 .map(|&s| s * *multiplier)
3951 .sum();
3952 acc + high
3953 });
3954
3955 assert_eq!(high_scores_doubled(&root), 374);
3957 }
3958
3959 #[test]
3963 fn test_pkp_filter_by_value_type() {
3964 use std::any::TypeId;
3965
3966 #[derive(Debug)]
3967 struct User {
3968 name: String,
3969 age: i32,
3970 score: f64,
3971 active: bool,
3972 }
3973
3974 let user = User {
3975 name: "Alice".to_string(),
3976 age: 30,
3977 score: 95.5,
3978 active: true,
3979 };
3980
3981 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3983 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3984 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3985 let active_kp = KpType::new(
3986 |u: &User| Some(&u.active),
3987 |u: &mut User| Some(&mut u.active),
3988 );
3989
3990 let all_keypaths: Vec<PKp<User>> = vec![
3992 PKp::new(name_kp),
3993 PKp::new(age_kp),
3994 PKp::new(score_kp),
3995 PKp::new(active_kp),
3996 ];
3997
3998 let string_kps: Vec<_> = all_keypaths
4000 .iter()
4001 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
4002 .collect();
4003
4004 assert_eq!(string_kps.len(), 1);
4005 assert_eq!(
4006 string_kps[0].get_as::<String>(&user),
4007 Some(&"Alice".to_string())
4008 );
4009
4010 let i32_kps: Vec<_> = all_keypaths
4012 .iter()
4013 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
4014 .collect();
4015
4016 assert_eq!(i32_kps.len(), 1);
4017 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
4018
4019 let f64_kps: Vec<_> = all_keypaths
4021 .iter()
4022 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
4023 .collect();
4024
4025 assert_eq!(f64_kps.len(), 1);
4026 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
4027
4028 let bool_kps: Vec<_> = all_keypaths
4030 .iter()
4031 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
4032 .collect();
4033
4034 assert_eq!(bool_kps.len(), 1);
4035 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
4036 }
4037
4038 #[test]
4039 fn test_pkp_filter_by_struct_type() {
4040 use std::any::TypeId;
4041
4042 #[derive(Debug, PartialEq)]
4043 struct Address {
4044 street: String,
4045 city: String,
4046 }
4047
4048 #[derive(Debug)]
4049 struct User {
4050 name: String,
4051 age: i32,
4052 address: Address,
4053 }
4054
4055 let user = User {
4056 name: "Bob".to_string(),
4057 age: 25,
4058 address: Address {
4059 street: "123 Main St".to_string(),
4060 city: "NYC".to_string(),
4061 },
4062 };
4063
4064 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4066 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4067 let address_kp = KpType::new(
4068 |u: &User| Some(&u.address),
4069 |u: &mut User| Some(&mut u.address),
4070 );
4071
4072 let all_keypaths: Vec<PKp<User>> =
4073 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
4074
4075 let struct_kps: Vec<_> = all_keypaths
4077 .iter()
4078 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
4079 .collect();
4080
4081 assert_eq!(struct_kps.len(), 1);
4082 assert_eq!(
4083 struct_kps[0].get_as::<Address>(&user),
4084 Some(&Address {
4085 street: "123 Main St".to_string(),
4086 city: "NYC".to_string(),
4087 })
4088 );
4089
4090 let primitive_kps: Vec<_> = all_keypaths
4092 .iter()
4093 .filter(|pkp| {
4094 pkp.value_type_id() == TypeId::of::<String>()
4095 || pkp.value_type_id() == TypeId::of::<i32>()
4096 })
4097 .collect();
4098
4099 assert_eq!(primitive_kps.len(), 2);
4100 }
4101
4102 #[test]
4103 fn test_pkp_filter_by_arc_type() {
4104 use std::any::TypeId;
4105 use std::sync::Arc;
4106
4107 #[derive(Debug)]
4108 struct User {
4109 name: String,
4110 shared_data: Arc<String>,
4111 shared_number: Arc<i32>,
4112 }
4113
4114 let user = User {
4115 name: "Charlie".to_string(),
4116 shared_data: Arc::new("shared".to_string()),
4117 shared_number: Arc::new(42),
4118 };
4119
4120 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4122 let shared_data_kp = KpType::new(
4123 |u: &User| Some(&u.shared_data),
4124 |u: &mut User| Some(&mut u.shared_data),
4125 );
4126 let shared_number_kp = KpType::new(
4127 |u: &User| Some(&u.shared_number),
4128 |u: &mut User| Some(&mut u.shared_number),
4129 );
4130
4131 let all_keypaths: Vec<PKp<User>> = vec![
4132 PKp::new(name_kp),
4133 PKp::new(shared_data_kp),
4134 PKp::new(shared_number_kp),
4135 ];
4136
4137 let arc_string_kps: Vec<_> = all_keypaths
4139 .iter()
4140 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
4141 .collect();
4142
4143 assert_eq!(arc_string_kps.len(), 1);
4144 assert_eq!(
4145 arc_string_kps[0]
4146 .get_as::<Arc<String>>(&user)
4147 .map(|arc| arc.as_str()),
4148 Some("shared")
4149 );
4150
4151 let arc_i32_kps: Vec<_> = all_keypaths
4153 .iter()
4154 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
4155 .collect();
4156
4157 assert_eq!(arc_i32_kps.len(), 1);
4158 assert_eq!(
4159 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
4160 Some(42)
4161 );
4162
4163 let all_arc_kps: Vec<_> = all_keypaths
4165 .iter()
4166 .filter(|pkp| {
4167 pkp.value_type_id() == TypeId::of::<Arc<String>>()
4168 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
4169 })
4170 .collect();
4171
4172 assert_eq!(all_arc_kps.len(), 2);
4173 }
4174
4175 #[test]
4176 fn test_pkp_filter_by_box_type() {
4177 use std::any::TypeId;
4178
4179 #[derive(Debug)]
4180 struct User {
4181 name: String,
4182 boxed_value: Box<i32>,
4183 boxed_string: Box<String>,
4184 }
4185
4186 let user = User {
4187 name: "Diana".to_string(),
4188 boxed_value: Box::new(100),
4189 boxed_string: Box::new("boxed".to_string()),
4190 };
4191
4192 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4194 let boxed_value_kp = KpType::new(
4195 |u: &User| Some(&u.boxed_value),
4196 |u: &mut User| Some(&mut u.boxed_value),
4197 );
4198 let boxed_string_kp = KpType::new(
4199 |u: &User| Some(&u.boxed_string),
4200 |u: &mut User| Some(&mut u.boxed_string),
4201 );
4202
4203 let all_keypaths: Vec<PKp<User>> = vec![
4204 PKp::new(name_kp),
4205 PKp::new(boxed_value_kp),
4206 PKp::new(boxed_string_kp),
4207 ];
4208
4209 let box_i32_kps: Vec<_> = all_keypaths
4211 .iter()
4212 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4213 .collect();
4214
4215 assert_eq!(box_i32_kps.len(), 1);
4216 assert_eq!(
4217 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4218 Some(100)
4219 );
4220
4221 let box_string_kps: Vec<_> = all_keypaths
4223 .iter()
4224 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4225 .collect();
4226
4227 assert_eq!(box_string_kps.len(), 1);
4228 assert_eq!(
4229 box_string_kps[0]
4230 .get_as::<Box<String>>(&user)
4231 .map(|b| b.as_str()),
4232 Some("boxed")
4233 );
4234 }
4235
4236 #[test]
4237 fn test_akp_filter_by_root_and_value_type() {
4238 use std::any::TypeId;
4239
4240 #[derive(Debug)]
4241 struct User {
4242 name: String,
4243 age: i32,
4244 }
4245
4246 #[derive(Debug)]
4247 struct Product {
4248 title: String,
4249 price: f64,
4250 }
4251
4252 let user = User {
4253 name: "Eve".to_string(),
4254 age: 28,
4255 };
4256
4257 let product = Product {
4258 title: "Book".to_string(),
4259 price: 19.99,
4260 };
4261
4262 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4264 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4265 let product_title_kp = KpType::new(
4266 |p: &Product| Some(&p.title),
4267 |p: &mut Product| Some(&mut p.title),
4268 );
4269 let product_price_kp = KpType::new(
4270 |p: &Product| Some(&p.price),
4271 |p: &mut Product| Some(&mut p.price),
4272 );
4273
4274 let all_keypaths: Vec<AKp> = vec![
4275 AKp::new(user_name_kp),
4276 AKp::new(user_age_kp),
4277 AKp::new(product_title_kp),
4278 AKp::new(product_price_kp),
4279 ];
4280
4281 let user_kps: Vec<_> = all_keypaths
4283 .iter()
4284 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4285 .collect();
4286
4287 assert_eq!(user_kps.len(), 2);
4288
4289 let product_kps: Vec<_> = all_keypaths
4291 .iter()
4292 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4293 .collect();
4294
4295 assert_eq!(product_kps.len(), 2);
4296
4297 let string_value_kps: Vec<_> = all_keypaths
4299 .iter()
4300 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4301 .collect();
4302
4303 assert_eq!(string_value_kps.len(), 2);
4304
4305 let user_string_kps: Vec<_> = all_keypaths
4307 .iter()
4308 .filter(|akp| {
4309 akp.root_type_id() == TypeId::of::<User>()
4310 && akp.value_type_id() == TypeId::of::<String>()
4311 })
4312 .collect();
4313
4314 assert_eq!(user_string_kps.len(), 1);
4315 assert_eq!(
4316 user_string_kps[0].get_as::<User, String>(&user),
4317 Some(Some(&"Eve".to_string()))
4318 );
4319
4320 let product_f64_kps: Vec<_> = all_keypaths
4322 .iter()
4323 .filter(|akp| {
4324 akp.root_type_id() == TypeId::of::<Product>()
4325 && akp.value_type_id() == TypeId::of::<f64>()
4326 })
4327 .collect();
4328
4329 assert_eq!(product_f64_kps.len(), 1);
4330 assert_eq!(
4331 product_f64_kps[0].get_as::<Product, f64>(&product),
4332 Some(Some(&19.99))
4333 );
4334 }
4335
4336 #[test]
4337 fn test_akp_filter_by_arc_root_type() {
4338 use std::any::TypeId;
4339 use std::sync::Arc;
4340
4341 #[derive(Debug)]
4342 struct User {
4343 name: String,
4344 }
4345
4346 #[derive(Debug)]
4347 struct Product {
4348 title: String,
4349 }
4350
4351 let user = User {
4352 name: "Frank".to_string(),
4353 };
4354 let product = Product {
4355 title: "Laptop".to_string(),
4356 };
4357
4358 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4360 let product_title_kp = KpType::new(
4361 |p: &Product| Some(&p.title),
4362 |p: &mut Product| Some(&mut p.title),
4363 );
4364
4365 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4367 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4368
4369 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4370
4371 let arc_user_kps: Vec<_> = all_keypaths
4373 .iter()
4374 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4375 .collect();
4376
4377 assert_eq!(arc_user_kps.len(), 1);
4378
4379 let arc_user = Arc::new(user);
4381 assert_eq!(
4382 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4383 Some(Some(&"Frank".to_string()))
4384 );
4385
4386 let arc_product_kps: Vec<_> = all_keypaths
4388 .iter()
4389 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4390 .collect();
4391
4392 assert_eq!(arc_product_kps.len(), 1);
4393
4394 let arc_product = Arc::new(product);
4396 assert_eq!(
4397 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4398 Some(Some(&"Laptop".to_string()))
4399 );
4400 }
4401
4402 #[test]
4403 fn test_akp_filter_by_box_root_type() {
4404 use std::any::TypeId;
4405
4406 #[derive(Debug)]
4407 struct Config {
4408 setting: String,
4409 }
4410
4411 let config = Config {
4412 setting: "enabled".to_string(),
4413 };
4414
4415 let config_kp1 = KpType::new(
4417 |c: &Config| Some(&c.setting),
4418 |c: &mut Config| Some(&mut c.setting),
4419 );
4420 let config_kp2 = KpType::new(
4421 |c: &Config| Some(&c.setting),
4422 |c: &mut Config| Some(&mut c.setting),
4423 );
4424
4425 let regular_akp = AKp::new(config_kp1);
4427 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4428
4429 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4430
4431 let config_kps: Vec<_> = all_keypaths
4433 .iter()
4434 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4435 .collect();
4436
4437 assert_eq!(config_kps.len(), 1);
4438 assert_eq!(
4439 config_kps[0].get_as::<Config, String>(&config),
4440 Some(Some(&"enabled".to_string()))
4441 );
4442
4443 let box_config_kps: Vec<_> = all_keypaths
4445 .iter()
4446 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4447 .collect();
4448
4449 assert_eq!(box_config_kps.len(), 1);
4450
4451 let box_config = Box::new(Config {
4453 setting: "enabled".to_string(),
4454 });
4455 assert_eq!(
4456 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4457 Some(Some(&"enabled".to_string()))
4458 );
4459 }
4460
4461 #[test]
4462 fn test_mixed_collection_type_filtering() {
4463 use std::any::TypeId;
4464 use std::sync::Arc;
4465
4466 #[derive(Debug)]
4467 struct User {
4468 name: String,
4469 email: String,
4470 }
4471
4472 #[derive(Debug)]
4473 struct Product {
4474 title: String,
4475 sku: String,
4476 }
4477
4478 let user = User {
4479 name: "Grace".to_string(),
4480 email: "grace@example.com".to_string(),
4481 };
4482
4483 let product = Product {
4484 title: "Widget".to_string(),
4485 sku: "WID-001".to_string(),
4486 };
4487
4488 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4490 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4491 let user_email_kp1 =
4492 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4493 let user_email_kp2 =
4494 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4495 let product_title_kp = KpType::new(
4496 |p: &Product| Some(&p.title),
4497 |p: &mut Product| Some(&mut p.title),
4498 );
4499 let product_sku_kp = KpType::new(
4500 |p: &Product| Some(&p.sku),
4501 |p: &mut Product| Some(&mut p.sku),
4502 );
4503
4504 let all_keypaths: Vec<AKp> = vec![
4505 AKp::new(user_name_kp1),
4506 AKp::new(user_email_kp1),
4507 AKp::new(product_title_kp),
4508 AKp::new(product_sku_kp),
4509 AKp::new(user_name_kp2).for_arc::<User>(),
4510 AKp::new(user_email_kp2).for_box::<User>(),
4511 ];
4512
4513 let string_value_kps: Vec<_> = all_keypaths
4515 .iter()
4516 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4517 .collect();
4518
4519 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4523 .iter()
4524 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4525 .collect();
4526
4527 assert_eq!(user_root_kps.len(), 2);
4528
4529 let arc_user_kps: Vec<_> = all_keypaths
4531 .iter()
4532 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4533 .collect();
4534
4535 assert_eq!(arc_user_kps.len(), 1);
4536
4537 let box_user_kps: Vec<_> = all_keypaths
4539 .iter()
4540 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4541 .collect();
4542
4543 assert_eq!(box_user_kps.len(), 1);
4544
4545 let product_kps: Vec<_> = all_keypaths
4547 .iter()
4548 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4549 .collect();
4550
4551 assert_eq!(product_kps.len(), 2);
4552
4553 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4555 assert!(user_value.is_some());
4556 assert!(user_value.unwrap().is_some());
4557 }
4558
4559 #[test]
4564 fn test_kp_with_pin() {
4565 use std::pin::Pin;
4566
4567 #[derive(Debug)]
4571 struct SelfReferential {
4572 value: String,
4573 ptr_to_value: *const String, }
4575
4576 impl SelfReferential {
4577 fn new(s: String) -> Self {
4578 let mut sr = Self {
4579 value: s,
4580 ptr_to_value: std::ptr::null(),
4581 };
4582 sr.ptr_to_value = &sr.value as *const String;
4584 sr
4585 }
4586
4587 fn get_value(&self) -> &str {
4588 &self.value
4589 }
4590 }
4591
4592 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4594 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4595
4596 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4598 |p: &Pin<Box<SelfReferential>>| {
4599 Some(&p.as_ref().get_ref().value)
4601 },
4602 |p: &mut Pin<Box<SelfReferential>>| {
4603 unsafe {
4606 let sr = Pin::get_unchecked_mut(p.as_mut());
4607 Some(&mut sr.value)
4608 }
4609 },
4610 );
4611
4612 let result = kp.get(&pinned);
4614 assert_eq!(result, Some(&"pinned_data".to_string()));
4615
4616 assert_eq!(pinned.get_value(), "pinned_data");
4618 }
4619
4620 #[test]
4621 fn test_kp_with_pin_arc() {
4622 use std::pin::Pin;
4623 use std::sync::Arc;
4624
4625 struct AsyncState {
4626 status: String,
4627 data: Vec<i32>,
4628 }
4629
4630 let state = AsyncState {
4632 status: "ready".to_string(),
4633 data: vec![1, 2, 3, 4, 5],
4634 };
4635
4636 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4637
4638 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4640 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4641 |_: &mut Pin<Arc<AsyncState>>| {
4642 None::<&mut String>
4644 },
4645 );
4646
4647 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4649 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4650 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4651 );
4652
4653 let status = status_kp.get(&pinned_arc);
4654 assert_eq!(status, Some(&"ready".to_string()));
4655
4656 let data = data_kp.get(&pinned_arc);
4657 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4658 }
4659
4660 #[test]
4661 fn test_kp_with_maybe_uninit() {
4662 use std::mem::MaybeUninit;
4663
4664 struct Config {
4668 name: MaybeUninit<String>,
4669 value: MaybeUninit<i32>,
4670 initialized: bool,
4671 }
4672
4673 impl Config {
4674 fn new_uninit() -> Self {
4675 Self {
4676 name: MaybeUninit::uninit(),
4677 value: MaybeUninit::uninit(),
4678 initialized: false,
4679 }
4680 }
4681
4682 fn init(&mut self, name: String, value: i32) {
4683 self.name.write(name);
4684 self.value.write(value);
4685 self.initialized = true;
4686 }
4687
4688 fn get_name(&self) -> Option<&String> {
4689 if self.initialized {
4690 unsafe { Some(self.name.assume_init_ref()) }
4691 } else {
4692 None
4693 }
4694 }
4695
4696 fn get_value(&self) -> Option<&i32> {
4697 if self.initialized {
4698 unsafe { Some(self.value.assume_init_ref()) }
4699 } else {
4700 None
4701 }
4702 }
4703 }
4704
4705 let name_kp: KpType<Config, String> = Kp::new(
4707 |c: &Config| c.get_name(),
4708 |c: &mut Config| {
4709 if c.initialized {
4710 unsafe { Some(c.name.assume_init_mut()) }
4711 } else {
4712 None
4713 }
4714 },
4715 );
4716
4717 let value_kp: KpType<Config, i32> = Kp::new(
4718 |c: &Config| c.get_value(),
4719 |c: &mut Config| {
4720 if c.initialized {
4721 unsafe { Some(c.value.assume_init_mut()) }
4722 } else {
4723 None
4724 }
4725 },
4726 );
4727
4728 let uninit_config = Config::new_uninit();
4730 assert_eq!(name_kp.get(&uninit_config), None);
4731 assert_eq!(value_kp.get(&uninit_config), None);
4732
4733 let mut init_config = Config::new_uninit();
4735 init_config.init("test_config".to_string(), 42);
4736
4737 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4738 assert_eq!(value_kp.get(&init_config), Some(&42));
4739
4740 if let Some(val) = value_kp.get_mut(&mut init_config) {
4742 *val = 100;
4743 }
4744
4745 assert_eq!(value_kp.get(&init_config), Some(&100));
4746 }
4747
4748 #[test]
4749 fn test_kp_with_weak() {
4750 use std::sync::{Arc, Weak};
4751
4752 #[derive(Debug, Clone)]
4756 struct Node {
4757 value: i32,
4758 }
4759
4760 struct NodeWithParent {
4761 value: i32,
4762 parent: Option<Arc<Node>>, }
4764
4765 let parent = Arc::new(Node { value: 100 });
4766
4767 let child = NodeWithParent {
4768 value: 42,
4769 parent: Some(parent.clone()),
4770 };
4771
4772 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4774 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4775 |_: &mut NodeWithParent| None::<&mut i32>,
4776 );
4777
4778 let parent_val = parent_value_kp.get(&child);
4780 assert_eq!(parent_val, Some(&100));
4781 }
4782
4783 #[test]
4784 fn test_kp_with_rc_weak() {
4785 use std::rc::Rc;
4786
4787 struct TreeNode {
4790 value: String,
4791 parent: Option<Rc<TreeNode>>, }
4793
4794 let root = Rc::new(TreeNode {
4795 value: "root".to_string(),
4796 parent: None,
4797 });
4798
4799 let child1 = TreeNode {
4800 value: "child1".to_string(),
4801 parent: Some(root.clone()),
4802 };
4803
4804 let child2 = TreeNode {
4805 value: "child2".to_string(),
4806 parent: Some(root.clone()),
4807 };
4808
4809 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4811 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4812 |_: &mut TreeNode| None::<&mut String>,
4813 );
4814
4815 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4817 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4818
4819 assert_eq!(parent_name_kp.get(&root), None);
4821 }
4822
4823 #[test]
4824 fn test_kp_with_complex_weak_structure() {
4825 use std::sync::Arc;
4826
4827 struct Cache {
4830 data: String,
4831 backup: Option<Arc<Cache>>, }
4833
4834 let primary = Arc::new(Cache {
4835 data: "primary_data".to_string(),
4836 backup: None,
4837 });
4838
4839 let backup = Arc::new(Cache {
4840 data: "backup_data".to_string(),
4841 backup: Some(primary.clone()),
4842 });
4843
4844 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4846 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4847 |_: &mut Arc<Cache>| None::<&mut String>,
4848 );
4849
4850 let data = backup_data_kp.get(&backup);
4852 assert_eq!(data, Some(&"primary_data".to_string()));
4853
4854 let no_backup = backup_data_kp.get(&primary);
4856 assert_eq!(no_backup, None);
4857 }
4858
4859 #[test]
4860 fn test_kp_chain_with_pin_and_arc() {
4861 use std::pin::Pin;
4862 use std::sync::Arc;
4863
4864 struct Outer {
4867 inner: Arc<Inner>,
4868 }
4869
4870 struct Inner {
4871 value: String,
4872 }
4873
4874 let outer = Outer {
4875 inner: Arc::new(Inner {
4876 value: "nested_value".to_string(),
4877 }),
4878 };
4879
4880 let pinned_outer = Box::pin(outer);
4881
4882 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4884 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4885 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4886 );
4887
4888 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4890 |a: &Arc<Inner>| Some(&a.value),
4891 |_: &mut Arc<Inner>| None::<&mut String>,
4892 );
4893
4894 let chained = to_inner.then(to_value);
4896
4897 let result = chained.get(&pinned_outer);
4898 assert_eq!(result, Some(&"nested_value".to_string()));
4899 }
4900
4901 #[test]
4902 fn test_kp_with_maybe_uninit_array() {
4903 use std::mem::MaybeUninit;
4904
4905 struct Buffer {
4909 data: [MaybeUninit<u8>; 10],
4910 len: usize,
4911 }
4912
4913 impl Buffer {
4914 fn new() -> Self {
4915 Self {
4916 data: unsafe { MaybeUninit::uninit().assume_init() },
4917 len: 0,
4918 }
4919 }
4920
4921 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4922 if self.len >= self.data.len() {
4923 return Err("Buffer full");
4924 }
4925 self.data[self.len].write(byte);
4926 self.len += 1;
4927 Ok(())
4928 }
4929
4930 fn get(&self, idx: usize) -> Option<&u8> {
4931 if idx < self.len {
4932 unsafe { Some(self.data[idx].assume_init_ref()) }
4933 } else {
4934 None
4935 }
4936 }
4937
4938 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4939 if idx < self.len {
4940 unsafe { Some(self.data[idx].assume_init_mut()) }
4941 } else {
4942 None
4943 }
4944 }
4945 }
4946
4947 let len_kp: KpType<Buffer, usize> =
4949 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4950
4951 let mut buffer = Buffer::new();
4952
4953 assert_eq!(len_kp.get(&buffer), Some(&0));
4955
4956 buffer.push(1).unwrap();
4958 buffer.push(2).unwrap();
4959 buffer.push(3).unwrap();
4960
4961 assert_eq!(len_kp.get(&buffer), Some(&3));
4963
4964 assert_eq!(buffer.get(0), Some(&1));
4966 assert_eq!(buffer.get(1), Some(&2));
4967 assert_eq!(buffer.get(2), Some(&3));
4968 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4972 *elem = 20;
4973 }
4974 assert_eq!(buffer.get(1), Some(&20));
4975 }
4976
4977 #[test]
4978 fn test_kp_then_lock_deep_structs() {
4979 use std::sync::{Arc, Mutex};
4980
4981 #[derive(Clone)]
4982 struct Root {
4983 guard: Arc<Mutex<Level1>>,
4984 }
4985 #[derive(Clone)]
4986 struct Level1 {
4987 name: String,
4988 nested: Level2,
4989 }
4990 #[derive(Clone)]
4991 struct Level2 {
4992 count: i32,
4993 }
4994
4995 let root = Root {
4996 guard: Arc::new(Mutex::new(Level1 {
4997 name: "deep".to_string(),
4998 nested: Level2 { count: 42 },
4999 })),
5000 };
5001
5002 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
5003 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
5004
5005 let lock_kp = {
5006 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
5007 Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
5008 let next: KpType<Level1, Level1> =
5009 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5010 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5011 };
5012
5013 let chained = kp_to_guard.then_lock(lock_kp);
5014 let level1 = chained.get(&root);
5015 assert!(level1.is_some());
5016 assert_eq!(level1.unwrap().name, "deep");
5017 assert_eq!(level1.unwrap().nested.count, 42);
5018
5019 let mut_root = &mut root.clone();
5020 let mut_level1 = chained.get_mut(mut_root);
5021 assert!(mut_level1.is_some());
5022 mut_level1.unwrap().nested.count = 99;
5023 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
5024 }
5025
5026 #[test]
5027 fn test_kp_then_lock_with_enum() {
5028 use std::sync::{Arc, Mutex};
5029
5030 #[derive(Clone)]
5031 enum Message {
5032 Request(LevelA),
5033 Response(i32),
5034 }
5035 #[derive(Clone)]
5036 struct LevelA {
5037 data: Arc<Mutex<i32>>,
5038 }
5039
5040 struct RootWithEnum {
5041 msg: Arc<Mutex<Message>>,
5042 }
5043
5044 let root = RootWithEnum {
5045 msg: Arc::new(Mutex::new(Message::Request(LevelA {
5046 data: Arc::new(Mutex::new(100)),
5047 }))),
5048 };
5049
5050 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
5051 Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
5052
5053 let lock_kp_msg = {
5054 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
5055 Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
5056 let next: KpType<Message, Message> =
5057 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
5058 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5059 };
5060
5061 let chained = kp_msg.then_lock(lock_kp_msg);
5062 let msg = chained.get(&root);
5063 assert!(msg.is_some());
5064 match msg.unwrap() {
5065 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
5066 Message::Response(_) => panic!("expected Request"),
5067 }
5068 }
5069
5070 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5071 #[tokio::test]
5072 async fn test_kp_then_async_deep_chain() {
5073 use std::sync::Arc;
5074 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5075
5076 #[derive(Clone)]
5077 struct Root {
5078 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
5079 }
5080 #[derive(Clone)]
5081 struct Level1 {
5082 value: i32,
5083 }
5084
5085 let root = Root {
5086 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
5087 };
5088
5089 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
5090 |r: &Root| Some(&r.tokio_guard),
5091 |r: &mut Root| Some(&mut r.tokio_guard),
5092 );
5093
5094 let async_kp = {
5095 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
5096 Kp::new(
5097 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
5098 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
5099 );
5100 let next: KpType<Level1, Level1> =
5101 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5102 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5103 };
5104
5105 let chained = kp_to_guard.then_async(async_kp);
5106 let level1 = chained.get(&root).await;
5107 assert!(level1.is_some());
5108 assert_eq!(level1.unwrap().value, 7);
5109 }
5110
5111 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5114 #[tokio::test]
5115 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
5116 use std::sync::{Arc, Mutex};
5117 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5118 use crate::lock::{LockKp, ArcMutexAccess};
5119
5120 #[derive(Clone)]
5122 struct Root {
5123 sync_mutex: Arc<Mutex<Level1>>,
5124 }
5125 #[derive(Clone)]
5127 struct Level1 {
5128 inner: Level2,
5129 }
5130 #[derive(Clone)]
5132 struct Level2 {
5133 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
5134 }
5135 #[derive(Clone)]
5137 struct Level3 {
5138 leaf: i32,
5139 }
5140
5141 let mut root = Root {
5142 sync_mutex: Arc::new(Mutex::new(Level1 {
5143 inner: Level2 {
5144 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
5145 },
5146 })),
5147 };
5148
5149 let identity_l1: KpType<Level1, Level1> =
5151 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5152 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
5153 Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
5154 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
5155
5156 let kp_l1_inner: KpType<Level1, Level2> =
5158 Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
5159
5160 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
5162 |l: &Level2| Some(&l.tokio_mutex),
5163 |l: &mut Level2| Some(&mut l.tokio_mutex),
5164 );
5165
5166 let async_l3 = {
5168 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
5169 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
5170 let next: KpType<Level3, Level3> =
5171 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
5172 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5173 };
5174
5175 let kp_l3_leaf: KpType<Level3, i32> =
5177 Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
5178
5179 let step1 = lock_root_to_l1.then(kp_l1_inner);
5181 let step2 = step1.then(kp_l2_tokio);
5182 let step3 = step2.then_async(async_l3);
5183 let deep_chain = step3.then(kp_l3_leaf);
5184
5185 let leaf = deep_chain.get(&root).await;
5187 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5188 assert_eq!(leaf, Some(&100));
5189
5190 let mut root_mut = root.clone();
5192 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5193 assert!(leaf_mut.is_some());
5194 *leaf_mut.unwrap() = 99;
5195
5196 let leaf_after = deep_chain.get(&root_mut).await;
5198 assert_eq!(leaf_after, Some(&99));
5199 }
5200}