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 #[inline]
906 pub fn get_optional(&self, root: Option<Root>) -> Option<Value> {
907 root.and_then(|r| (self.get)(r))
908 }
909
910 #[inline]
912 pub fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue> {
913 root.and_then(|r| (self.set)(r))
914 }
915
916 #[inline]
918 pub fn get_or_else<F>(&self, root: Root, f: F) -> Value
919 where
920 F: FnOnce() -> Value,
921 {
922 (self.get)(root).unwrap_or_else(f)
923 }
924
925 #[inline]
927 pub fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
928 where
929 F: FnOnce() -> MutValue,
930 {
931 (self.set)(root).unwrap_or_else(f)
932 }
933
934 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
935 self,
936 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
937 ) -> Kp<
938 R,
939 SV,
940 Root,
941 SubValue,
942 MutRoot,
943 MutSubValue,
944 impl Fn(Root) -> Option<SubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
945 impl Fn(MutRoot) -> Option<MutSubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
946 >
947 where
948 SubValue: std::borrow::Borrow<SV>,
949 MutSubValue: std::borrow::BorrowMut<SV>,
950 G2: Fn(Value) -> Option<SubValue>,
951 S2: Fn(MutValue) -> Option<MutSubValue>,
952 V: 'static,
953 {
954 Kp::new(
955 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
956 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
957 )
958 }
959
960 pub fn then_lock<
962 Lock,
963 Mid,
964 V2,
965 LockValue,
966 MidValue,
967 Value2,
968 MutLock,
969 MutMid,
970 MutValue2,
971 G1,
972 S1,
973 L,
974 G2,
975 S2,
976 >(
977 self,
978 lock_kp: crate::lock::LockKp<
979 V,
980 Lock,
981 Mid,
982 V2,
983 Value,
984 LockValue,
985 MidValue,
986 Value2,
987 MutValue,
988 MutLock,
989 MutMid,
990 MutValue2,
991 G1,
992 S1,
993 L,
994 G2,
995 S2,
996 >,
997 ) -> 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>>
998 where
999 V: 'static + Clone,
1000 V2: 'static,
1001 Value: std::borrow::Borrow<V>,
1002 Value2: std::borrow::Borrow<V2>,
1003 MutValue: std::borrow::BorrowMut<V>,
1004 MutValue2: std::borrow::BorrowMut<V2>,
1005 LockValue: std::borrow::Borrow<Lock>,
1006 MidValue: std::borrow::Borrow<Mid>,
1007 MutLock: std::borrow::BorrowMut<Lock>,
1008 MutMid: std::borrow::BorrowMut<Mid>,
1009 G1: Fn(Value) -> Option<LockValue>,
1010 S1: Fn(MutValue) -> Option<MutLock>,
1011 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
1012 G2: Fn(MidValue) -> Option<Value2>,
1013 S2: Fn(MutMid) -> Option<MutValue2>,
1014 {
1015 crate::lock::KpThenLockKp {
1016 first: self,
1017 second: lock_kp,
1018 _p: std::marker::PhantomData,
1019 }
1020 }
1021
1022 #[cfg(feature = "pin_project")]
1025 pub fn then_pin_future<Struct, Output, L>(
1026 self,
1027 pin_fut: L,
1028 ) -> crate::pin::KpThenPinFuture<
1029 R,
1030 Struct,
1031 Output,
1032 Root,
1033 MutRoot,
1034 Value,
1035 MutValue,
1036 Self,
1037 L,
1038 >
1039 where
1040 V: 'static,
1041 Struct: Unpin + 'static,
1042 Output: 'static,
1043 Value: std::borrow::Borrow<Struct>,
1044 MutValue: std::borrow::BorrowMut<Struct>,
1045 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
1046 {
1047 crate::pin::KpThenPinFuture {
1048 first: self,
1049 second: pin_fut,
1050 _p: std::marker::PhantomData,
1051 }
1052 }
1053
1054 pub fn then_async<AsyncKp>(
1057 self,
1058 async_kp: AsyncKp,
1059 ) -> crate::async_lock::KpThenAsyncKeyPath<
1060 R,
1061 V,
1062 <AsyncKp::Value as KeyPathValueTarget>::Target,
1063 Root,
1064 Value,
1065 AsyncKp::Value,
1066 MutRoot,
1067 MutValue,
1068 AsyncKp::MutValue,
1069 Self,
1070 AsyncKp,
1071 >
1072 where
1073 V: 'static,
1074 Value: std::borrow::Borrow<V>,
1075 MutValue: std::borrow::BorrowMut<V>,
1076 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
1077 AsyncKp::Value: KeyPathValueTarget
1078 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1079 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1080 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
1081 {
1082 crate::async_lock::KpThenAsyncKeyPath {
1083 first: self,
1084 second: async_kp,
1085 _p: std::marker::PhantomData,
1086 }
1087 }
1088
1089 pub fn map<MappedValue, F>(
1102 &self,
1103 mapper: F,
1104 ) -> Kp<
1105 R,
1106 MappedValue,
1107 Root,
1108 MappedValue,
1109 MutRoot,
1110 MappedValue,
1111 impl Fn(Root) -> Option<MappedValue>,
1112 impl Fn(MutRoot) -> Option<MappedValue>,
1113 >
1114 where
1115 F: Fn(&V) -> MappedValue + Copy + 'static,
1118 V: 'static,
1119 MappedValue: 'static,
1120 {
1121 Kp::new(
1122 move |root: Root| {
1123 (&self.get)(root).map(|value| {
1124 let v: &V = value.borrow();
1125 mapper(v)
1126 })
1127 },
1128 move |root: MutRoot| {
1129 (&self.set)(root).map(|value| {
1130 let v: &V = value.borrow();
1131 mapper(v)
1132 })
1133 },
1134 )
1135 }
1136
1137 pub fn filter<F>(
1150 &self,
1151 predicate: F,
1152 ) -> Kp<
1153 R,
1154 V,
1155 Root,
1156 Value,
1157 MutRoot,
1158 MutValue,
1159 impl Fn(Root) -> Option<Value>,
1160 impl Fn(MutRoot) -> Option<MutValue>,
1161 >
1162 where
1163 F: Fn(&V) -> bool + Copy + 'static,
1166 V: 'static,
1167 {
1168 Kp::new(
1169 move |root: Root| {
1170 (&self.get)(root).filter(|value| {
1171 let v: &V = value.borrow();
1172 predicate(v)
1173 })
1174 },
1175 move |root: MutRoot| {
1176 (&self.set)(root).filter(|value| {
1177 let v: &V = value.borrow();
1178 predicate(v)
1179 })
1180 },
1181 )
1182 }
1183
1184 pub fn filter_map<MappedValue, F>(
1197 &self,
1198 mapper: F,
1199 ) -> Kp<
1200 R,
1201 MappedValue,
1202 Root,
1203 MappedValue,
1204 MutRoot,
1205 MappedValue,
1206 impl Fn(Root) -> Option<MappedValue>,
1207 impl Fn(MutRoot) -> Option<MappedValue>,
1208 >
1209 where
1210 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1213 V: 'static,
1214 MappedValue: 'static,
1215 {
1216 Kp::new(
1217 move |root: Root| {
1218 (&self.get)(root).and_then(|value| {
1219 let v: &V = value.borrow();
1220 mapper(v)
1221 })
1222 },
1223 move |root: MutRoot| {
1224 (&self.set)(root).and_then(|value| {
1225 let v: &V = value.borrow();
1226 mapper(v)
1227 })
1228 },
1229 )
1230 }
1231
1232 pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
1244 where
1245 F: Fn(&V) -> I + 'static,
1248 V: 'static,
1249 I: IntoIterator<Item = Item>,
1250 Item: 'static,
1251 {
1252 move |root: Root| {
1253 (&self.get)(root)
1254 .map(|value| {
1255 let v: &V = value.borrow();
1256 mapper(v).into_iter().collect()
1257 })
1258 .unwrap_or_else(Vec::new)
1259 }
1260 }
1261
1262 pub fn inspect<F>(
1273 &self,
1274 inspector: F,
1275 ) -> Kp<
1276 R,
1277 V,
1278 Root,
1279 Value,
1280 MutRoot,
1281 MutValue,
1282 impl Fn(Root) -> Option<Value>,
1283 impl Fn(MutRoot) -> Option<MutValue>,
1284 >
1285 where
1286 F: Fn(&V) + Copy + 'static,
1289 V: 'static,
1290 {
1291 Kp::new(
1292 move |root: Root| {
1293 (&self.get)(root).map(|value| {
1294 let v: &V = value.borrow();
1295 inspector(v);
1296 value
1297 })
1298 },
1299 move |root: MutRoot| {
1300 (&self.set)(root).map(|value| {
1301 let v: &V = value.borrow();
1302 inspector(v);
1303 value
1304 })
1305 },
1306 )
1307 }
1308
1309 pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
1323 where
1324 F: Fn(Acc, &V) -> Acc + 'static,
1327 V: 'static,
1328 Acc: Copy + 'static,
1330 {
1331 move |root: Root| {
1332 (&self.get)(root)
1333 .map(|value| {
1334 let v: &V = value.borrow();
1335 folder(init, v)
1336 })
1337 .unwrap_or(init)
1338 }
1339 }
1340
1341 pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1353 where
1354 F: Fn(&V) -> bool + 'static,
1357 V: 'static,
1358 {
1359 move |root: Root| {
1360 (&self.get)(root)
1361 .map(|value| {
1362 let v: &V = value.borrow();
1363 predicate(v)
1364 })
1365 .unwrap_or(false)
1366 }
1367 }
1368
1369 pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1381 where
1382 F: Fn(&V) -> bool + 'static,
1385 V: 'static,
1386 {
1387 move |root: Root| {
1388 (&self.get)(root)
1389 .map(|value| {
1390 let v: &V = value.borrow();
1391 predicate(v)
1392 })
1393 .unwrap_or(true)
1394 }
1395 }
1396
1397 pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
1409 where
1410 F: Fn(&V) -> usize + 'static,
1413 V: 'static,
1414 {
1415 move |root: Root| {
1416 (&self.get)(root).map(|value| {
1417 let v: &V = value.borrow();
1418 counter(v)
1419 })
1420 }
1421 }
1422
1423 pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
1437 where
1438 F: Fn(&V) -> Option<Item> + 'static,
1441 V: 'static,
1442 Item: 'static,
1443 {
1444 move |root: Root| {
1445 (&self.get)(root).and_then(|value| {
1446 let v: &V = value.borrow();
1447 finder(v)
1448 })
1449 }
1450 }
1451
1452 pub fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output>
1463 where
1464 F: Fn(&V, usize) -> Output + 'static,
1467 V: 'static,
1468 Output: 'static,
1469 {
1470 move |root: Root| {
1471 (&self.get)(root).map(|value| {
1472 let v: &V = value.borrow();
1473 taker(v, n)
1474 })
1475 }
1476 }
1477
1478 pub fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output>
1489 where
1490 F: Fn(&V, usize) -> Output + 'static,
1493 V: 'static,
1494 Output: 'static,
1495 {
1496 move |root: Root| {
1497 (&self.get)(root).map(|value| {
1498 let v: &V = value.borrow();
1499 skipper(v, n)
1500 })
1501 }
1502 }
1503
1504 pub fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output>
1517 where
1518 F: Fn(&V) -> Output + 'static,
1521 V: 'static,
1522 Output: 'static,
1523 {
1524 move |root: Root| {
1525 (&self.get)(root).map(|value| {
1526 let v: &V = value.borrow();
1527 partitioner(v)
1528 })
1529 }
1530 }
1531
1532 pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
1544 where
1545 F: Fn(&V) -> Option<Item> + 'static,
1548 V: 'static,
1549 Item: 'static,
1550 {
1551 move |root: Root| {
1552 (&self.get)(root).and_then(|value| {
1553 let v: &V = value.borrow();
1554 min_fn(v)
1555 })
1556 }
1557 }
1558
1559 pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
1571 where
1572 F: Fn(&V) -> Option<Item> + 'static,
1575 V: 'static,
1576 Item: 'static,
1577 {
1578 move |root: Root| {
1579 (&self.get)(root).and_then(|value| {
1580 let v: &V = value.borrow();
1581 max_fn(v)
1582 })
1583 }
1584 }
1585
1586 pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
1598 where
1599 F: Fn(&V) -> Sum + 'static,
1602 V: 'static,
1603 Sum: 'static,
1604 {
1605 move |root: Root| {
1606 (&self.get)(root).map(|value| {
1607 let v: &V = value.borrow();
1608 sum_fn(v)
1609 })
1610 }
1611 }
1612
1613 pub fn chain<SV, SubValue, MutSubValue, G2, S2>(
1616 self,
1617 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1618 ) -> Kp<
1619 R,
1620 SV,
1621 Root,
1622 SubValue,
1623 MutRoot,
1624 MutSubValue,
1625 impl Fn(Root) -> Option<SubValue>,
1626 impl Fn(MutRoot) -> Option<MutSubValue>,
1627 >
1628 where
1629 SubValue: std::borrow::Borrow<SV>,
1630 MutSubValue: std::borrow::BorrowMut<SV>,
1631 G2: Fn(Value) -> Option<SubValue>,
1632 S2: Fn(MutValue) -> Option<MutSubValue>,
1633 V: 'static,
1634 {
1635 self.then(next)
1636 }
1637
1638 pub fn for_arc<'b>(
1639 &self,
1640 ) -> Kp<
1641 std::sync::Arc<R>,
1642 V,
1643 std::sync::Arc<R>,
1644 Value,
1645 std::sync::Arc<R>,
1646 MutValue,
1647 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1648 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1649 >
1650 where
1651 R: 'b,
1652 V: 'b,
1653 Root: for<'a> From<&'a R>,
1654 MutRoot: for<'a> From<&'a mut R>,
1655 {
1656 Kp::new(
1657 move |arc_root: std::sync::Arc<R>| {
1658 let r_ref: &R = &*arc_root;
1659 (&self.get)(Root::from(r_ref))
1660 },
1661 move |mut arc_root: std::sync::Arc<R>| {
1662 std::sync::Arc::get_mut(&mut arc_root)
1664 .and_then(|r_mut| (&self.set)(MutRoot::from(r_mut)))
1665 },
1666 )
1667 }
1668
1669 pub fn for_box<'a>(
1670 &self,
1671 ) -> Kp<
1672 Box<R>,
1673 V,
1674 Box<R>,
1675 Value,
1676 Box<R>,
1677 MutValue,
1678 impl Fn(Box<R>) -> Option<Value>,
1679 impl Fn(Box<R>) -> Option<MutValue>,
1680 >
1681 where
1682 R: 'a,
1683 V: 'a,
1684 Root: for<'b> From<&'b R>,
1685 MutRoot: for<'b> From<&'b mut R>,
1686 {
1687 Kp::new(
1688 move |r: Box<R>| {
1689 let r_ref: &R = r.as_ref();
1690 (&self.get)(Root::from(r_ref))
1691 },
1692 move |mut r: Box<R>| {
1693 (self.set)(MutRoot::from(r.as_mut()))
1695 },
1696 )
1697 }
1698}
1699
1700pub fn zip_kps<'a, RootType, Value1, Value2>(
1714 kp1: &'a KpType<'a, RootType, Value1>,
1715 kp2: &'a KpType<'a, RootType, Value2>,
1716) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1717where
1718 RootType: 'a,
1719 Value1: 'a,
1720 Value2: 'a,
1721{
1722 move |root: &'a RootType| {
1723 let val1 = (kp1.get)(root)?;
1724 let val2 = (kp2.get)(root)?;
1725 Some((val1, val2))
1726 }
1727}
1728
1729impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1730where
1731 Root: std::borrow::Borrow<R>,
1732 MutRoot: std::borrow::BorrowMut<R>,
1733 G: Fn(Root) -> Option<Root>,
1734 S: Fn(MutRoot) -> Option<MutRoot>,
1735{
1736 pub fn identity_typed() -> Kp<
1737 R,
1738 R,
1739 Root,
1740 Root,
1741 MutRoot,
1742 MutRoot,
1743 fn(Root) -> Option<Root>,
1744 fn(MutRoot) -> Option<MutRoot>,
1745 > {
1746 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1747 }
1748
1749 pub fn identity<'a>() -> KpType<'a, R, R> {
1750 KpType::new(|r| Some(r), |r| Some(r))
1751 }
1752}
1753
1754pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1763where
1764 Root: std::borrow::Borrow<Enum>,
1765 Value: std::borrow::Borrow<Variant>,
1766 MutRoot: std::borrow::BorrowMut<Enum>,
1767 MutValue: std::borrow::BorrowMut<Variant>,
1768 G: Fn(Root) -> Option<Value>,
1769 S: Fn(MutRoot) -> Option<MutValue>,
1770 E: Fn(Variant) -> Enum,
1771{
1772 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1773 embedder: E,
1774}
1775
1776unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1778 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1779where
1780 Root: std::borrow::Borrow<Enum>,
1781 Value: std::borrow::Borrow<Variant>,
1782 MutRoot: std::borrow::BorrowMut<Enum>,
1783 MutValue: std::borrow::BorrowMut<Variant>,
1784 G: Fn(Root) -> Option<Value> + Send,
1785 S: Fn(MutRoot) -> Option<MutValue> + Send,
1786 E: Fn(Variant) -> Enum + Send,
1787{
1788}
1789unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1790 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1791where
1792 Root: std::borrow::Borrow<Enum>,
1793 Value: std::borrow::Borrow<Variant>,
1794 MutRoot: std::borrow::BorrowMut<Enum>,
1795 MutValue: std::borrow::BorrowMut<Variant>,
1796 G: Fn(Root) -> Option<Value> + Sync,
1797 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1798 E: Fn(Variant) -> Enum + Sync,
1799{
1800}
1801
1802impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1803 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1804where
1805 Root: std::borrow::Borrow<Enum>,
1806 Value: std::borrow::Borrow<Variant>,
1807 MutRoot: std::borrow::BorrowMut<Enum>,
1808 MutValue: std::borrow::BorrowMut<Variant>,
1809 G: Fn(Root) -> Option<Value>,
1810 S: Fn(MutRoot) -> Option<MutValue>,
1811 E: Fn(Variant) -> Enum,
1812{
1813 pub fn new(
1815 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1816 embedder: E,
1817 ) -> Self {
1818 Self {
1819 extractor,
1820 embedder,
1821 }
1822 }
1823
1824 pub fn get(&self, enum_value: Root) -> Option<Value> {
1826 self.extractor.get(enum_value)
1827 }
1828
1829 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1831 self.extractor.get_mut(enum_value)
1832 }
1833
1834 pub fn embed(&self, value: Variant) -> Enum {
1836 (self.embedder)(value)
1837 }
1838
1839 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1841 &self.extractor
1842 }
1843
1844 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1846 self.extractor
1847 }
1848
1849 pub fn map<MappedValue, F>(
1860 &self,
1861 mapper: F,
1862 ) -> EnumKp<
1863 Enum,
1864 MappedValue,
1865 Root,
1866 MappedValue,
1867 MutRoot,
1868 MappedValue,
1869 impl Fn(Root) -> Option<MappedValue>,
1870 impl Fn(MutRoot) -> Option<MappedValue>,
1871 impl Fn(MappedValue) -> Enum,
1872 >
1873 where
1874 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1877 Variant: 'static,
1878 MappedValue: 'static,
1879 E: Fn(Variant) -> Enum + Copy + 'static,
1881 {
1882 let mapped_extractor = self.extractor.map(mapper);
1883
1884 let new_embedder = move |_value: MappedValue| -> Enum {
1888 panic!(
1889 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1890 )
1891 };
1892
1893 EnumKp::new(mapped_extractor, new_embedder)
1894 }
1895
1896 pub fn filter<F>(
1908 &self,
1909 predicate: F,
1910 ) -> EnumKp<
1911 Enum,
1912 Variant,
1913 Root,
1914 Value,
1915 MutRoot,
1916 MutValue,
1917 impl Fn(Root) -> Option<Value>,
1918 impl Fn(MutRoot) -> Option<MutValue>,
1919 E,
1920 >
1921 where
1922 F: Fn(&Variant) -> bool + Copy + 'static,
1925 Variant: 'static,
1926 E: Copy,
1928 {
1929 let filtered_extractor = self.extractor.filter(predicate);
1930 EnumKp::new(filtered_extractor, self.embedder)
1931 }
1932}
1933
1934pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1936 Enum,
1937 Variant,
1938 &'a Enum,
1939 &'a Variant,
1940 &'a mut Enum,
1941 &'a mut Variant,
1942 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1943 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1944 fn(Variant) -> Enum,
1945>;
1946
1947pub fn enum_variant<'a, Enum, Variant>(
1965 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1966 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1967 embedder: fn(Variant) -> Enum,
1968) -> EnumKpType<'a, Enum, Variant> {
1969 EnumKp::new(Kp::new(getter, setter), embedder)
1970}
1971
1972pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1982 EnumKp::new(
1983 Kp::new(
1984 |r: &Result<T, E>| r.as_ref().ok(),
1985 |r: &mut Result<T, E>| r.as_mut().ok(),
1986 ),
1987 |t: T| Ok(t),
1988 )
1989}
1990
1991pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
2001 EnumKp::new(
2002 Kp::new(
2003 |r: &Result<T, E>| r.as_ref().err(),
2004 |r: &mut Result<T, E>| r.as_mut().err(),
2005 ),
2006 |e: E| Err(e),
2007 )
2008}
2009
2010pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
2020 EnumKp::new(
2021 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
2022 |t: T| Some(t),
2023 )
2024}
2025
2026pub fn variant_of<'a, Enum, Variant>(
2044 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2045 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2046 embedder: fn(Variant) -> Enum,
2047) -> EnumKpType<'a, Enum, Variant> {
2048 enum_variant(getter, setter, embedder)
2049}
2050
2051pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
2064 Kp::new(
2065 |b: &Box<T>| Some(b.as_ref()),
2066 |b: &mut Box<T>| Some(b.as_mut()),
2067 )
2068}
2069
2070pub fn kp_arc<'a, T>() -> Kp<
2081 Arc<T>,
2082 T,
2083 &'a Arc<T>,
2084 &'a T,
2085 &'a mut Arc<T>,
2086 &'a mut T,
2087 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
2088 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
2089> {
2090 Kp::new(
2091 |arc: &Arc<T>| Some(arc.as_ref()),
2092 |arc: &mut Arc<T>| Arc::get_mut(arc),
2093 )
2094}
2095
2096pub fn kp_rc<'a, T>() -> Kp<
2107 std::rc::Rc<T>,
2108 T,
2109 &'a std::rc::Rc<T>,
2110 &'a T,
2111 &'a mut std::rc::Rc<T>,
2112 &'a mut T,
2113 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
2114 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
2115> {
2116 Kp::new(
2117 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
2118 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
2119 )
2120}
2121
2122use std::any::{Any, TypeId};
2125use std::rc::Rc;
2126
2127#[cfg(test)]
2142mod tests {
2143 use super::*;
2144 use std::collections::HashMap;
2145
2146 #[derive(Debug)]
2147 struct TestKP {
2148 a: String,
2149 b: String,
2150 c: std::sync::Arc<String>,
2151 d: std::sync::Mutex<String>,
2152 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
2153 f: Option<TestKP2>,
2154 g: HashMap<i32, TestKP2>,
2155 }
2156
2157 impl TestKP {
2158 fn new() -> Self {
2159 Self {
2160 a: String::from("a"),
2161 b: String::from("b"),
2162 c: std::sync::Arc::new(String::from("c")),
2163 d: std::sync::Mutex::new(String::from("d")),
2164 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2165 f: Some(TestKP2 {
2166 a: String::from("a3"),
2167 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2168 }),
2169 g: HashMap::new(),
2170 }
2171 }
2172
2173 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2174 KpComposed::from_closures(
2175 move |r: &TestKP| r.g.get(&index),
2176 move |r: &mut TestKP| r.g.get_mut(&index),
2177 )
2178 }
2179
2180 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2183 TestKP2,
2184 String,
2185 Root,
2186 Value,
2187 MutRoot,
2188 MutValue,
2189 impl Fn(Root) -> Option<Value>,
2190 impl Fn(MutRoot) -> Option<MutValue>,
2191 >
2192 where
2193 Root: std::borrow::Borrow<TestKP2>,
2194 MutRoot: std::borrow::BorrowMut<TestKP2>,
2195 Value: std::borrow::Borrow<String> + From<String>,
2196 MutValue: std::borrow::BorrowMut<String> + From<String>,
2197 {
2198 Kp::new(
2199 |r: Root| Some(Value::from(r.borrow().a.clone())),
2200 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2201 )
2202 }
2203
2204 fn c<'a>() -> KpType<'a, TestKP, String> {
2207 KpType::new(
2208 |r: &TestKP| Some(r.c.as_ref()),
2209 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2210 Some(arc_str) => Some(arc_str),
2211 None => None,
2212 },
2213 )
2214 }
2215
2216 fn a<'a>() -> KpType<'a, TestKP, String> {
2217 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2218 }
2219
2220 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2221 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2222 }
2223
2224 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2225 KpType::identity()
2226 }
2227 }
2228
2229 #[derive(Debug)]
2230 struct TestKP2 {
2231 a: String,
2232 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2233 }
2234
2235 impl TestKP2 {
2236 fn new() -> Self {
2237 TestKP2 {
2238 a: String::from("a2"),
2239 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2240 }
2241 }
2242
2243 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2244 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2251 fn(MutRoot) -> Option<MutRoot>,
2252 >
2253 where
2254 Root: std::borrow::Borrow<TestKP2>,
2255 MutRoot: std::borrow::BorrowMut<TestKP2>,
2256 G: Fn(Root) -> Option<Root>,
2257 S: Fn(MutRoot) -> Option<MutRoot>,
2258 {
2259 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2260 }
2261
2262 fn a<'a>() -> KpType<'a, TestKP2, String> {
2263 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2264 }
2265
2266 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2267 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2268 }
2269
2270 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2275 KpType::identity()
2276 }
2277 }
2278
2279 #[derive(Debug)]
2280 struct TestKP3 {
2281 a: String,
2282 b: std::sync::Arc<std::sync::Mutex<String>>,
2283 }
2284
2285 impl TestKP3 {
2286 fn new() -> Self {
2287 TestKP3 {
2288 a: String::from("a2"),
2289 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2290 }
2291 }
2292
2293 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2294 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2301 fn(MutRoot) -> Option<MutRoot>,
2302 >
2303 where
2304 Root: std::borrow::Borrow<TestKP3>,
2305 MutRoot: std::borrow::BorrowMut<TestKP3>,
2306 G: Fn(Root) -> Option<Root>,
2307 S: Fn(MutRoot) -> Option<MutRoot>,
2308 {
2309 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2310 }
2311
2312 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2313 KpType::identity()
2314 }
2315 }
2316
2317 impl TestKP3 {}
2318
2319 impl TestKP {}
2320 #[test]
2321 fn test_a() {
2322 let instance2 = TestKP2::new();
2323 let mut instance = TestKP::new();
2324 let kp = TestKP::identity();
2325 let kp_a = TestKP::a();
2326 let wres = TestKP::f().then(TestKP2::a()).get_mut(&mut instance).unwrap();
2328 *wres = String::from("a3 changed successfully");
2329 let res = TestKP::f().then(TestKP2::a()).get(&instance);
2330 println!("{:?}", res);
2331 let res = TestKP::f().then(TestKP2::identity()).get(&instance);
2332 println!("{:?}", res);
2333 let res = kp.get(&instance);
2334 println!("{:?}", res);
2335
2336 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2337 println!("{:?}", new_kp_from_hashmap.get(&instance));
2338 }
2339
2340 #[test]
2419 fn test_enum_kp_result_ok() {
2420 let ok_result: Result<String, i32> = Ok("success".to_string());
2421 let mut err_result: Result<String, i32> = Err(42);
2422
2423 let ok_kp = enum_ok();
2424
2425 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2427 assert_eq!(ok_kp.get(&err_result), None);
2428
2429 let embedded = ok_kp.embed("embedded".to_string());
2431 assert_eq!(embedded, Ok("embedded".to_string()));
2432
2433 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2435 *val = "modified".to_string();
2436 }
2437 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2440 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2441 *val = "modified".to_string();
2442 }
2443 assert_eq!(ok_result2, Ok("modified".to_string()));
2444 }
2445
2446 #[test]
2447 fn test_enum_kp_result_err() {
2448 let ok_result: Result<String, i32> = Ok("success".to_string());
2449 let mut err_result: Result<String, i32> = Err(42);
2450
2451 let err_kp = enum_err();
2452
2453 assert_eq!(err_kp.get(&err_result), Some(&42));
2455 assert_eq!(err_kp.get(&ok_result), None);
2456
2457 let embedded = err_kp.embed(99);
2459 assert_eq!(embedded, Err(99));
2460
2461 if let Some(val) = err_kp.get_mut(&mut err_result) {
2463 *val = 100;
2464 }
2465 assert_eq!(err_result, Err(100));
2466 }
2467
2468 #[test]
2469 fn test_enum_kp_option_some() {
2470 let some_opt = Some("value".to_string());
2471 let mut none_opt: Option<String> = None;
2472
2473 let some_kp = enum_some();
2474
2475 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2477 assert_eq!(some_kp.get(&none_opt), None);
2478
2479 let embedded = some_kp.embed("embedded".to_string());
2481 assert_eq!(embedded, Some("embedded".to_string()));
2482
2483 let mut some_opt2 = Some("original".to_string());
2485 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2486 *val = "modified".to_string();
2487 }
2488 assert_eq!(some_opt2, Some("modified".to_string()));
2489 }
2490
2491 #[test]
2492 fn test_enum_kp_custom_enum() {
2493 #[derive(Debug, PartialEq)]
2494 enum MyEnum {
2495 A(String),
2496 B(i32),
2497 C,
2498 }
2499
2500 let mut enum_a = MyEnum::A("hello".to_string());
2501 let enum_b = MyEnum::B(42);
2502 let enum_c = MyEnum::C;
2503
2504 let kp_a = enum_variant(
2506 |e: &MyEnum| match e {
2507 MyEnum::A(s) => Some(s),
2508 _ => None,
2509 },
2510 |e: &mut MyEnum| match e {
2511 MyEnum::A(s) => Some(s),
2512 _ => None,
2513 },
2514 |s: String| MyEnum::A(s),
2515 );
2516
2517 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2519 assert_eq!(kp_a.get(&enum_b), None);
2520 assert_eq!(kp_a.get(&enum_c), None);
2521
2522 let embedded = kp_a.embed("world".to_string());
2524 assert_eq!(embedded, MyEnum::A("world".to_string()));
2525
2526 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2528 *val = "modified".to_string();
2529 }
2530 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2531 }
2532
2533 #[test]
2534 fn test_container_kp_box() {
2535 let boxed = Box::new("value".to_string());
2536 let mut boxed_mut = Box::new("original".to_string());
2537
2538 let box_kp = kp_box();
2539
2540 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2542
2543 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2545 *val = "modified".to_string();
2546 }
2547 assert_eq!(*boxed_mut, "modified".to_string());
2548 }
2549
2550 #[test]
2551 fn test_container_kp_arc() {
2552 let arc = Arc::new("value".to_string());
2553 let mut arc_mut = Arc::new("original".to_string());
2554
2555 let arc_kp = kp_arc();
2556
2557 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2559
2560 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2562 *val = "modified".to_string();
2563 }
2564 assert_eq!(*arc_mut, "modified".to_string());
2565
2566 let arc_shared = Arc::new("shared".to_string());
2568 let arc_shared2 = Arc::clone(&arc_shared);
2569 let mut arc_shared_mut = arc_shared;
2570 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2571 }
2572
2573 #[test]
2574 fn test_enum_kp_composition() {
2575 #[derive(Debug, PartialEq)]
2577 struct Inner {
2578 value: String,
2579 }
2580
2581 let result: Result<Inner, i32> = Ok(Inner {
2582 value: "nested".to_string(),
2583 });
2584
2585 let inner_kp = KpType::new(
2587 |i: &Inner| Some(&i.value),
2588 |i: &mut Inner| Some(&mut i.value),
2589 );
2590
2591 let ok_kp = enum_ok::<Inner, i32>();
2593 let ok_kp_base = ok_kp.into_kp();
2594 let composed = ok_kp_base.then(inner_kp);
2595
2596 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2597 }
2598
2599 #[test]
2600 fn test_pkp_basic() {
2601 #[derive(Debug)]
2602 struct User {
2603 name: String,
2604 age: i32,
2605 }
2606
2607 let user = User {
2608 name: "Alice".to_string(),
2609 age: 30,
2610 };
2611
2612 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2614 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2615
2616 let name_pkp = PKp::new(name_kp);
2618 let age_pkp = PKp::new(age_kp);
2619
2620 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2622 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2623
2624 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2626 assert_eq!(age_pkp.get_as::<String>(&user), None);
2627
2628 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2630 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2631 }
2632
2633 #[test]
2634 fn test_pkp_collection() {
2635 #[derive(Debug)]
2636 struct User {
2637 name: String,
2638 age: i32,
2639 }
2640
2641 let user = User {
2642 name: "Bob".to_string(),
2643 age: 25,
2644 };
2645
2646 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2648 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2649
2650 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2651
2652 let name_value = keypaths[0].get_as::<String>(&user);
2654 let age_value = keypaths[1].get_as::<i32>(&user);
2655
2656 assert_eq!(name_value, Some(&"Bob".to_string()));
2657 assert_eq!(age_value, Some(&25));
2658 }
2659
2660 #[test]
2661 fn test_pkp_for_arc() {
2662 #[derive(Debug)]
2663 struct User {
2664 name: String,
2665 }
2666
2667 let user = Arc::new(User {
2668 name: "Charlie".to_string(),
2669 });
2670
2671 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2672 let name_pkp = PKp::new(name_kp);
2673
2674 let arc_pkp = name_pkp.for_arc();
2676
2677 assert_eq!(
2678 arc_pkp.get_as::<String>(&user),
2679 Some(&"Charlie".to_string())
2680 );
2681 }
2682
2683 #[test]
2684 fn test_pkp_for_option() {
2685 #[derive(Debug)]
2686 struct User {
2687 name: String,
2688 }
2689
2690 let some_user = Some(User {
2691 name: "Diana".to_string(),
2692 });
2693 let none_user: Option<User> = None;
2694
2695 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2696 let name_pkp = PKp::new(name_kp);
2697
2698 let opt_pkp = name_pkp.for_option();
2700
2701 assert_eq!(
2702 opt_pkp.get_as::<String>(&some_user),
2703 Some(&"Diana".to_string())
2704 );
2705 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2706 }
2707
2708 #[test]
2709 fn test_akp_basic() {
2710 #[derive(Debug)]
2711 struct User {
2712 name: String,
2713 age: i32,
2714 }
2715
2716 #[derive(Debug)]
2717 struct Product {
2718 title: String,
2719 price: f64,
2720 }
2721
2722 let user = User {
2723 name: "Eve".to_string(),
2724 age: 28,
2725 };
2726
2727 let product = Product {
2728 title: "Book".to_string(),
2729 price: 19.99,
2730 };
2731
2732 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2734 let user_name_akp = AKp::new(user_name_kp);
2735
2736 let product_title_kp = KpType::new(
2737 |p: &Product| Some(&p.title),
2738 |p: &mut Product| Some(&mut p.title),
2739 );
2740 let product_title_akp = AKp::new(product_title_kp);
2741
2742 assert_eq!(
2744 user_name_akp.get_as::<User, String>(&user),
2745 Some(Some(&"Eve".to_string()))
2746 );
2747 assert_eq!(
2748 product_title_akp.get_as::<Product, String>(&product),
2749 Some(Some(&"Book".to_string()))
2750 );
2751
2752 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2754 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2755
2756 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2758 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2759 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2760 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2761 }
2762
2763 #[test]
2764 fn test_akp_heterogeneous_collection() {
2765 #[derive(Debug)]
2766 struct User {
2767 name: String,
2768 }
2769
2770 #[derive(Debug)]
2771 struct Product {
2772 title: String,
2773 }
2774
2775 let user = User {
2776 name: "Frank".to_string(),
2777 };
2778 let product = Product {
2779 title: "Laptop".to_string(),
2780 };
2781
2782 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2784 let product_title_kp = KpType::new(
2785 |p: &Product| Some(&p.title),
2786 |p: &mut Product| Some(&mut p.title),
2787 );
2788
2789 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2790
2791 let user_any: &dyn Any = &user;
2793 let product_any: &dyn Any = &product;
2794
2795 let user_value = keypaths[0].get(user_any);
2796 let product_value = keypaths[1].get(product_any);
2797
2798 assert!(user_value.is_some());
2799 assert!(product_value.is_some());
2800
2801 assert_eq!(
2803 user_value.and_then(|v| v.downcast_ref::<String>()),
2804 Some(&"Frank".to_string())
2805 );
2806 assert_eq!(
2807 product_value.and_then(|v| v.downcast_ref::<String>()),
2808 Some(&"Laptop".to_string())
2809 );
2810 }
2811
2812 #[test]
2813 fn test_akp_for_option() {
2814 #[derive(Debug)]
2815 struct User {
2816 name: String,
2817 }
2818
2819 let some_user = Some(User {
2820 name: "Grace".to_string(),
2821 });
2822 let none_user: Option<User> = None;
2823
2824 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2825 let name_akp = AKp::new(name_kp);
2826
2827 let opt_akp = name_akp.for_option::<User>();
2829
2830 assert_eq!(
2831 opt_akp.get_as::<Option<User>, String>(&some_user),
2832 Some(Some(&"Grace".to_string()))
2833 );
2834 assert_eq!(
2835 opt_akp.get_as::<Option<User>, String>(&none_user),
2836 Some(None)
2837 );
2838 }
2839
2840 #[test]
2841 fn test_akp_for_result() {
2842 #[derive(Debug)]
2843 struct User {
2844 name: String,
2845 }
2846
2847 let ok_user: Result<User, String> = Ok(User {
2848 name: "Henry".to_string(),
2849 });
2850 let err_user: Result<User, String> = Err("Not found".to_string());
2851
2852 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2853 let name_akp = AKp::new(name_kp);
2854
2855 let result_akp = name_akp.for_result::<User, String>();
2857
2858 assert_eq!(
2859 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2860 Some(Some(&"Henry".to_string()))
2861 );
2862 assert_eq!(
2863 result_akp.get_as::<Result<User, String>, String>(&err_user),
2864 Some(None)
2865 );
2866 }
2867
2868 #[test]
2871 fn test_kp_map() {
2872 #[derive(Debug)]
2873 struct User {
2874 name: String,
2875 age: i32,
2876 }
2877
2878 let user = User {
2879 name: "Alice".to_string(),
2880 age: 30,
2881 };
2882
2883 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2885 let len_kp = name_kp.map(|name: &String| name.len());
2886
2887 assert_eq!(len_kp.get(&user), Some(5));
2888
2889 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2891 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2892
2893 assert_eq!(double_age_kp.get(&user), Some(60));
2894
2895 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2897 assert_eq!(is_adult_kp.get(&user), Some(true));
2898 }
2899
2900 #[test]
2901 fn test_kp_filter() {
2902 #[derive(Debug)]
2903 struct User {
2904 name: String,
2905 age: i32,
2906 }
2907
2908 let adult = User {
2909 name: "Alice".to_string(),
2910 age: 30,
2911 };
2912
2913 let minor = User {
2914 name: "Bob".to_string(),
2915 age: 15,
2916 };
2917
2918 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2919 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2920
2921 assert_eq!(adult_age_kp.get(&adult), Some(&30));
2922 assert_eq!(adult_age_kp.get(&minor), None);
2923
2924 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2926 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2927
2928 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2929 assert_eq!(short_name_kp.get(&adult), None);
2930 }
2931
2932 #[test]
2933 fn test_kp_map_and_filter() {
2934 #[derive(Debug)]
2935 struct User {
2936 scores: Vec<i32>,
2937 }
2938
2939 let user = User {
2940 scores: vec![85, 92, 78, 95],
2941 };
2942
2943 let scores_kp = KpType::new(
2944 |u: &User| Some(&u.scores),
2945 |u: &mut User| Some(&mut u.scores),
2946 );
2947
2948 let avg_kp =
2950 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2951
2952 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2954
2955 assert_eq!(high_avg_kp.get(&user), Some(87)); }
2957
2958 #[test]
2959 fn test_enum_kp_map() {
2960 let ok_result: Result<String, i32> = Ok("hello".to_string());
2961 let err_result: Result<String, i32> = Err(42);
2962
2963 let ok_kp = enum_ok::<String, i32>();
2964 let len_kp = ok_kp.map(|s: &String| s.len());
2965
2966 assert_eq!(len_kp.get(&ok_result), Some(5));
2967 assert_eq!(len_kp.get(&err_result), None);
2968
2969 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2971 let none_opt: Option<Vec<i32>> = None;
2972
2973 let some_kp = enum_some::<Vec<i32>>();
2974 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2975
2976 assert_eq!(count_kp.get(&some_opt), Some(5));
2977 assert_eq!(count_kp.get(&none_opt), None);
2978 }
2979
2980 #[test]
2981 fn test_enum_kp_filter() {
2982 let ok_result1: Result<i32, String> = Ok(42);
2983 let ok_result2: Result<i32, String> = Ok(-5);
2984 let err_result: Result<i32, String> = Err("error".to_string());
2985
2986 let ok_kp = enum_ok::<i32, String>();
2987 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2988
2989 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2990 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2995 let short_str = Some("hi".to_string());
2996
2997 let some_kp = enum_some::<String>();
2998 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2999
3000 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
3001 assert_eq!(long_kp.get(&short_str), None);
3002 }
3003
3004 #[test]
3005 fn test_pkp_filter() {
3006 #[derive(Debug)]
3007 struct User {
3008 name: String,
3009 age: i32,
3010 }
3011
3012 let adult = User {
3013 name: "Alice".to_string(),
3014 age: 30,
3015 };
3016
3017 let minor = User {
3018 name: "Bob".to_string(),
3019 age: 15,
3020 };
3021
3022 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3023 let age_pkp = PKp::new(age_kp);
3024
3025 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
3027
3028 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
3029 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
3030
3031 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3033 let name_pkp = PKp::new(name_kp);
3034 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
3035
3036 assert_eq!(
3037 short_name_pkp.get_as::<String>(&minor),
3038 Some(&"Bob".to_string())
3039 );
3040 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
3041 }
3042
3043 #[test]
3044 fn test_akp_filter() {
3045 #[derive(Debug)]
3046 struct User {
3047 age: i32,
3048 }
3049
3050 #[derive(Debug)]
3051 struct Product {
3052 price: f64,
3053 }
3054
3055 let adult = User { age: 30 };
3056 let minor = User { age: 15 };
3057 let expensive = Product { price: 99.99 };
3058 let cheap = Product { price: 5.0 };
3059
3060 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3062 let age_akp = AKp::new(age_kp);
3063 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
3064
3065 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
3066 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
3067
3068 let price_kp = KpType::new(
3070 |p: &Product| Some(&p.price),
3071 |p: &mut Product| Some(&mut p.price),
3072 );
3073 let price_akp = AKp::new(price_kp);
3074 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
3075
3076 assert_eq!(
3077 expensive_akp.get_as::<Product, f64>(&expensive),
3078 Some(Some(&99.99))
3079 );
3080 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
3081 }
3082
3083 #[test]
3086 fn test_kp_filter_map() {
3087 #[derive(Debug)]
3088 struct User {
3089 middle_name: Option<String>,
3090 }
3091
3092 let user_with = User {
3093 middle_name: Some("Marie".to_string()),
3094 };
3095 let user_without = User { middle_name: None };
3096
3097 let middle_kp = KpType::new(
3098 |u: &User| Some(&u.middle_name),
3099 |u: &mut User| Some(&mut u.middle_name),
3100 );
3101
3102 let first_char_kp = middle_kp
3103 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
3104
3105 assert_eq!(first_char_kp.get(&user_with), Some('M'));
3106 assert_eq!(first_char_kp.get(&user_without), None);
3107 }
3108
3109 #[test]
3110 fn test_kp_inspect() {
3111 #[derive(Debug)]
3112 struct User {
3113 name: String,
3114 }
3115
3116 let user = User {
3117 name: "Alice".to_string(),
3118 };
3119
3120 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3124
3125 let result = name_kp.get(&user);
3128 assert_eq!(result, Some(&"Alice".to_string()));
3129
3130 }
3133
3134 #[test]
3135 fn test_kp_fold_value() {
3136 #[derive(Debug)]
3137 struct User {
3138 scores: Vec<i32>,
3139 }
3140
3141 let user = User {
3142 scores: vec![85, 92, 78, 95],
3143 };
3144
3145 let scores_kp = KpType::new(
3146 |u: &User| Some(&u.scores),
3147 |u: &mut User| Some(&mut u.scores),
3148 );
3149
3150 let sum_fn =
3152 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
3153
3154 assert_eq!(sum_fn(&user), 350);
3155 }
3156
3157 #[test]
3158 fn test_kp_any_all() {
3159 #[derive(Debug)]
3160 struct User {
3161 scores: Vec<i32>,
3162 }
3163
3164 let user_high = User {
3165 scores: vec![85, 92, 88],
3166 };
3167 let user_mixed = User {
3168 scores: vec![65, 92, 78],
3169 };
3170
3171 let scores_kp = KpType::new(
3172 |u: &User| Some(&u.scores),
3173 |u: &mut User| Some(&mut u.scores),
3174 );
3175
3176 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
3178 assert!(has_high_fn(&user_high));
3179 assert!(has_high_fn(&user_mixed));
3180
3181 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
3183 assert!(all_passing_fn(&user_high));
3184 assert!(!all_passing_fn(&user_mixed));
3185 }
3186
3187 #[test]
3188 fn test_kp_count_items() {
3189 #[derive(Debug)]
3190 struct User {
3191 tags: Vec<String>,
3192 }
3193
3194 let user = User {
3195 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
3196 };
3197
3198 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3199 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
3200
3201 assert_eq!(count_fn(&user), Some(3));
3202 }
3203
3204 #[test]
3205 fn test_kp_find_in() {
3206 #[derive(Debug)]
3207 struct User {
3208 scores: Vec<i32>,
3209 }
3210
3211 let user = User {
3212 scores: vec![85, 92, 78, 95, 88],
3213 };
3214
3215 let scores_kp = KpType::new(
3216 |u: &User| Some(&u.scores),
3217 |u: &mut User| Some(&mut u.scores),
3218 );
3219
3220 let first_high_fn =
3222 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3223
3224 assert_eq!(first_high_fn(&user), Some(92));
3225
3226 let perfect_fn =
3228 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3229
3230 assert_eq!(perfect_fn(&user), None);
3231 }
3232
3233 #[test]
3234 fn test_kp_take_skip() {
3235 #[derive(Debug)]
3236 struct User {
3237 tags: Vec<String>,
3238 }
3239
3240 let user = User {
3241 tags: vec![
3242 "a".to_string(),
3243 "b".to_string(),
3244 "c".to_string(),
3245 "d".to_string(),
3246 ],
3247 };
3248
3249 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3250
3251 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3253 tags.iter().take(n).cloned().collect::<Vec<_>>()
3254 });
3255
3256 let taken = take_fn(&user).unwrap();
3257 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3258
3259 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3261 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3262 });
3263
3264 let skipped = skip_fn(&user).unwrap();
3265 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3266 }
3267
3268 #[test]
3269 fn test_kp_partition() {
3270 #[derive(Debug)]
3271 struct User {
3272 scores: Vec<i32>,
3273 }
3274
3275 let user = User {
3276 scores: vec![85, 92, 65, 95, 72, 58],
3277 };
3278
3279 let scores_kp = KpType::new(
3280 |u: &User| Some(&u.scores),
3281 |u: &mut User| Some(&mut u.scores),
3282 );
3283
3284 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3285 scores.iter().copied().partition(|&s| s >= 70)
3286 });
3287
3288 let (passing, failing) = partition_fn(&user).unwrap();
3289 assert_eq!(passing, vec![85, 92, 95, 72]);
3290 assert_eq!(failing, vec![65, 58]);
3291 }
3292
3293 #[test]
3294 fn test_kp_min_max() {
3295 #[derive(Debug)]
3296 struct User {
3297 scores: Vec<i32>,
3298 }
3299
3300 let user = User {
3301 scores: vec![85, 92, 78, 95, 88],
3302 };
3303
3304 let scores_kp = KpType::new(
3305 |u: &User| Some(&u.scores),
3306 |u: &mut User| Some(&mut u.scores),
3307 );
3308
3309 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3311 assert_eq!(min_fn(&user), Some(78));
3312
3313 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3315 assert_eq!(max_fn(&user), Some(95));
3316 }
3317
3318 #[test]
3319 fn test_kp_sum() {
3320 #[derive(Debug)]
3321 struct User {
3322 scores: Vec<i32>,
3323 }
3324
3325 let user = User {
3326 scores: vec![85, 92, 78],
3327 };
3328
3329 let scores_kp = KpType::new(
3330 |u: &User| Some(&u.scores),
3331 |u: &mut User| Some(&mut u.scores),
3332 );
3333
3334 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3335 assert_eq!(sum_fn(&user), Some(255));
3336
3337 let avg_fn =
3339 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3340 assert_eq!(avg_fn.get(&user), Some(85));
3341 }
3342
3343 #[test]
3344 fn test_kp_chain() {
3345 #[derive(Debug)]
3346 struct User {
3347 profile: Profile,
3348 }
3349
3350 #[derive(Debug)]
3351 struct Profile {
3352 settings: Settings,
3353 }
3354
3355 #[derive(Debug)]
3356 struct Settings {
3357 theme: String,
3358 }
3359
3360 let user = User {
3361 profile: Profile {
3362 settings: Settings {
3363 theme: "dark".to_string(),
3364 },
3365 },
3366 };
3367
3368 let profile_kp = KpType::new(
3369 |u: &User| Some(&u.profile),
3370 |u: &mut User| Some(&mut u.profile),
3371 );
3372 let settings_kp = KpType::new(
3373 |p: &Profile| Some(&p.settings),
3374 |p: &mut Profile| Some(&mut p.settings),
3375 );
3376 let theme_kp = KpType::new(
3377 |s: &Settings| Some(&s.theme),
3378 |s: &mut Settings| Some(&mut s.theme),
3379 );
3380
3381 let profile_settings = profile_kp.chain(settings_kp);
3383 let theme_path = profile_settings.chain(theme_kp);
3384 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3385 }
3386
3387 #[test]
3388 fn test_kp_zip() {
3389 #[derive(Debug)]
3390 struct User {
3391 name: String,
3392 age: i32,
3393 }
3394
3395 let user = User {
3396 name: "Alice".to_string(),
3397 age: 30,
3398 };
3399
3400 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3401 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3402
3403 let zipped_fn = zip_kps(&name_kp, &age_kp);
3404 let result = zipped_fn(&user);
3405
3406 assert_eq!(result, Some((&"Alice".to_string(), &30)));
3407 }
3408
3409 #[test]
3410 fn test_kp_complex_pipeline() {
3411 #[derive(Debug)]
3412 struct User {
3413 transactions: Vec<Transaction>,
3414 }
3415
3416 #[derive(Debug)]
3417 struct Transaction {
3418 amount: f64,
3419 category: String,
3420 }
3421
3422 let user = User {
3423 transactions: vec![
3424 Transaction {
3425 amount: 50.0,
3426 category: "food".to_string(),
3427 },
3428 Transaction {
3429 amount: 100.0,
3430 category: "transport".to_string(),
3431 },
3432 Transaction {
3433 amount: 25.0,
3434 category: "food".to_string(),
3435 },
3436 Transaction {
3437 amount: 200.0,
3438 category: "shopping".to_string(),
3439 },
3440 ],
3441 };
3442
3443 let txns_kp = KpType::new(
3444 |u: &User| Some(&u.transactions),
3445 |u: &mut User| Some(&mut u.transactions),
3446 );
3447
3448 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3450 txns.iter()
3451 .filter(|t| t.category == "food")
3452 .map(|t| t.amount)
3453 .sum::<f64>()
3454 });
3455
3456 assert_eq!(food_total.get(&user), Some(75.0));
3457
3458 let has_large =
3460 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3461
3462 assert!(has_large(&user));
3463
3464 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3466 assert_eq!(count(&user), Some(4));
3467 }
3468
3469 #[test]
3473 fn test_no_clone_required_for_root() {
3474 use std::sync::Arc;
3475 use std::sync::atomic::{AtomicUsize, Ordering};
3476
3477 struct NonCloneableRoot {
3480 data: Arc<AtomicUsize>,
3481 cached_value: usize,
3482 }
3483
3484 impl NonCloneableRoot {
3485 fn new() -> Self {
3486 Self {
3487 data: Arc::new(AtomicUsize::new(42)),
3488 cached_value: 42,
3489 }
3490 }
3491
3492 fn increment(&mut self) {
3493 self.data.fetch_add(1, Ordering::SeqCst);
3494 self.cached_value = self.data.load(Ordering::SeqCst);
3495 }
3496
3497 fn get_value(&self) -> &usize {
3498 &self.cached_value
3499 }
3500
3501 fn get_value_mut(&mut self) -> &mut usize {
3502 &mut self.cached_value
3503 }
3504 }
3505
3506 let mut root = NonCloneableRoot::new();
3507
3508 let data_kp = KpType::new(
3510 |r: &NonCloneableRoot| Some(r.get_value()),
3511 |r: &mut NonCloneableRoot| {
3512 r.increment();
3513 Some(r.get_value_mut())
3514 },
3515 );
3516
3517 assert_eq!(data_kp.get(&root), Some(&42));
3519
3520 {
3521 let doubled = data_kp.map(|val: &usize| val * 2);
3523 assert_eq!(doubled.get(&root), Some(84));
3524
3525 let filtered = data_kp.filter(|val: &usize| *val > 0);
3527 assert_eq!(filtered.get(&root), Some(&42));
3528 } let value_ref = data_kp.get_mut(&mut root);
3532 assert!(value_ref.is_some());
3533 }
3534
3535 #[test]
3536 fn test_no_clone_required_for_value() {
3537 use std::sync::Arc;
3538 use std::sync::atomic::{AtomicUsize, Ordering};
3539
3540 struct NonCloneableValue {
3542 counter: Arc<AtomicUsize>,
3543 }
3544
3545 impl NonCloneableValue {
3546 fn new(val: usize) -> Self {
3547 Self {
3548 counter: Arc::new(AtomicUsize::new(val)),
3549 }
3550 }
3551
3552 fn get(&self) -> usize {
3553 self.counter.load(Ordering::SeqCst)
3554 }
3555 }
3556
3557 struct Root {
3558 value: NonCloneableValue,
3559 }
3560
3561 let root = Root {
3562 value: NonCloneableValue::new(100),
3563 };
3564
3565 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3567
3568 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3570 assert_eq!(counter_kp.get(&root), Some(100));
3571
3572 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3574 assert!(filtered.get(&root).is_some());
3575 }
3576
3577 #[test]
3578 fn test_static_does_not_leak_memory() {
3579 use std::sync::Arc;
3580 use std::sync::atomic::{AtomicUsize, Ordering};
3581
3582 static CREATED: AtomicUsize = AtomicUsize::new(0);
3584 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3585
3586 struct Tracked {
3587 id: usize,
3588 }
3589
3590 impl Tracked {
3591 fn new() -> Self {
3592 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3593 Self { id }
3594 }
3595 }
3596
3597 impl Drop for Tracked {
3598 fn drop(&mut self) {
3599 DROPPED.fetch_add(1, Ordering::SeqCst);
3600 }
3601 }
3602
3603 struct Root {
3604 data: Tracked,
3605 }
3606
3607 CREATED.store(0, Ordering::SeqCst);
3609 DROPPED.store(0, Ordering::SeqCst);
3610
3611 {
3612 let root = Root {
3613 data: Tracked::new(),
3614 };
3615
3616 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3617
3618 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3620 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3621 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3622
3623 assert_eq!(mapped1.get(&root), Some(0));
3624 assert_eq!(mapped2.get(&root), Some(1));
3625 assert_eq!(mapped3.get(&root), Some(2));
3626
3627 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3629 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3630 }
3631
3632 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3634 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3635
3636 }
3638
3639 #[test]
3640 fn test_references_not_cloned() {
3641 use std::sync::Arc;
3642
3643 struct ExpensiveData {
3645 large_vec: Vec<u8>,
3646 }
3647
3648 impl ExpensiveData {
3649 fn new(size: usize) -> Self {
3650 Self {
3651 large_vec: vec![0u8; size],
3652 }
3653 }
3654
3655 fn size(&self) -> usize {
3656 self.large_vec.len()
3657 }
3658 }
3659
3660 struct Root {
3661 expensive: ExpensiveData,
3662 }
3663
3664 let root = Root {
3665 expensive: ExpensiveData::new(1_000_000), };
3667
3668 let expensive_kp = KpType::new(
3669 |r: &Root| Some(&r.expensive),
3670 |r: &mut Root| Some(&mut r.expensive),
3671 );
3672
3673 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3675 assert_eq!(size_kp.get(&root), Some(1_000_000));
3676
3677 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3679 assert!(large_filter.get(&root).is_some());
3680
3681 }
3683
3684 #[test]
3685 fn test_hof_with_arc_no_extra_clones() {
3686 use std::sync::Arc;
3687
3688 #[derive(Debug)]
3689 struct SharedData {
3690 value: String,
3691 }
3692
3693 struct Root {
3694 shared: Arc<SharedData>,
3695 }
3696
3697 let shared = Arc::new(SharedData {
3698 value: "shared".to_string(),
3699 });
3700
3701 assert_eq!(Arc::strong_count(&shared), 1);
3703
3704 {
3705 let root = Root {
3706 shared: Arc::clone(&shared),
3707 };
3708
3709 assert_eq!(Arc::strong_count(&shared), 2);
3711
3712 let shared_kp = KpType::new(
3713 |r: &Root| Some(&r.shared),
3714 |r: &mut Root| Some(&mut r.shared),
3715 );
3716
3717 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3719
3720 assert_eq!(value_kp.get(&root), Some(6));
3722 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3726 assert!(filtered.get(&root).is_some());
3727 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3732
3733 #[test]
3734 fn test_closure_captures_not_root_values() {
3735 use std::sync::Arc;
3736 use std::sync::atomic::{AtomicUsize, Ordering};
3737
3738 let call_count = Arc::new(AtomicUsize::new(0));
3740 let call_count_clone = Arc::clone(&call_count);
3741
3742 struct Root {
3743 value: i32,
3744 }
3745
3746 let root = Root { value: 42 };
3747
3748 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3749
3750 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3753 call_count_clone.fetch_add(1, Ordering::SeqCst);
3754 v * 2
3755 });
3756
3757 assert_eq!(doubled(&root), 84);
3759 assert_eq!(doubled(&root), 84);
3760 assert_eq!(doubled(&root), 84);
3761
3762 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3764
3765 }
3767
3768 #[test]
3769 fn test_static_with_borrowed_data() {
3770 struct Root {
3774 data: String,
3775 }
3776
3777 {
3778 let root = Root {
3779 data: "temporary".to_string(),
3780 };
3781
3782 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3783
3784 let len_kp = data_kp.map(|s: &String| s.len());
3786 assert_eq!(len_kp.get(&root), Some(9));
3787
3788 } }
3793
3794 #[test]
3795 fn test_multiple_hof_operations_no_accumulation() {
3796 use std::sync::Arc;
3797 use std::sync::atomic::{AtomicUsize, Ordering};
3798
3799 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3800
3801 struct Tracked {
3802 id: usize,
3803 }
3804
3805 impl Drop for Tracked {
3806 fn drop(&mut self) {
3807 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3808 }
3809 }
3810
3811 struct Root {
3812 values: Vec<Tracked>,
3813 }
3814
3815 DROP_COUNT.store(0, Ordering::SeqCst);
3816
3817 {
3818 let root = Root {
3819 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3820 };
3821
3822 let values_kp = KpType::new(
3823 |r: &Root| Some(&r.values),
3824 |r: &mut Root| Some(&mut r.values),
3825 );
3826
3827 let count = values_kp.count_items(|v| v.len());
3829 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3830 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3831 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3832
3833 assert_eq!(count(&root), Some(3));
3834 assert_eq!(sum(&root), Some(6));
3835 assert!(has_2(&root));
3836 assert!(all_positive(&root));
3837
3838 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3840 }
3841
3842 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3844 }
3845
3846 #[test]
3847 fn test_copy_bound_only_for_function_not_data() {
3848 #[derive(Debug)]
3852 struct NonCopyData {
3853 value: String,
3854 }
3855
3856 struct Root {
3857 data: NonCopyData,
3858 }
3859
3860 let root = Root {
3861 data: NonCopyData {
3862 value: "test".to_string(),
3863 },
3864 };
3865
3866 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3867
3868 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3871 assert_eq!(len_kp.get(&root), Some(4));
3872
3873 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3875 assert!(filtered.get(&root).is_some());
3876 }
3877
3878 #[test]
3879 fn test_no_memory_leak_with_cyclic_references() {
3880 use std::sync::atomic::{AtomicUsize, Ordering};
3881 use std::sync::{Arc, Weak};
3882
3883 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3884
3885 struct Node {
3886 id: usize,
3887 parent: Option<Weak<Node>>,
3888 }
3889
3890 impl Drop for Node {
3891 fn drop(&mut self) {
3892 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3893 }
3894 }
3895
3896 struct Root {
3897 node: Arc<Node>,
3898 }
3899
3900 DROP_COUNT.store(0, Ordering::SeqCst);
3901
3902 {
3903 let root = Root {
3904 node: Arc::new(Node {
3905 id: 1,
3906 parent: None,
3907 }),
3908 };
3909
3910 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3911
3912 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3914 assert_eq!(id_kp.get(&root), Some(1));
3915
3916 assert_eq!(Arc::strong_count(&root.node), 1);
3918
3919 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3921 }
3922
3923 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3925 }
3926
3927 #[test]
3928 fn test_hof_operations_are_zero_cost_abstractions() {
3929 struct Root {
3933 value: i32,
3934 }
3935
3936 let root = Root { value: 10 };
3937
3938 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3939
3940 let direct_result = value_kp.get(&root).map(|v| v * 2);
3942 assert_eq!(direct_result, Some(20));
3943
3944 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3946 let hof_result = mapped_kp.get(&root);
3947 assert_eq!(hof_result, Some(20));
3948
3949 assert_eq!(direct_result, hof_result);
3951 }
3952
3953 #[test]
3954 fn test_complex_closure_captures_allowed() {
3955 use std::sync::Arc;
3956
3957 struct Root {
3959 scores: Vec<i32>,
3960 }
3961
3962 let root = Root {
3963 scores: vec![85, 92, 78, 95, 88],
3964 };
3965
3966 let scores_kp = KpType::new(
3967 |r: &Root| Some(&r.scores),
3968 |r: &mut Root| Some(&mut r.scores),
3969 );
3970
3971 let threshold = 90;
3973 let multiplier = Arc::new(2);
3974
3975 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3977 let high: i32 = scores
3978 .iter()
3979 .filter(|&&s| s >= threshold)
3980 .map(|&s| s * *multiplier)
3981 .sum();
3982 acc + high
3983 });
3984
3985 assert_eq!(high_scores_doubled(&root), 374);
3987 }
3988
3989 #[test]
3993 fn test_pkp_filter_by_value_type() {
3994 use std::any::TypeId;
3995
3996 #[derive(Debug)]
3997 struct User {
3998 name: String,
3999 age: i32,
4000 score: f64,
4001 active: bool,
4002 }
4003
4004 let user = User {
4005 name: "Alice".to_string(),
4006 age: 30,
4007 score: 95.5,
4008 active: true,
4009 };
4010
4011 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4013 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4014 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
4015 let active_kp = KpType::new(
4016 |u: &User| Some(&u.active),
4017 |u: &mut User| Some(&mut u.active),
4018 );
4019
4020 let all_keypaths: Vec<PKp<User>> = vec![
4022 PKp::new(name_kp),
4023 PKp::new(age_kp),
4024 PKp::new(score_kp),
4025 PKp::new(active_kp),
4026 ];
4027
4028 let string_kps: Vec<_> = all_keypaths
4030 .iter()
4031 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
4032 .collect();
4033
4034 assert_eq!(string_kps.len(), 1);
4035 assert_eq!(
4036 string_kps[0].get_as::<String>(&user),
4037 Some(&"Alice".to_string())
4038 );
4039
4040 let i32_kps: Vec<_> = all_keypaths
4042 .iter()
4043 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
4044 .collect();
4045
4046 assert_eq!(i32_kps.len(), 1);
4047 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
4048
4049 let f64_kps: Vec<_> = all_keypaths
4051 .iter()
4052 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
4053 .collect();
4054
4055 assert_eq!(f64_kps.len(), 1);
4056 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
4057
4058 let bool_kps: Vec<_> = all_keypaths
4060 .iter()
4061 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
4062 .collect();
4063
4064 assert_eq!(bool_kps.len(), 1);
4065 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
4066 }
4067
4068 #[test]
4069 fn test_pkp_filter_by_struct_type() {
4070 use std::any::TypeId;
4071
4072 #[derive(Debug, PartialEq)]
4073 struct Address {
4074 street: String,
4075 city: String,
4076 }
4077
4078 #[derive(Debug)]
4079 struct User {
4080 name: String,
4081 age: i32,
4082 address: Address,
4083 }
4084
4085 let user = User {
4086 name: "Bob".to_string(),
4087 age: 25,
4088 address: Address {
4089 street: "123 Main St".to_string(),
4090 city: "NYC".to_string(),
4091 },
4092 };
4093
4094 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4096 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4097 let address_kp = KpType::new(
4098 |u: &User| Some(&u.address),
4099 |u: &mut User| Some(&mut u.address),
4100 );
4101
4102 let all_keypaths: Vec<PKp<User>> =
4103 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
4104
4105 let struct_kps: Vec<_> = all_keypaths
4107 .iter()
4108 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
4109 .collect();
4110
4111 assert_eq!(struct_kps.len(), 1);
4112 assert_eq!(
4113 struct_kps[0].get_as::<Address>(&user),
4114 Some(&Address {
4115 street: "123 Main St".to_string(),
4116 city: "NYC".to_string(),
4117 })
4118 );
4119
4120 let primitive_kps: Vec<_> = all_keypaths
4122 .iter()
4123 .filter(|pkp| {
4124 pkp.value_type_id() == TypeId::of::<String>()
4125 || pkp.value_type_id() == TypeId::of::<i32>()
4126 })
4127 .collect();
4128
4129 assert_eq!(primitive_kps.len(), 2);
4130 }
4131
4132 #[test]
4133 fn test_pkp_filter_by_arc_type() {
4134 use std::any::TypeId;
4135 use std::sync::Arc;
4136
4137 #[derive(Debug)]
4138 struct User {
4139 name: String,
4140 shared_data: Arc<String>,
4141 shared_number: Arc<i32>,
4142 }
4143
4144 let user = User {
4145 name: "Charlie".to_string(),
4146 shared_data: Arc::new("shared".to_string()),
4147 shared_number: Arc::new(42),
4148 };
4149
4150 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4152 let shared_data_kp = KpType::new(
4153 |u: &User| Some(&u.shared_data),
4154 |u: &mut User| Some(&mut u.shared_data),
4155 );
4156 let shared_number_kp = KpType::new(
4157 |u: &User| Some(&u.shared_number),
4158 |u: &mut User| Some(&mut u.shared_number),
4159 );
4160
4161 let all_keypaths: Vec<PKp<User>> = vec![
4162 PKp::new(name_kp),
4163 PKp::new(shared_data_kp),
4164 PKp::new(shared_number_kp),
4165 ];
4166
4167 let arc_string_kps: Vec<_> = all_keypaths
4169 .iter()
4170 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
4171 .collect();
4172
4173 assert_eq!(arc_string_kps.len(), 1);
4174 assert_eq!(
4175 arc_string_kps[0]
4176 .get_as::<Arc<String>>(&user)
4177 .map(|arc| arc.as_str()),
4178 Some("shared")
4179 );
4180
4181 let arc_i32_kps: Vec<_> = all_keypaths
4183 .iter()
4184 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
4185 .collect();
4186
4187 assert_eq!(arc_i32_kps.len(), 1);
4188 assert_eq!(
4189 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
4190 Some(42)
4191 );
4192
4193 let all_arc_kps: Vec<_> = all_keypaths
4195 .iter()
4196 .filter(|pkp| {
4197 pkp.value_type_id() == TypeId::of::<Arc<String>>()
4198 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
4199 })
4200 .collect();
4201
4202 assert_eq!(all_arc_kps.len(), 2);
4203 }
4204
4205 #[test]
4206 fn test_pkp_filter_by_box_type() {
4207 use std::any::TypeId;
4208
4209 #[derive(Debug)]
4210 struct User {
4211 name: String,
4212 boxed_value: Box<i32>,
4213 boxed_string: Box<String>,
4214 }
4215
4216 let user = User {
4217 name: "Diana".to_string(),
4218 boxed_value: Box::new(100),
4219 boxed_string: Box::new("boxed".to_string()),
4220 };
4221
4222 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4224 let boxed_value_kp = KpType::new(
4225 |u: &User| Some(&u.boxed_value),
4226 |u: &mut User| Some(&mut u.boxed_value),
4227 );
4228 let boxed_string_kp = KpType::new(
4229 |u: &User| Some(&u.boxed_string),
4230 |u: &mut User| Some(&mut u.boxed_string),
4231 );
4232
4233 let all_keypaths: Vec<PKp<User>> = vec![
4234 PKp::new(name_kp),
4235 PKp::new(boxed_value_kp),
4236 PKp::new(boxed_string_kp),
4237 ];
4238
4239 let box_i32_kps: Vec<_> = all_keypaths
4241 .iter()
4242 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4243 .collect();
4244
4245 assert_eq!(box_i32_kps.len(), 1);
4246 assert_eq!(
4247 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4248 Some(100)
4249 );
4250
4251 let box_string_kps: Vec<_> = all_keypaths
4253 .iter()
4254 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4255 .collect();
4256
4257 assert_eq!(box_string_kps.len(), 1);
4258 assert_eq!(
4259 box_string_kps[0]
4260 .get_as::<Box<String>>(&user)
4261 .map(|b| b.as_str()),
4262 Some("boxed")
4263 );
4264 }
4265
4266 #[test]
4267 fn test_akp_filter_by_root_and_value_type() {
4268 use std::any::TypeId;
4269
4270 #[derive(Debug)]
4271 struct User {
4272 name: String,
4273 age: i32,
4274 }
4275
4276 #[derive(Debug)]
4277 struct Product {
4278 title: String,
4279 price: f64,
4280 }
4281
4282 let user = User {
4283 name: "Eve".to_string(),
4284 age: 28,
4285 };
4286
4287 let product = Product {
4288 title: "Book".to_string(),
4289 price: 19.99,
4290 };
4291
4292 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4294 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4295 let product_title_kp = KpType::new(
4296 |p: &Product| Some(&p.title),
4297 |p: &mut Product| Some(&mut p.title),
4298 );
4299 let product_price_kp = KpType::new(
4300 |p: &Product| Some(&p.price),
4301 |p: &mut Product| Some(&mut p.price),
4302 );
4303
4304 let all_keypaths: Vec<AKp> = vec![
4305 AKp::new(user_name_kp),
4306 AKp::new(user_age_kp),
4307 AKp::new(product_title_kp),
4308 AKp::new(product_price_kp),
4309 ];
4310
4311 let user_kps: Vec<_> = all_keypaths
4313 .iter()
4314 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4315 .collect();
4316
4317 assert_eq!(user_kps.len(), 2);
4318
4319 let product_kps: Vec<_> = all_keypaths
4321 .iter()
4322 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4323 .collect();
4324
4325 assert_eq!(product_kps.len(), 2);
4326
4327 let string_value_kps: Vec<_> = all_keypaths
4329 .iter()
4330 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4331 .collect();
4332
4333 assert_eq!(string_value_kps.len(), 2);
4334
4335 let user_string_kps: Vec<_> = all_keypaths
4337 .iter()
4338 .filter(|akp| {
4339 akp.root_type_id() == TypeId::of::<User>()
4340 && akp.value_type_id() == TypeId::of::<String>()
4341 })
4342 .collect();
4343
4344 assert_eq!(user_string_kps.len(), 1);
4345 assert_eq!(
4346 user_string_kps[0].get_as::<User, String>(&user),
4347 Some(Some(&"Eve".to_string()))
4348 );
4349
4350 let product_f64_kps: Vec<_> = all_keypaths
4352 .iter()
4353 .filter(|akp| {
4354 akp.root_type_id() == TypeId::of::<Product>()
4355 && akp.value_type_id() == TypeId::of::<f64>()
4356 })
4357 .collect();
4358
4359 assert_eq!(product_f64_kps.len(), 1);
4360 assert_eq!(
4361 product_f64_kps[0].get_as::<Product, f64>(&product),
4362 Some(Some(&19.99))
4363 );
4364 }
4365
4366 #[test]
4367 fn test_akp_filter_by_arc_root_type() {
4368 use std::any::TypeId;
4369 use std::sync::Arc;
4370
4371 #[derive(Debug)]
4372 struct User {
4373 name: String,
4374 }
4375
4376 #[derive(Debug)]
4377 struct Product {
4378 title: String,
4379 }
4380
4381 let user = User {
4382 name: "Frank".to_string(),
4383 };
4384 let product = Product {
4385 title: "Laptop".to_string(),
4386 };
4387
4388 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4390 let product_title_kp = KpType::new(
4391 |p: &Product| Some(&p.title),
4392 |p: &mut Product| Some(&mut p.title),
4393 );
4394
4395 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4397 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4398
4399 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4400
4401 let arc_user_kps: Vec<_> = all_keypaths
4403 .iter()
4404 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4405 .collect();
4406
4407 assert_eq!(arc_user_kps.len(), 1);
4408
4409 let arc_user = Arc::new(user);
4411 assert_eq!(
4412 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4413 Some(Some(&"Frank".to_string()))
4414 );
4415
4416 let arc_product_kps: Vec<_> = all_keypaths
4418 .iter()
4419 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4420 .collect();
4421
4422 assert_eq!(arc_product_kps.len(), 1);
4423
4424 let arc_product = Arc::new(product);
4426 assert_eq!(
4427 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4428 Some(Some(&"Laptop".to_string()))
4429 );
4430 }
4431
4432 #[test]
4433 fn test_akp_filter_by_box_root_type() {
4434 use std::any::TypeId;
4435
4436 #[derive(Debug)]
4437 struct Config {
4438 setting: String,
4439 }
4440
4441 let config = Config {
4442 setting: "enabled".to_string(),
4443 };
4444
4445 let config_kp1 = KpType::new(
4447 |c: &Config| Some(&c.setting),
4448 |c: &mut Config| Some(&mut c.setting),
4449 );
4450 let config_kp2 = KpType::new(
4451 |c: &Config| Some(&c.setting),
4452 |c: &mut Config| Some(&mut c.setting),
4453 );
4454
4455 let regular_akp = AKp::new(config_kp1);
4457 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4458
4459 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4460
4461 let config_kps: Vec<_> = all_keypaths
4463 .iter()
4464 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4465 .collect();
4466
4467 assert_eq!(config_kps.len(), 1);
4468 assert_eq!(
4469 config_kps[0].get_as::<Config, String>(&config),
4470 Some(Some(&"enabled".to_string()))
4471 );
4472
4473 let box_config_kps: Vec<_> = all_keypaths
4475 .iter()
4476 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4477 .collect();
4478
4479 assert_eq!(box_config_kps.len(), 1);
4480
4481 let box_config = Box::new(Config {
4483 setting: "enabled".to_string(),
4484 });
4485 assert_eq!(
4486 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4487 Some(Some(&"enabled".to_string()))
4488 );
4489 }
4490
4491 #[test]
4492 fn test_mixed_collection_type_filtering() {
4493 use std::any::TypeId;
4494 use std::sync::Arc;
4495
4496 #[derive(Debug)]
4497 struct User {
4498 name: String,
4499 email: String,
4500 }
4501
4502 #[derive(Debug)]
4503 struct Product {
4504 title: String,
4505 sku: String,
4506 }
4507
4508 let user = User {
4509 name: "Grace".to_string(),
4510 email: "grace@example.com".to_string(),
4511 };
4512
4513 let product = Product {
4514 title: "Widget".to_string(),
4515 sku: "WID-001".to_string(),
4516 };
4517
4518 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4520 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4521 let user_email_kp1 =
4522 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4523 let user_email_kp2 =
4524 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4525 let product_title_kp = KpType::new(
4526 |p: &Product| Some(&p.title),
4527 |p: &mut Product| Some(&mut p.title),
4528 );
4529 let product_sku_kp = KpType::new(
4530 |p: &Product| Some(&p.sku),
4531 |p: &mut Product| Some(&mut p.sku),
4532 );
4533
4534 let all_keypaths: Vec<AKp> = vec![
4535 AKp::new(user_name_kp1),
4536 AKp::new(user_email_kp1),
4537 AKp::new(product_title_kp),
4538 AKp::new(product_sku_kp),
4539 AKp::new(user_name_kp2).for_arc::<User>(),
4540 AKp::new(user_email_kp2).for_box::<User>(),
4541 ];
4542
4543 let string_value_kps: Vec<_> = all_keypaths
4545 .iter()
4546 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4547 .collect();
4548
4549 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4553 .iter()
4554 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4555 .collect();
4556
4557 assert_eq!(user_root_kps.len(), 2);
4558
4559 let arc_user_kps: Vec<_> = all_keypaths
4561 .iter()
4562 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4563 .collect();
4564
4565 assert_eq!(arc_user_kps.len(), 1);
4566
4567 let box_user_kps: Vec<_> = all_keypaths
4569 .iter()
4570 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4571 .collect();
4572
4573 assert_eq!(box_user_kps.len(), 1);
4574
4575 let product_kps: Vec<_> = all_keypaths
4577 .iter()
4578 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4579 .collect();
4580
4581 assert_eq!(product_kps.len(), 2);
4582
4583 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4585 assert!(user_value.is_some());
4586 assert!(user_value.unwrap().is_some());
4587 }
4588
4589 #[test]
4594 fn test_kp_with_pin() {
4595 use std::pin::Pin;
4596
4597 #[derive(Debug)]
4601 struct SelfReferential {
4602 value: String,
4603 ptr_to_value: *const String, }
4605
4606 impl SelfReferential {
4607 fn new(s: String) -> Self {
4608 let mut sr = Self {
4609 value: s,
4610 ptr_to_value: std::ptr::null(),
4611 };
4612 sr.ptr_to_value = &sr.value as *const String;
4614 sr
4615 }
4616
4617 fn get_value(&self) -> &str {
4618 &self.value
4619 }
4620 }
4621
4622 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4624 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4625
4626 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4628 |p: &Pin<Box<SelfReferential>>| {
4629 Some(&p.as_ref().get_ref().value)
4631 },
4632 |p: &mut Pin<Box<SelfReferential>>| {
4633 unsafe {
4636 let sr = Pin::get_unchecked_mut(p.as_mut());
4637 Some(&mut sr.value)
4638 }
4639 },
4640 );
4641
4642 let result = kp.get(&pinned);
4644 assert_eq!(result, Some(&"pinned_data".to_string()));
4645
4646 assert_eq!(pinned.get_value(), "pinned_data");
4648 }
4649
4650 #[test]
4651 fn test_kp_with_pin_arc() {
4652 use std::pin::Pin;
4653 use std::sync::Arc;
4654
4655 struct AsyncState {
4656 status: String,
4657 data: Vec<i32>,
4658 }
4659
4660 let state = AsyncState {
4662 status: "ready".to_string(),
4663 data: vec![1, 2, 3, 4, 5],
4664 };
4665
4666 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4667
4668 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4670 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4671 |_: &mut Pin<Arc<AsyncState>>| {
4672 None::<&mut String>
4674 },
4675 );
4676
4677 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4679 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4680 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4681 );
4682
4683 let status = status_kp.get(&pinned_arc);
4684 assert_eq!(status, Some(&"ready".to_string()));
4685
4686 let data = data_kp.get(&pinned_arc);
4687 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4688 }
4689
4690 #[test]
4691 fn test_kp_with_maybe_uninit() {
4692 use std::mem::MaybeUninit;
4693
4694 struct Config {
4698 name: MaybeUninit<String>,
4699 value: MaybeUninit<i32>,
4700 initialized: bool,
4701 }
4702
4703 impl Config {
4704 fn new_uninit() -> Self {
4705 Self {
4706 name: MaybeUninit::uninit(),
4707 value: MaybeUninit::uninit(),
4708 initialized: false,
4709 }
4710 }
4711
4712 fn init(&mut self, name: String, value: i32) {
4713 self.name.write(name);
4714 self.value.write(value);
4715 self.initialized = true;
4716 }
4717
4718 fn get_name(&self) -> Option<&String> {
4719 if self.initialized {
4720 unsafe { Some(self.name.assume_init_ref()) }
4721 } else {
4722 None
4723 }
4724 }
4725
4726 fn get_value(&self) -> Option<&i32> {
4727 if self.initialized {
4728 unsafe { Some(self.value.assume_init_ref()) }
4729 } else {
4730 None
4731 }
4732 }
4733 }
4734
4735 let name_kp: KpType<Config, String> = Kp::new(
4737 |c: &Config| c.get_name(),
4738 |c: &mut Config| {
4739 if c.initialized {
4740 unsafe { Some(c.name.assume_init_mut()) }
4741 } else {
4742 None
4743 }
4744 },
4745 );
4746
4747 let value_kp: KpType<Config, i32> = Kp::new(
4748 |c: &Config| c.get_value(),
4749 |c: &mut Config| {
4750 if c.initialized {
4751 unsafe { Some(c.value.assume_init_mut()) }
4752 } else {
4753 None
4754 }
4755 },
4756 );
4757
4758 let uninit_config = Config::new_uninit();
4760 assert_eq!(name_kp.get(&uninit_config), None);
4761 assert_eq!(value_kp.get(&uninit_config), None);
4762
4763 let mut init_config = Config::new_uninit();
4765 init_config.init("test_config".to_string(), 42);
4766
4767 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4768 assert_eq!(value_kp.get(&init_config), Some(&42));
4769
4770 if let Some(val) = value_kp.get_mut(&mut init_config) {
4772 *val = 100;
4773 }
4774
4775 assert_eq!(value_kp.get(&init_config), Some(&100));
4776 }
4777
4778 #[test]
4779 fn test_kp_with_weak() {
4780 use std::sync::{Arc, Weak};
4781
4782 #[derive(Debug, Clone)]
4786 struct Node {
4787 value: i32,
4788 }
4789
4790 struct NodeWithParent {
4791 value: i32,
4792 parent: Option<Arc<Node>>, }
4794
4795 let parent = Arc::new(Node { value: 100 });
4796
4797 let child = NodeWithParent {
4798 value: 42,
4799 parent: Some(parent.clone()),
4800 };
4801
4802 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4804 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4805 |_: &mut NodeWithParent| None::<&mut i32>,
4806 );
4807
4808 let parent_val = parent_value_kp.get(&child);
4810 assert_eq!(parent_val, Some(&100));
4811 }
4812
4813 #[test]
4814 fn test_kp_with_rc_weak() {
4815 use std::rc::Rc;
4816
4817 struct TreeNode {
4820 value: String,
4821 parent: Option<Rc<TreeNode>>, }
4823
4824 let root = Rc::new(TreeNode {
4825 value: "root".to_string(),
4826 parent: None,
4827 });
4828
4829 let child1 = TreeNode {
4830 value: "child1".to_string(),
4831 parent: Some(root.clone()),
4832 };
4833
4834 let child2 = TreeNode {
4835 value: "child2".to_string(),
4836 parent: Some(root.clone()),
4837 };
4838
4839 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4841 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4842 |_: &mut TreeNode| None::<&mut String>,
4843 );
4844
4845 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4847 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4848
4849 assert_eq!(parent_name_kp.get(&root), None);
4851 }
4852
4853 #[test]
4854 fn test_kp_with_complex_weak_structure() {
4855 use std::sync::Arc;
4856
4857 struct Cache {
4860 data: String,
4861 backup: Option<Arc<Cache>>, }
4863
4864 let primary = Arc::new(Cache {
4865 data: "primary_data".to_string(),
4866 backup: None,
4867 });
4868
4869 let backup = Arc::new(Cache {
4870 data: "backup_data".to_string(),
4871 backup: Some(primary.clone()),
4872 });
4873
4874 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4876 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4877 |_: &mut Arc<Cache>| None::<&mut String>,
4878 );
4879
4880 let data = backup_data_kp.get(&backup);
4882 assert_eq!(data, Some(&"primary_data".to_string()));
4883
4884 let no_backup = backup_data_kp.get(&primary);
4886 assert_eq!(no_backup, None);
4887 }
4888
4889 #[test]
4890 fn test_kp_chain_with_pin_and_arc() {
4891 use std::pin::Pin;
4892 use std::sync::Arc;
4893
4894 struct Outer {
4897 inner: Arc<Inner>,
4898 }
4899
4900 struct Inner {
4901 value: String,
4902 }
4903
4904 let outer = Outer {
4905 inner: Arc::new(Inner {
4906 value: "nested_value".to_string(),
4907 }),
4908 };
4909
4910 let pinned_outer = Box::pin(outer);
4911
4912 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4914 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4915 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4916 );
4917
4918 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4920 |a: &Arc<Inner>| Some(&a.value),
4921 |_: &mut Arc<Inner>| None::<&mut String>,
4922 );
4923
4924 let chained = to_inner.then(to_value);
4926
4927 let result = chained.get(&pinned_outer);
4928 assert_eq!(result, Some(&"nested_value".to_string()));
4929 }
4930
4931 #[test]
4932 fn test_kp_with_maybe_uninit_array() {
4933 use std::mem::MaybeUninit;
4934
4935 struct Buffer {
4939 data: [MaybeUninit<u8>; 10],
4940 len: usize,
4941 }
4942
4943 impl Buffer {
4944 fn new() -> Self {
4945 Self {
4946 data: unsafe { MaybeUninit::uninit().assume_init() },
4947 len: 0,
4948 }
4949 }
4950
4951 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4952 if self.len >= self.data.len() {
4953 return Err("Buffer full");
4954 }
4955 self.data[self.len].write(byte);
4956 self.len += 1;
4957 Ok(())
4958 }
4959
4960 fn get(&self, idx: usize) -> Option<&u8> {
4961 if idx < self.len {
4962 unsafe { Some(self.data[idx].assume_init_ref()) }
4963 } else {
4964 None
4965 }
4966 }
4967
4968 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4969 if idx < self.len {
4970 unsafe { Some(self.data[idx].assume_init_mut()) }
4971 } else {
4972 None
4973 }
4974 }
4975 }
4976
4977 let len_kp: KpType<Buffer, usize> =
4979 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4980
4981 let mut buffer = Buffer::new();
4982
4983 assert_eq!(len_kp.get(&buffer), Some(&0));
4985
4986 buffer.push(1).unwrap();
4988 buffer.push(2).unwrap();
4989 buffer.push(3).unwrap();
4990
4991 assert_eq!(len_kp.get(&buffer), Some(&3));
4993
4994 assert_eq!(buffer.get(0), Some(&1));
4996 assert_eq!(buffer.get(1), Some(&2));
4997 assert_eq!(buffer.get(2), Some(&3));
4998 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
5002 *elem = 20;
5003 }
5004 assert_eq!(buffer.get(1), Some(&20));
5005 }
5006
5007 #[test]
5008 fn test_kp_then_lock_deep_structs() {
5009 use std::sync::{Arc, Mutex};
5010
5011 #[derive(Clone)]
5012 struct Root {
5013 guard: Arc<Mutex<Level1>>,
5014 }
5015 #[derive(Clone)]
5016 struct Level1 {
5017 name: String,
5018 nested: Level2,
5019 }
5020 #[derive(Clone)]
5021 struct Level2 {
5022 count: i32,
5023 }
5024
5025 let root = Root {
5026 guard: Arc::new(Mutex::new(Level1 {
5027 name: "deep".to_string(),
5028 nested: Level2 { count: 42 },
5029 })),
5030 };
5031
5032 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
5033 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
5034
5035 let lock_kp = {
5036 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
5037 Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
5038 let next: KpType<Level1, Level1> =
5039 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5040 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5041 };
5042
5043 let chained = kp_to_guard.then_lock(lock_kp);
5044 let level1 = chained.get(&root);
5045 assert!(level1.is_some());
5046 assert_eq!(level1.unwrap().name, "deep");
5047 assert_eq!(level1.unwrap().nested.count, 42);
5048
5049 let mut_root = &mut root.clone();
5050 let mut_level1 = chained.get_mut(mut_root);
5051 assert!(mut_level1.is_some());
5052 mut_level1.unwrap().nested.count = 99;
5053 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
5054 }
5055
5056 #[test]
5057 fn test_kp_then_lock_with_enum() {
5058 use std::sync::{Arc, Mutex};
5059
5060 #[derive(Clone)]
5061 enum Message {
5062 Request(LevelA),
5063 Response(i32),
5064 }
5065 #[derive(Clone)]
5066 struct LevelA {
5067 data: Arc<Mutex<i32>>,
5068 }
5069
5070 struct RootWithEnum {
5071 msg: Arc<Mutex<Message>>,
5072 }
5073
5074 let root = RootWithEnum {
5075 msg: Arc::new(Mutex::new(Message::Request(LevelA {
5076 data: Arc::new(Mutex::new(100)),
5077 }))),
5078 };
5079
5080 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
5081 Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
5082
5083 let lock_kp_msg = {
5084 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
5085 Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
5086 let next: KpType<Message, Message> =
5087 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
5088 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5089 };
5090
5091 let chained = kp_msg.then_lock(lock_kp_msg);
5092 let msg = chained.get(&root);
5093 assert!(msg.is_some());
5094 match msg.unwrap() {
5095 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
5096 Message::Response(_) => panic!("expected Request"),
5097 }
5098 }
5099
5100 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5101 #[tokio::test]
5102 async fn test_kp_then_async_deep_chain() {
5103 use std::sync::Arc;
5104 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5105
5106 #[derive(Clone)]
5107 struct Root {
5108 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
5109 }
5110 #[derive(Clone)]
5111 struct Level1 {
5112 value: i32,
5113 }
5114
5115 let root = Root {
5116 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
5117 };
5118
5119 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
5120 |r: &Root| Some(&r.tokio_guard),
5121 |r: &mut Root| Some(&mut r.tokio_guard),
5122 );
5123
5124 let async_kp = {
5125 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
5126 Kp::new(
5127 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
5128 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
5129 );
5130 let next: KpType<Level1, Level1> =
5131 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5132 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5133 };
5134
5135 let chained = kp_to_guard.then_async(async_kp);
5136 let level1 = chained.get(&root).await;
5137 assert!(level1.is_some());
5138 assert_eq!(level1.unwrap().value, 7);
5139 }
5140
5141 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5144 #[tokio::test]
5145 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
5146 use std::sync::{Arc, Mutex};
5147 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5148 use crate::lock::{LockKp, ArcMutexAccess};
5149
5150 #[derive(Clone)]
5152 struct Root {
5153 sync_mutex: Arc<Mutex<Level1>>,
5154 }
5155 #[derive(Clone)]
5157 struct Level1 {
5158 inner: Level2,
5159 }
5160 #[derive(Clone)]
5162 struct Level2 {
5163 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
5164 }
5165 #[derive(Clone)]
5167 struct Level3 {
5168 leaf: i32,
5169 }
5170
5171 let mut root = Root {
5172 sync_mutex: Arc::new(Mutex::new(Level1 {
5173 inner: Level2 {
5174 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
5175 },
5176 })),
5177 };
5178
5179 let identity_l1: KpType<Level1, Level1> =
5181 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5182 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
5183 Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
5184 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
5185
5186 let kp_l1_inner: KpType<Level1, Level2> =
5188 Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
5189
5190 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
5192 |l: &Level2| Some(&l.tokio_mutex),
5193 |l: &mut Level2| Some(&mut l.tokio_mutex),
5194 );
5195
5196 let async_l3 = {
5198 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
5199 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
5200 let next: KpType<Level3, Level3> =
5201 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
5202 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5203 };
5204
5205 let kp_l3_leaf: KpType<Level3, i32> =
5207 Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
5208
5209 let step1 = lock_root_to_l1.then(kp_l1_inner);
5211 let step2 = step1.then(kp_l2_tokio);
5212 let step3 = step2.then_async(async_l3);
5213 let deep_chain = step3.then(kp_l3_leaf);
5214
5215 let leaf = deep_chain.get(&root).await;
5217 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5218 assert_eq!(leaf, Some(&100));
5219
5220 let mut root_mut = root.clone();
5222 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5223 assert!(leaf_mut.is_some());
5224 *leaf_mut.unwrap() = 99;
5225
5226 let leaf_after = deep_chain.get(&root_mut).await;
5228 assert_eq!(leaf_after, Some(&99));
5229 }
5230}