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 KpDynamic<R, V> = Kp<
134 R,
135 V,
136 &'static R,
137 &'static V,
138 &'static mut R,
139 &'static mut V,
140 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
141 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
142>;
143
144pub type KpBox<'a, R, V> = Kp<
145R, V,
146&'a R, &'a V,
147&'a mut R, &'a mut V,
148Box<dyn Fn(&'a R) -> Option<&'a V> + 'a>,
149Box<dyn Fn(&'a mut R) -> Option<&'a mut V> + 'a>,
150>;
151
152pub type KpArc<'a, R, V> = Kp<
153 R, V,
154 &'a R, &'a V,
155 &'a mut R, &'a mut V,
156 Arc<dyn Fn(&'a R) -> Option<&'a V> + Send + Sync + 'a>,
157 Arc<dyn Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync + 'a>,
158>;
159
160
161pub type KpType<'a, R, V> = Kp<
162 R,
163 V,
164 &'a R,
165 &'a V,
166 &'a mut R,
167 &'a mut V,
168 for<'b> fn(&'b R) -> Option<&'b V>,
169 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
170>;
171
172impl<'a, R, V> KpType<'a, R, V>
173where
174 'a: 'static,
175{
176 #[inline]
179 pub fn to_dynamic(self) -> KpDynamic<R, V> {
180 self.into()
181 }
182}
183
184impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V>
185where
186 'a: 'static,
187 R: 'static,
188 V: 'static,
189{
190 #[inline]
191 fn from(kp: KpType<'a, R, V>) -> Self {
192 let get_fn = kp.get;
193 let set_fn = kp.set;
194 Kp::new(
195 Box::new(move |t: &R| get_fn(t)),
196 Box::new(move |t: &mut R| set_fn(t)),
197 )
198 }
199}
200
201pub type KpComposed<R, V> = Kp<
237 R,
238 V,
239 &'static R,
240 &'static V,
241 &'static mut R,
242 &'static mut V,
243 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
244 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
245>;
246
247impl<R, V> Kp<
248 R,
249 V,
250 &'static R,
251 &'static V,
252 &'static mut R,
253 &'static mut V,
254 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
255 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
256> {
257 pub fn from_closures<G, S>(get: G, set: S) -> Self
260 where
261 G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
262 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
263 {
264 Self::new(Box::new(get), Box::new(set))
265 }
266}
267
268pub struct AKp {
269 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
270 root_type_id: TypeId,
271 value_type_id: TypeId,
272}
273
274impl AKp {
275 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
277 where
278 R: Any + 'static,
279 V: Any + 'static,
280 {
281 let root_type_id = TypeId::of::<R>();
282 let value_type_id = TypeId::of::<V>();
283 let getter_fn = keypath.get;
284
285 Self {
286 getter: Rc::new(move |any: &dyn Any| {
287 if let Some(root) = any.downcast_ref::<R>() {
288 getter_fn(root).map(|value: &V| value as &dyn Any)
289 } else {
290 None
291 }
292 }),
293 root_type_id,
294 value_type_id,
295 }
296 }
297
298 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
300 where
301 R: Any + 'static,
302 V: Any + 'static,
303 {
304 Self::new(keypath)
305 }
306
307 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
309 (self.getter)(root)
310 }
311
312 pub fn root_type_id(&self) -> TypeId {
314 self.root_type_id
315 }
316
317 pub fn value_type_id(&self) -> TypeId {
319 self.value_type_id
320 }
321
322 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
324 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
325 {
326 Some(
327 self.get(root as &dyn Any)
328 .and_then(|any| any.downcast_ref::<Value>()),
329 )
330 } else {
331 None
332 }
333 }
334
335 pub fn kind_name(&self) -> String {
337 format!("{:?}", self.value_type_id)
338 }
339
340 pub fn root_kind_name(&self) -> String {
342 format!("{:?}", self.root_type_id)
343 }
344
345 pub fn for_arc<Root>(&self) -> AKp
347 where
348 Root: Any + 'static,
349 {
350 let value_type_id = self.value_type_id;
351 let getter = self.getter.clone();
352
353 AKp {
354 getter: Rc::new(move |any: &dyn Any| {
355 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
356 getter(arc.as_ref() as &dyn Any)
357 } else {
358 None
359 }
360 }),
361 root_type_id: TypeId::of::<Arc<Root>>(),
362 value_type_id,
363 }
364 }
365
366 pub fn for_box<Root>(&self) -> AKp
368 where
369 Root: Any + 'static,
370 {
371 let value_type_id = self.value_type_id;
372 let getter = self.getter.clone();
373
374 AKp {
375 getter: Rc::new(move |any: &dyn Any| {
376 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
377 getter(boxed.as_ref() as &dyn Any)
378 } else {
379 None
380 }
381 }),
382 root_type_id: TypeId::of::<Box<Root>>(),
383 value_type_id,
384 }
385 }
386
387 pub fn for_rc<Root>(&self) -> AKp
389 where
390 Root: Any + 'static,
391 {
392 let value_type_id = self.value_type_id;
393 let getter = self.getter.clone();
394
395 AKp {
396 getter: Rc::new(move |any: &dyn Any| {
397 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
398 getter(rc.as_ref() as &dyn Any)
399 } else {
400 None
401 }
402 }),
403 root_type_id: TypeId::of::<Rc<Root>>(),
404 value_type_id,
405 }
406 }
407
408 pub fn for_option<Root>(&self) -> AKp
410 where
411 Root: Any + 'static,
412 {
413 let value_type_id = self.value_type_id;
414 let getter = self.getter.clone();
415
416 AKp {
417 getter: Rc::new(move |any: &dyn Any| {
418 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
419 opt.as_ref().and_then(|root| getter(root as &dyn Any))
420 } else {
421 None
422 }
423 }),
424 root_type_id: TypeId::of::<Option<Root>>(),
425 value_type_id,
426 }
427 }
428
429 pub fn for_result<Root, E>(&self) -> AKp
431 where
432 Root: Any + 'static,
433 E: 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(result) = any.downcast_ref::<Result<Root, E>>() {
441 result
442 .as_ref()
443 .ok()
444 .and_then(|root| getter(root as &dyn Any))
445 } else {
446 None
447 }
448 }),
449 root_type_id: TypeId::of::<Result<Root, E>>(),
450 value_type_id,
451 }
452 }
453
454 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
467 where
468 Root: Any + 'static,
469 OrigValue: Any + 'static,
470 MappedValue: Any + 'static,
471 F: Fn(&OrigValue) -> MappedValue + 'static,
472 {
473 let orig_root_type_id = self.root_type_id;
474 let orig_value_type_id = self.value_type_id;
475 let getter = self.getter.clone();
476 let mapped_type_id = TypeId::of::<MappedValue>();
477
478 AKp {
479 getter: Rc::new(move |any_root: &dyn Any| {
480 if any_root.type_id() == orig_root_type_id {
482 getter(any_root).and_then(|any_value| {
483 if orig_value_type_id == TypeId::of::<OrigValue>() {
485 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
486 let mapped = mapper(orig_val);
487 Box::leak(Box::new(mapped)) as &dyn Any
489 })
490 } else {
491 None
492 }
493 })
494 } else {
495 None
496 }
497 }),
498 root_type_id: orig_root_type_id,
499 value_type_id: mapped_type_id,
500 }
501 }
502
503 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
516 where
517 Root: Any + 'static,
518 Value: Any + 'static,
519 F: Fn(&Value) -> bool + 'static,
520 {
521 let orig_root_type_id = self.root_type_id;
522 let orig_value_type_id = self.value_type_id;
523 let getter = self.getter.clone();
524
525 AKp {
526 getter: Rc::new(move |any_root: &dyn Any| {
527 if any_root.type_id() == orig_root_type_id {
529 getter(any_root).filter(|any_value| {
530 if orig_value_type_id == TypeId::of::<Value>() {
532 any_value
533 .downcast_ref::<Value>()
534 .map(|val| predicate(val))
535 .unwrap_or(false)
536 } else {
537 false
538 }
539 })
540 } else {
541 None
542 }
543 }),
544 root_type_id: orig_root_type_id,
545 value_type_id: orig_value_type_id,
546 }
547 }
548}
549pub struct PKp<Root> {
550 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
551 value_type_id: TypeId,
552 _phantom: std::marker::PhantomData<Root>,
553}
554
555impl<Root> PKp<Root>
556where
557 Root: 'static,
558{
559 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
561 where
562 V: Any + 'static,
563 {
564 let value_type_id = TypeId::of::<V>();
565 let getter_fn = keypath.get;
566
567 Self {
568 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
569 value_type_id,
570 _phantom: std::marker::PhantomData,
571 }
572 }
573
574 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
576 where
577 V: Any + 'static,
578 {
579 Self::new(keypath)
580 }
581
582 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
584 (self.getter)(root)
585 }
586
587 pub fn value_type_id(&self) -> TypeId {
589 self.value_type_id
590 }
591
592 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
594 if self.value_type_id == TypeId::of::<Value>() {
595 self.get(root).and_then(|any| any.downcast_ref::<Value>())
596 } else {
597 None
598 }
599 }
600
601 pub fn kind_name(&self) -> String {
603 format!("{:?}", self.value_type_id)
604 }
605
606 pub fn for_arc(&self) -> PKp<Arc<Root>> {
608 let getter = self.getter.clone();
609 let value_type_id = self.value_type_id;
610
611 PKp {
612 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
613 value_type_id,
614 _phantom: std::marker::PhantomData,
615 }
616 }
617
618 pub fn for_box(&self) -> PKp<Box<Root>> {
620 let getter = self.getter.clone();
621 let value_type_id = self.value_type_id;
622
623 PKp {
624 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
625 value_type_id,
626 _phantom: std::marker::PhantomData,
627 }
628 }
629
630 pub fn for_rc(&self) -> PKp<Rc<Root>> {
632 let getter = self.getter.clone();
633 let value_type_id = self.value_type_id;
634
635 PKp {
636 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
637 value_type_id,
638 _phantom: std::marker::PhantomData,
639 }
640 }
641
642 pub fn for_option(&self) -> PKp<Option<Root>> {
644 let getter = self.getter.clone();
645 let value_type_id = self.value_type_id;
646
647 PKp {
648 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
649 value_type_id,
650 _phantom: std::marker::PhantomData,
651 }
652 }
653
654 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
656 where
657 E: 'static,
658 {
659 let getter = self.getter.clone();
660 let value_type_id = self.value_type_id;
661
662 PKp {
663 getter: Rc::new(move |result: &Result<Root, E>| {
664 result.as_ref().ok().and_then(|root| getter(root))
665 }),
666 value_type_id,
667 _phantom: std::marker::PhantomData,
668 }
669 }
670
671 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
685 where
686 OrigValue: Any + 'static,
687 MappedValue: Any + 'static,
688 F: Fn(&OrigValue) -> MappedValue + 'static,
689 {
690 let orig_type_id = self.value_type_id;
691 let getter = self.getter.clone();
692 let mapped_type_id = TypeId::of::<MappedValue>();
693
694 PKp {
695 getter: Rc::new(move |root: &Root| {
696 getter(root).and_then(|any_value| {
697 if orig_type_id == TypeId::of::<OrigValue>() {
699 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
700 let mapped = mapper(orig_val);
701 Box::leak(Box::new(mapped)) as &dyn Any
704 })
705 } else {
706 None
707 }
708 })
709 }),
710 value_type_id: mapped_type_id,
711 _phantom: std::marker::PhantomData,
712 }
713 }
714
715 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
729 where
730 Value: Any + 'static,
731 F: Fn(&Value) -> bool + 'static,
732 {
733 let orig_type_id = self.value_type_id;
734 let getter = self.getter.clone();
735
736 PKp {
737 getter: Rc::new(move |root: &Root| {
738 getter(root).filter(|any_value| {
739 if orig_type_id == TypeId::of::<Value>() {
741 any_value
742 .downcast_ref::<Value>()
743 .map(|val| predicate(val))
744 .unwrap_or(false)
745 } else {
746 false
747 }
748 })
749 }),
750 value_type_id: orig_type_id,
751 _phantom: std::marker::PhantomData,
752 }
753 }
754}
755
756#[derive(Clone)]
770pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
771where
772 Root: std::borrow::Borrow<R>,
773 MutRoot: std::borrow::BorrowMut<R>,
774 MutValue: std::borrow::BorrowMut<V>,
775 G: Fn(Root) -> Option<Value>,
776 S: Fn(MutRoot) -> Option<MutValue>,
777{
778 pub(crate) get: G,
780 pub(crate) set: S,
782 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
783}
784
785unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Send for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
787where
788 Root: std::borrow::Borrow<R>,
789 MutRoot: std::borrow::BorrowMut<R>,
790 MutValue: std::borrow::BorrowMut<V>,
791 G: Fn(Root) -> Option<Value> + Send,
792 S: Fn(MutRoot) -> Option<MutValue> + Send,
793{
794}
795unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Sync for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
796where
797 Root: std::borrow::Borrow<R>,
798 MutRoot: std::borrow::BorrowMut<R>,
799 MutValue: std::borrow::BorrowMut<V>,
800 G: Fn(Root) -> Option<Value> + Sync,
801 S: Fn(MutRoot) -> Option<MutValue> + Sync,
802{
803}
804
805impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
806where
807 Root: std::borrow::Borrow<R>,
808 Value: std::borrow::Borrow<V>,
809 MutRoot: std::borrow::BorrowMut<R>,
810 MutValue: std::borrow::BorrowMut<V>,
811 G: Fn(Root) -> Option<Value>,
812 S: Fn(MutRoot) -> Option<MutValue>,
813{
814 pub fn new(get: G, set: S) -> Self {
815 Self {
816 get: get,
817 set: set,
818 _p: std::marker::PhantomData,
819 }
820 }
821
822 pub const fn new_const(get: G, set: S) -> Self {
823 Self {
824 get: get,
825 set: set,
826 _p: std::marker::PhantomData,
827 }
828 }
829
830
831 #[inline]
832 pub fn get(&self, root: Root) -> Option<Value> {
833 (self.get)(root)
834 }
835 #[inline]
836 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
837 (self.set)(root)
838 }
839
840 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
841 self,
842 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
843 ) -> Kp<
844 R,
845 SV,
846 Root,
847 SubValue,
848 MutRoot,
849 MutSubValue,
850 impl Fn(Root) -> Option<SubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
851 impl Fn(MutRoot) -> Option<MutSubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
852 >
853 where
854 SubValue: std::borrow::Borrow<SV>,
855 MutSubValue: std::borrow::BorrowMut<SV>,
856 G2: Fn(Value) -> Option<SubValue>,
857 S2: Fn(MutValue) -> Option<MutSubValue>,
858 V: 'static,
859 {
860 Kp::new(
861 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
862 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
863 )
864 }
865
866 pub fn then_lock<
868 Lock,
869 Mid,
870 V2,
871 LockValue,
872 MidValue,
873 Value2,
874 MutLock,
875 MutMid,
876 MutValue2,
877 G1,
878 S1,
879 L,
880 G2,
881 S2,
882 >(
883 self,
884 lock_kp: crate::lock::LockKp<
885 V,
886 Lock,
887 Mid,
888 V2,
889 Value,
890 LockValue,
891 MidValue,
892 Value2,
893 MutValue,
894 MutLock,
895 MutMid,
896 MutValue2,
897 G1,
898 S1,
899 L,
900 G2,
901 S2,
902 >,
903 ) -> 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>>
904 where
905 V: 'static + Clone,
906 V2: 'static,
907 Value: std::borrow::Borrow<V>,
908 Value2: std::borrow::Borrow<V2>,
909 MutValue: std::borrow::BorrowMut<V>,
910 MutValue2: std::borrow::BorrowMut<V2>,
911 LockValue: std::borrow::Borrow<Lock>,
912 MidValue: std::borrow::Borrow<Mid>,
913 MutLock: std::borrow::BorrowMut<Lock>,
914 MutMid: std::borrow::BorrowMut<Mid>,
915 G1: Fn(Value) -> Option<LockValue>,
916 S1: Fn(MutValue) -> Option<MutLock>,
917 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
918 G2: Fn(MidValue) -> Option<Value2>,
919 S2: Fn(MutMid) -> Option<MutValue2>,
920 {
921 crate::lock::KpThenLockKp {
922 first: self,
923 second: lock_kp,
924 _p: std::marker::PhantomData,
925 }
926 }
927
928 #[cfg(feature = "pin_project")]
931 pub fn then_pin_future<Struct, Output, L>(
932 self,
933 pin_fut: L,
934 ) -> crate::pin::KpThenPinFuture<
935 R,
936 Struct,
937 Output,
938 Root,
939 MutRoot,
940 Value,
941 MutValue,
942 Self,
943 L,
944 >
945 where
946 V: 'static,
947 Struct: Unpin + 'static,
948 Output: 'static,
949 Value: std::borrow::Borrow<Struct>,
950 MutValue: std::borrow::BorrowMut<Struct>,
951 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
952 {
953 crate::pin::KpThenPinFuture {
954 first: self,
955 second: pin_fut,
956 _p: std::marker::PhantomData,
957 }
958 }
959
960 pub fn then_async<AsyncKp>(
963 self,
964 async_kp: AsyncKp,
965 ) -> crate::async_lock::KpThenAsyncKeyPath<
966 R,
967 V,
968 <AsyncKp::Value as KeyPathValueTarget>::Target,
969 Root,
970 Value,
971 AsyncKp::Value,
972 MutRoot,
973 MutValue,
974 AsyncKp::MutValue,
975 Self,
976 AsyncKp,
977 >
978 where
979 V: 'static,
980 Value: std::borrow::Borrow<V>,
981 MutValue: std::borrow::BorrowMut<V>,
982 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
983 AsyncKp::Value: KeyPathValueTarget
984 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
985 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
986 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
987 {
988 crate::async_lock::KpThenAsyncKeyPath {
989 first: self,
990 second: async_kp,
991 _p: std::marker::PhantomData,
992 }
993 }
994
995 pub fn map<MappedValue, F>(
1008 &self,
1009 mapper: F,
1010 ) -> Kp<
1011 R,
1012 MappedValue,
1013 Root,
1014 MappedValue,
1015 MutRoot,
1016 MappedValue,
1017 impl Fn(Root) -> Option<MappedValue>,
1018 impl Fn(MutRoot) -> Option<MappedValue>,
1019 >
1020 where
1021 F: Fn(&V) -> MappedValue + Copy + 'static,
1024 V: 'static,
1025 MappedValue: 'static,
1026 {
1027 Kp::new(
1028 move |root: Root| {
1029 (&self.get)(root).map(|value| {
1030 let v: &V = value.borrow();
1031 mapper(v)
1032 })
1033 },
1034 move |root: MutRoot| {
1035 (&self.set)(root).map(|value| {
1036 let v: &V = value.borrow();
1037 mapper(v)
1038 })
1039 },
1040 )
1041 }
1042
1043 pub fn filter<F>(
1056 &self,
1057 predicate: F,
1058 ) -> Kp<
1059 R,
1060 V,
1061 Root,
1062 Value,
1063 MutRoot,
1064 MutValue,
1065 impl Fn(Root) -> Option<Value>,
1066 impl Fn(MutRoot) -> Option<MutValue>,
1067 >
1068 where
1069 F: Fn(&V) -> bool + Copy + 'static,
1072 V: 'static,
1073 {
1074 Kp::new(
1075 move |root: Root| {
1076 (&self.get)(root).filter(|value| {
1077 let v: &V = value.borrow();
1078 predicate(v)
1079 })
1080 },
1081 move |root: MutRoot| {
1082 (&self.set)(root).filter(|value| {
1083 let v: &V = value.borrow();
1084 predicate(v)
1085 })
1086 },
1087 )
1088 }
1089
1090 pub fn filter_map<MappedValue, F>(
1103 &self,
1104 mapper: F,
1105 ) -> Kp<
1106 R,
1107 MappedValue,
1108 Root,
1109 MappedValue,
1110 MutRoot,
1111 MappedValue,
1112 impl Fn(Root) -> Option<MappedValue>,
1113 impl Fn(MutRoot) -> Option<MappedValue>,
1114 >
1115 where
1116 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1119 V: 'static,
1120 MappedValue: 'static,
1121 {
1122 Kp::new(
1123 move |root: Root| {
1124 (&self.get)(root).and_then(|value| {
1125 let v: &V = value.borrow();
1126 mapper(v)
1127 })
1128 },
1129 move |root: MutRoot| {
1130 (&self.set)(root).and_then(|value| {
1131 let v: &V = value.borrow();
1132 mapper(v)
1133 })
1134 },
1135 )
1136 }
1137
1138 pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
1150 where
1151 F: Fn(&V) -> I + 'static,
1154 V: 'static,
1155 I: IntoIterator<Item = Item>,
1156 Item: 'static,
1157 {
1158 move |root: Root| {
1159 (&self.get)(root)
1160 .map(|value| {
1161 let v: &V = value.borrow();
1162 mapper(v).into_iter().collect()
1163 })
1164 .unwrap_or_else(Vec::new)
1165 }
1166 }
1167
1168 pub fn inspect<F>(
1179 &self,
1180 inspector: F,
1181 ) -> Kp<
1182 R,
1183 V,
1184 Root,
1185 Value,
1186 MutRoot,
1187 MutValue,
1188 impl Fn(Root) -> Option<Value>,
1189 impl Fn(MutRoot) -> Option<MutValue>,
1190 >
1191 where
1192 F: Fn(&V) + Copy + 'static,
1195 V: 'static,
1196 {
1197 Kp::new(
1198 move |root: Root| {
1199 (&self.get)(root).map(|value| {
1200 let v: &V = value.borrow();
1201 inspector(v);
1202 value
1203 })
1204 },
1205 move |root: MutRoot| {
1206 (&self.set)(root).map(|value| {
1207 let v: &V = value.borrow();
1208 inspector(v);
1209 value
1210 })
1211 },
1212 )
1213 }
1214
1215 pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
1229 where
1230 F: Fn(Acc, &V) -> Acc + 'static,
1233 V: 'static,
1234 Acc: Copy + 'static,
1236 {
1237 move |root: Root| {
1238 (&self.get)(root)
1239 .map(|value| {
1240 let v: &V = value.borrow();
1241 folder(init, v)
1242 })
1243 .unwrap_or(init)
1244 }
1245 }
1246
1247 pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1259 where
1260 F: Fn(&V) -> bool + 'static,
1263 V: 'static,
1264 {
1265 move |root: Root| {
1266 (&self.get)(root)
1267 .map(|value| {
1268 let v: &V = value.borrow();
1269 predicate(v)
1270 })
1271 .unwrap_or(false)
1272 }
1273 }
1274
1275 pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1287 where
1288 F: Fn(&V) -> bool + 'static,
1291 V: 'static,
1292 {
1293 move |root: Root| {
1294 (&self.get)(root)
1295 .map(|value| {
1296 let v: &V = value.borrow();
1297 predicate(v)
1298 })
1299 .unwrap_or(true)
1300 }
1301 }
1302
1303 pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
1315 where
1316 F: Fn(&V) -> usize + 'static,
1319 V: 'static,
1320 {
1321 move |root: Root| {
1322 (&self.get)(root).map(|value| {
1323 let v: &V = value.borrow();
1324 counter(v)
1325 })
1326 }
1327 }
1328
1329 pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
1343 where
1344 F: Fn(&V) -> Option<Item> + 'static,
1347 V: 'static,
1348 Item: 'static,
1349 {
1350 move |root: Root| {
1351 (&self.get)(root).and_then(|value| {
1352 let v: &V = value.borrow();
1353 finder(v)
1354 })
1355 }
1356 }
1357
1358 pub fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output>
1369 where
1370 F: Fn(&V, usize) -> Output + 'static,
1373 V: 'static,
1374 Output: 'static,
1375 {
1376 move |root: Root| {
1377 (&self.get)(root).map(|value| {
1378 let v: &V = value.borrow();
1379 taker(v, n)
1380 })
1381 }
1382 }
1383
1384 pub fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output>
1395 where
1396 F: Fn(&V, usize) -> Output + 'static,
1399 V: 'static,
1400 Output: 'static,
1401 {
1402 move |root: Root| {
1403 (&self.get)(root).map(|value| {
1404 let v: &V = value.borrow();
1405 skipper(v, n)
1406 })
1407 }
1408 }
1409
1410 pub fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output>
1423 where
1424 F: Fn(&V) -> Output + 'static,
1427 V: 'static,
1428 Output: 'static,
1429 {
1430 move |root: Root| {
1431 (&self.get)(root).map(|value| {
1432 let v: &V = value.borrow();
1433 partitioner(v)
1434 })
1435 }
1436 }
1437
1438 pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
1450 where
1451 F: Fn(&V) -> Option<Item> + 'static,
1454 V: 'static,
1455 Item: 'static,
1456 {
1457 move |root: Root| {
1458 (&self.get)(root).and_then(|value| {
1459 let v: &V = value.borrow();
1460 min_fn(v)
1461 })
1462 }
1463 }
1464
1465 pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
1477 where
1478 F: Fn(&V) -> Option<Item> + 'static,
1481 V: 'static,
1482 Item: 'static,
1483 {
1484 move |root: Root| {
1485 (&self.get)(root).and_then(|value| {
1486 let v: &V = value.borrow();
1487 max_fn(v)
1488 })
1489 }
1490 }
1491
1492 pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
1504 where
1505 F: Fn(&V) -> Sum + 'static,
1508 V: 'static,
1509 Sum: 'static,
1510 {
1511 move |root: Root| {
1512 (&self.get)(root).map(|value| {
1513 let v: &V = value.borrow();
1514 sum_fn(v)
1515 })
1516 }
1517 }
1518
1519 pub fn chain<SV, SubValue, MutSubValue, G2, S2>(
1522 self,
1523 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1524 ) -> Kp<
1525 R,
1526 SV,
1527 Root,
1528 SubValue,
1529 MutRoot,
1530 MutSubValue,
1531 impl Fn(Root) -> Option<SubValue>,
1532 impl Fn(MutRoot) -> Option<MutSubValue>,
1533 >
1534 where
1535 SubValue: std::borrow::Borrow<SV>,
1536 MutSubValue: std::borrow::BorrowMut<SV>,
1537 G2: Fn(Value) -> Option<SubValue>,
1538 S2: Fn(MutValue) -> Option<MutSubValue>,
1539 V: 'static,
1540 {
1541 self.then(next)
1542 }
1543
1544 pub fn for_arc<'b>(
1545 &self,
1546 ) -> Kp<
1547 std::sync::Arc<R>,
1548 V,
1549 std::sync::Arc<R>,
1550 Value,
1551 std::sync::Arc<R>,
1552 MutValue,
1553 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1554 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1555 >
1556 where
1557 R: 'b,
1558 V: 'b,
1559 Root: for<'a> From<&'a R>,
1560 MutRoot: for<'a> From<&'a mut R>,
1561 {
1562 Kp::new(
1563 move |arc_root: std::sync::Arc<R>| {
1564 let r_ref: &R = &*arc_root;
1565 (&self.get)(Root::from(r_ref))
1566 },
1567 move |mut arc_root: std::sync::Arc<R>| {
1568 std::sync::Arc::get_mut(&mut arc_root)
1570 .and_then(|r_mut| (&self.set)(MutRoot::from(r_mut)))
1571 },
1572 )
1573 }
1574
1575 pub fn for_box<'a>(
1576 &self,
1577 ) -> Kp<
1578 Box<R>,
1579 V,
1580 Box<R>,
1581 Value,
1582 Box<R>,
1583 MutValue,
1584 impl Fn(Box<R>) -> Option<Value>,
1585 impl Fn(Box<R>) -> Option<MutValue>,
1586 >
1587 where
1588 R: 'a,
1589 V: 'a,
1590 Root: for<'b> From<&'b R>,
1591 MutRoot: for<'b> From<&'b mut R>,
1592 {
1593 Kp::new(
1594 move |r: Box<R>| {
1595 let r_ref: &R = r.as_ref();
1596 (&self.get)(Root::from(r_ref))
1597 },
1598 move |mut r: Box<R>| {
1599 (self.set)(MutRoot::from(r.as_mut()))
1601 },
1602 )
1603 }
1604}
1605
1606pub fn zip_kps<'a, RootType, Value1, Value2>(
1620 kp1: &'a KpType<'a, RootType, Value1>,
1621 kp2: &'a KpType<'a, RootType, Value2>,
1622) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1623where
1624 RootType: 'a,
1625 Value1: 'a,
1626 Value2: 'a,
1627{
1628 move |root: &'a RootType| {
1629 let val1 = (kp1.get)(root)?;
1630 let val2 = (kp2.get)(root)?;
1631 Some((val1, val2))
1632 }
1633}
1634
1635impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1636where
1637 Root: std::borrow::Borrow<R>,
1638 MutRoot: std::borrow::BorrowMut<R>,
1639 G: Fn(Root) -> Option<Root>,
1640 S: Fn(MutRoot) -> Option<MutRoot>,
1641{
1642 pub fn identity_typed() -> Kp<
1643 R,
1644 R,
1645 Root,
1646 Root,
1647 MutRoot,
1648 MutRoot,
1649 fn(Root) -> Option<Root>,
1650 fn(MutRoot) -> Option<MutRoot>,
1651 > {
1652 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1653 }
1654
1655 pub fn identity<'a>() -> KpType<'a, R, R> {
1656 KpType::new(|r| Some(r), |r| Some(r))
1657 }
1658}
1659
1660pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1669where
1670 Root: std::borrow::Borrow<Enum>,
1671 Value: std::borrow::Borrow<Variant>,
1672 MutRoot: std::borrow::BorrowMut<Enum>,
1673 MutValue: std::borrow::BorrowMut<Variant>,
1674 G: Fn(Root) -> Option<Value>,
1675 S: Fn(MutRoot) -> Option<MutValue>,
1676 E: Fn(Variant) -> Enum,
1677{
1678 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1679 embedder: E,
1680}
1681
1682unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1684 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1685where
1686 Root: std::borrow::Borrow<Enum>,
1687 Value: std::borrow::Borrow<Variant>,
1688 MutRoot: std::borrow::BorrowMut<Enum>,
1689 MutValue: std::borrow::BorrowMut<Variant>,
1690 G: Fn(Root) -> Option<Value> + Send,
1691 S: Fn(MutRoot) -> Option<MutValue> + Send,
1692 E: Fn(Variant) -> Enum + Send,
1693{
1694}
1695unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1696 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1697where
1698 Root: std::borrow::Borrow<Enum>,
1699 Value: std::borrow::Borrow<Variant>,
1700 MutRoot: std::borrow::BorrowMut<Enum>,
1701 MutValue: std::borrow::BorrowMut<Variant>,
1702 G: Fn(Root) -> Option<Value> + Sync,
1703 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1704 E: Fn(Variant) -> Enum + Sync,
1705{
1706}
1707
1708impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1709 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1710where
1711 Root: std::borrow::Borrow<Enum>,
1712 Value: std::borrow::Borrow<Variant>,
1713 MutRoot: std::borrow::BorrowMut<Enum>,
1714 MutValue: std::borrow::BorrowMut<Variant>,
1715 G: Fn(Root) -> Option<Value>,
1716 S: Fn(MutRoot) -> Option<MutValue>,
1717 E: Fn(Variant) -> Enum,
1718{
1719 pub fn new(
1721 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1722 embedder: E,
1723 ) -> Self {
1724 Self {
1725 extractor,
1726 embedder,
1727 }
1728 }
1729
1730 pub fn get(&self, enum_value: Root) -> Option<Value> {
1732 self.extractor.get(enum_value)
1733 }
1734
1735 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1737 self.extractor.get_mut(enum_value)
1738 }
1739
1740 pub fn embed(&self, value: Variant) -> Enum {
1742 (self.embedder)(value)
1743 }
1744
1745 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1747 &self.extractor
1748 }
1749
1750 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1752 self.extractor
1753 }
1754
1755 pub fn map<MappedValue, F>(
1766 &self,
1767 mapper: F,
1768 ) -> EnumKp<
1769 Enum,
1770 MappedValue,
1771 Root,
1772 MappedValue,
1773 MutRoot,
1774 MappedValue,
1775 impl Fn(Root) -> Option<MappedValue>,
1776 impl Fn(MutRoot) -> Option<MappedValue>,
1777 impl Fn(MappedValue) -> Enum,
1778 >
1779 where
1780 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1783 Variant: 'static,
1784 MappedValue: 'static,
1785 E: Fn(Variant) -> Enum + Copy + 'static,
1787 {
1788 let mapped_extractor = self.extractor.map(mapper);
1789
1790 let new_embedder = move |_value: MappedValue| -> Enum {
1794 panic!(
1795 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1796 )
1797 };
1798
1799 EnumKp::new(mapped_extractor, new_embedder)
1800 }
1801
1802 pub fn filter<F>(
1814 &self,
1815 predicate: F,
1816 ) -> EnumKp<
1817 Enum,
1818 Variant,
1819 Root,
1820 Value,
1821 MutRoot,
1822 MutValue,
1823 impl Fn(Root) -> Option<Value>,
1824 impl Fn(MutRoot) -> Option<MutValue>,
1825 E,
1826 >
1827 where
1828 F: Fn(&Variant) -> bool + Copy + 'static,
1831 Variant: 'static,
1832 E: Copy,
1834 {
1835 let filtered_extractor = self.extractor.filter(predicate);
1836 EnumKp::new(filtered_extractor, self.embedder)
1837 }
1838}
1839
1840pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1842 Enum,
1843 Variant,
1844 &'a Enum,
1845 &'a Variant,
1846 &'a mut Enum,
1847 &'a mut Variant,
1848 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1849 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1850 fn(Variant) -> Enum,
1851>;
1852
1853pub fn enum_variant<'a, Enum, Variant>(
1871 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1872 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1873 embedder: fn(Variant) -> Enum,
1874) -> EnumKpType<'a, Enum, Variant> {
1875 EnumKp::new(Kp::new(getter, setter), embedder)
1876}
1877
1878pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1888 EnumKp::new(
1889 Kp::new(
1890 |r: &Result<T, E>| r.as_ref().ok(),
1891 |r: &mut Result<T, E>| r.as_mut().ok(),
1892 ),
1893 |t: T| Ok(t),
1894 )
1895}
1896
1897pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1907 EnumKp::new(
1908 Kp::new(
1909 |r: &Result<T, E>| r.as_ref().err(),
1910 |r: &mut Result<T, E>| r.as_mut().err(),
1911 ),
1912 |e: E| Err(e),
1913 )
1914}
1915
1916pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1926 EnumKp::new(
1927 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1928 |t: T| Some(t),
1929 )
1930}
1931
1932pub fn variant_of<'a, Enum, Variant>(
1950 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1951 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1952 embedder: fn(Variant) -> Enum,
1953) -> EnumKpType<'a, Enum, Variant> {
1954 enum_variant(getter, setter, embedder)
1955}
1956
1957pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1970 Kp::new(
1971 |b: &Box<T>| Some(b.as_ref()),
1972 |b: &mut Box<T>| Some(b.as_mut()),
1973 )
1974}
1975
1976pub fn kp_arc<'a, T>() -> Kp<
1987 Arc<T>,
1988 T,
1989 &'a Arc<T>,
1990 &'a T,
1991 &'a mut Arc<T>,
1992 &'a mut T,
1993 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
1994 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
1995> {
1996 Kp::new(
1997 |arc: &Arc<T>| Some(arc.as_ref()),
1998 |arc: &mut Arc<T>| Arc::get_mut(arc),
1999 )
2000}
2001
2002pub fn kp_rc<'a, T>() -> Kp<
2013 std::rc::Rc<T>,
2014 T,
2015 &'a std::rc::Rc<T>,
2016 &'a T,
2017 &'a mut std::rc::Rc<T>,
2018 &'a mut T,
2019 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
2020 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
2021> {
2022 Kp::new(
2023 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
2024 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
2025 )
2026}
2027
2028use std::any::{Any, TypeId};
2031use std::rc::Rc;
2032
2033#[cfg(test)]
2048mod tests {
2049 use super::*;
2050 use std::collections::HashMap;
2051
2052 #[derive(Debug)]
2053 struct TestKP {
2054 a: String,
2055 b: String,
2056 c: std::sync::Arc<String>,
2057 d: std::sync::Mutex<String>,
2058 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
2059 f: Option<TestKP2>,
2060 g: HashMap<i32, TestKP2>,
2061 }
2062
2063 impl TestKP {
2064 fn new() -> Self {
2065 Self {
2066 a: String::from("a"),
2067 b: String::from("b"),
2068 c: std::sync::Arc::new(String::from("c")),
2069 d: std::sync::Mutex::new(String::from("d")),
2070 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2071 f: Some(TestKP2 {
2072 a: String::from("a3"),
2073 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2074 }),
2075 g: HashMap::new(),
2076 }
2077 }
2078
2079 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2080 KpComposed::from_closures(
2081 move |r: &TestKP| r.g.get(&index),
2082 move |r: &mut TestKP| r.g.get_mut(&index),
2083 )
2084 }
2085
2086 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2089 TestKP2,
2090 String,
2091 Root,
2092 Value,
2093 MutRoot,
2094 MutValue,
2095 impl Fn(Root) -> Option<Value>,
2096 impl Fn(MutRoot) -> Option<MutValue>,
2097 >
2098 where
2099 Root: std::borrow::Borrow<TestKP2>,
2100 MutRoot: std::borrow::BorrowMut<TestKP2>,
2101 Value: std::borrow::Borrow<String> + From<String>,
2102 MutValue: std::borrow::BorrowMut<String> + From<String>,
2103 {
2104 Kp::new(
2105 |r: Root| Some(Value::from(r.borrow().a.clone())),
2106 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2107 )
2108 }
2109
2110 fn c<'a>() -> KpType<'a, TestKP, String> {
2113 KpType::new(
2114 |r: &TestKP| Some(r.c.as_ref()),
2115 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2116 Some(arc_str) => Some(arc_str),
2117 None => None,
2118 },
2119 )
2120 }
2121
2122 fn a<'a>() -> KpType<'a, TestKP, String> {
2123 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2124 }
2125
2126 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2127 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2128 }
2129
2130 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2131 KpType::identity()
2132 }
2133 }
2134
2135 #[derive(Debug)]
2136 struct TestKP2 {
2137 a: String,
2138 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2139 }
2140
2141 impl TestKP2 {
2142 fn new() -> Self {
2143 TestKP2 {
2144 a: String::from("a2"),
2145 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2146 }
2147 }
2148
2149 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2150 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2157 fn(MutRoot) -> Option<MutRoot>,
2158 >
2159 where
2160 Root: std::borrow::Borrow<TestKP2>,
2161 MutRoot: std::borrow::BorrowMut<TestKP2>,
2162 G: Fn(Root) -> Option<Root>,
2163 S: Fn(MutRoot) -> Option<MutRoot>,
2164 {
2165 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2166 }
2167
2168 fn a<'a>() -> KpType<'a, TestKP2, String> {
2169 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2170 }
2171
2172 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2173 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2174 }
2175
2176 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2181 KpType::identity()
2182 }
2183 }
2184
2185 #[derive(Debug)]
2186 struct TestKP3 {
2187 a: String,
2188 b: std::sync::Arc<std::sync::Mutex<String>>,
2189 }
2190
2191 impl TestKP3 {
2192 fn new() -> Self {
2193 TestKP3 {
2194 a: String::from("a2"),
2195 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2196 }
2197 }
2198
2199 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2200 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2207 fn(MutRoot) -> Option<MutRoot>,
2208 >
2209 where
2210 Root: std::borrow::Borrow<TestKP3>,
2211 MutRoot: std::borrow::BorrowMut<TestKP3>,
2212 G: Fn(Root) -> Option<Root>,
2213 S: Fn(MutRoot) -> Option<MutRoot>,
2214 {
2215 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2216 }
2217
2218 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2219 KpType::identity()
2220 }
2221 }
2222
2223 impl TestKP3 {}
2224
2225 impl TestKP {}
2226 #[test]
2227 fn test_a() {
2228 let instance2 = TestKP2::new();
2229 let mut instance = TestKP::new();
2230 let kp = TestKP::identity();
2231 let kp_a = TestKP::a();
2232 let wres = TestKP::f().then(TestKP2::a()).get_mut(&mut instance).unwrap();
2234 *wres = String::from("a3 changed successfully");
2235 let res = TestKP::f().then(TestKP2::a()).get(&instance);
2236 println!("{:?}", res);
2237 let res = TestKP::f().then(TestKP2::identity()).get(&instance);
2238 println!("{:?}", res);
2239 let res = kp.get(&instance);
2240 println!("{:?}", res);
2241
2242 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2243 println!("{:?}", new_kp_from_hashmap.get(&instance));
2244 }
2245
2246 #[test]
2325 fn test_enum_kp_result_ok() {
2326 let ok_result: Result<String, i32> = Ok("success".to_string());
2327 let mut err_result: Result<String, i32> = Err(42);
2328
2329 let ok_kp = enum_ok();
2330
2331 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2333 assert_eq!(ok_kp.get(&err_result), None);
2334
2335 let embedded = ok_kp.embed("embedded".to_string());
2337 assert_eq!(embedded, Ok("embedded".to_string()));
2338
2339 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2341 *val = "modified".to_string();
2342 }
2343 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2346 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2347 *val = "modified".to_string();
2348 }
2349 assert_eq!(ok_result2, Ok("modified".to_string()));
2350 }
2351
2352 #[test]
2353 fn test_enum_kp_result_err() {
2354 let ok_result: Result<String, i32> = Ok("success".to_string());
2355 let mut err_result: Result<String, i32> = Err(42);
2356
2357 let err_kp = enum_err();
2358
2359 assert_eq!(err_kp.get(&err_result), Some(&42));
2361 assert_eq!(err_kp.get(&ok_result), None);
2362
2363 let embedded = err_kp.embed(99);
2365 assert_eq!(embedded, Err(99));
2366
2367 if let Some(val) = err_kp.get_mut(&mut err_result) {
2369 *val = 100;
2370 }
2371 assert_eq!(err_result, Err(100));
2372 }
2373
2374 #[test]
2375 fn test_enum_kp_option_some() {
2376 let some_opt = Some("value".to_string());
2377 let mut none_opt: Option<String> = None;
2378
2379 let some_kp = enum_some();
2380
2381 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2383 assert_eq!(some_kp.get(&none_opt), None);
2384
2385 let embedded = some_kp.embed("embedded".to_string());
2387 assert_eq!(embedded, Some("embedded".to_string()));
2388
2389 let mut some_opt2 = Some("original".to_string());
2391 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2392 *val = "modified".to_string();
2393 }
2394 assert_eq!(some_opt2, Some("modified".to_string()));
2395 }
2396
2397 #[test]
2398 fn test_enum_kp_custom_enum() {
2399 #[derive(Debug, PartialEq)]
2400 enum MyEnum {
2401 A(String),
2402 B(i32),
2403 C,
2404 }
2405
2406 let mut enum_a = MyEnum::A("hello".to_string());
2407 let enum_b = MyEnum::B(42);
2408 let enum_c = MyEnum::C;
2409
2410 let kp_a = enum_variant(
2412 |e: &MyEnum| match e {
2413 MyEnum::A(s) => Some(s),
2414 _ => None,
2415 },
2416 |e: &mut MyEnum| match e {
2417 MyEnum::A(s) => Some(s),
2418 _ => None,
2419 },
2420 |s: String| MyEnum::A(s),
2421 );
2422
2423 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2425 assert_eq!(kp_a.get(&enum_b), None);
2426 assert_eq!(kp_a.get(&enum_c), None);
2427
2428 let embedded = kp_a.embed("world".to_string());
2430 assert_eq!(embedded, MyEnum::A("world".to_string()));
2431
2432 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2434 *val = "modified".to_string();
2435 }
2436 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2437 }
2438
2439 #[test]
2440 fn test_container_kp_box() {
2441 let boxed = Box::new("value".to_string());
2442 let mut boxed_mut = Box::new("original".to_string());
2443
2444 let box_kp = kp_box();
2445
2446 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2448
2449 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2451 *val = "modified".to_string();
2452 }
2453 assert_eq!(*boxed_mut, "modified".to_string());
2454 }
2455
2456 #[test]
2457 fn test_container_kp_arc() {
2458 let arc = Arc::new("value".to_string());
2459 let mut arc_mut = Arc::new("original".to_string());
2460
2461 let arc_kp = kp_arc();
2462
2463 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2465
2466 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2468 *val = "modified".to_string();
2469 }
2470 assert_eq!(*arc_mut, "modified".to_string());
2471
2472 let arc_shared = Arc::new("shared".to_string());
2474 let arc_shared2 = Arc::clone(&arc_shared);
2475 let mut arc_shared_mut = arc_shared;
2476 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2477 }
2478
2479 #[test]
2480 fn test_enum_kp_composition() {
2481 #[derive(Debug, PartialEq)]
2483 struct Inner {
2484 value: String,
2485 }
2486
2487 let result: Result<Inner, i32> = Ok(Inner {
2488 value: "nested".to_string(),
2489 });
2490
2491 let inner_kp = KpType::new(
2493 |i: &Inner| Some(&i.value),
2494 |i: &mut Inner| Some(&mut i.value),
2495 );
2496
2497 let ok_kp = enum_ok::<Inner, i32>();
2499 let ok_kp_base = ok_kp.into_kp();
2500 let composed = ok_kp_base.then(inner_kp);
2501
2502 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2503 }
2504
2505 #[test]
2506 fn test_pkp_basic() {
2507 #[derive(Debug)]
2508 struct User {
2509 name: String,
2510 age: i32,
2511 }
2512
2513 let user = User {
2514 name: "Alice".to_string(),
2515 age: 30,
2516 };
2517
2518 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2520 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2521
2522 let name_pkp = PKp::new(name_kp);
2524 let age_pkp = PKp::new(age_kp);
2525
2526 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2528 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2529
2530 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2532 assert_eq!(age_pkp.get_as::<String>(&user), None);
2533
2534 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2536 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2537 }
2538
2539 #[test]
2540 fn test_pkp_collection() {
2541 #[derive(Debug)]
2542 struct User {
2543 name: String,
2544 age: i32,
2545 }
2546
2547 let user = User {
2548 name: "Bob".to_string(),
2549 age: 25,
2550 };
2551
2552 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2554 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2555
2556 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2557
2558 let name_value = keypaths[0].get_as::<String>(&user);
2560 let age_value = keypaths[1].get_as::<i32>(&user);
2561
2562 assert_eq!(name_value, Some(&"Bob".to_string()));
2563 assert_eq!(age_value, Some(&25));
2564 }
2565
2566 #[test]
2567 fn test_pkp_for_arc() {
2568 #[derive(Debug)]
2569 struct User {
2570 name: String,
2571 }
2572
2573 let user = Arc::new(User {
2574 name: "Charlie".to_string(),
2575 });
2576
2577 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2578 let name_pkp = PKp::new(name_kp);
2579
2580 let arc_pkp = name_pkp.for_arc();
2582
2583 assert_eq!(
2584 arc_pkp.get_as::<String>(&user),
2585 Some(&"Charlie".to_string())
2586 );
2587 }
2588
2589 #[test]
2590 fn test_pkp_for_option() {
2591 #[derive(Debug)]
2592 struct User {
2593 name: String,
2594 }
2595
2596 let some_user = Some(User {
2597 name: "Diana".to_string(),
2598 });
2599 let none_user: Option<User> = None;
2600
2601 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2602 let name_pkp = PKp::new(name_kp);
2603
2604 let opt_pkp = name_pkp.for_option();
2606
2607 assert_eq!(
2608 opt_pkp.get_as::<String>(&some_user),
2609 Some(&"Diana".to_string())
2610 );
2611 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2612 }
2613
2614 #[test]
2615 fn test_akp_basic() {
2616 #[derive(Debug)]
2617 struct User {
2618 name: String,
2619 age: i32,
2620 }
2621
2622 #[derive(Debug)]
2623 struct Product {
2624 title: String,
2625 price: f64,
2626 }
2627
2628 let user = User {
2629 name: "Eve".to_string(),
2630 age: 28,
2631 };
2632
2633 let product = Product {
2634 title: "Book".to_string(),
2635 price: 19.99,
2636 };
2637
2638 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2640 let user_name_akp = AKp::new(user_name_kp);
2641
2642 let product_title_kp = KpType::new(
2643 |p: &Product| Some(&p.title),
2644 |p: &mut Product| Some(&mut p.title),
2645 );
2646 let product_title_akp = AKp::new(product_title_kp);
2647
2648 assert_eq!(
2650 user_name_akp.get_as::<User, String>(&user),
2651 Some(Some(&"Eve".to_string()))
2652 );
2653 assert_eq!(
2654 product_title_akp.get_as::<Product, String>(&product),
2655 Some(Some(&"Book".to_string()))
2656 );
2657
2658 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2660 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2661
2662 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2664 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2665 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2666 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2667 }
2668
2669 #[test]
2670 fn test_akp_heterogeneous_collection() {
2671 #[derive(Debug)]
2672 struct User {
2673 name: String,
2674 }
2675
2676 #[derive(Debug)]
2677 struct Product {
2678 title: String,
2679 }
2680
2681 let user = User {
2682 name: "Frank".to_string(),
2683 };
2684 let product = Product {
2685 title: "Laptop".to_string(),
2686 };
2687
2688 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2690 let product_title_kp = KpType::new(
2691 |p: &Product| Some(&p.title),
2692 |p: &mut Product| Some(&mut p.title),
2693 );
2694
2695 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2696
2697 let user_any: &dyn Any = &user;
2699 let product_any: &dyn Any = &product;
2700
2701 let user_value = keypaths[0].get(user_any);
2702 let product_value = keypaths[1].get(product_any);
2703
2704 assert!(user_value.is_some());
2705 assert!(product_value.is_some());
2706
2707 assert_eq!(
2709 user_value.and_then(|v| v.downcast_ref::<String>()),
2710 Some(&"Frank".to_string())
2711 );
2712 assert_eq!(
2713 product_value.and_then(|v| v.downcast_ref::<String>()),
2714 Some(&"Laptop".to_string())
2715 );
2716 }
2717
2718 #[test]
2719 fn test_akp_for_option() {
2720 #[derive(Debug)]
2721 struct User {
2722 name: String,
2723 }
2724
2725 let some_user = Some(User {
2726 name: "Grace".to_string(),
2727 });
2728 let none_user: Option<User> = None;
2729
2730 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2731 let name_akp = AKp::new(name_kp);
2732
2733 let opt_akp = name_akp.for_option::<User>();
2735
2736 assert_eq!(
2737 opt_akp.get_as::<Option<User>, String>(&some_user),
2738 Some(Some(&"Grace".to_string()))
2739 );
2740 assert_eq!(
2741 opt_akp.get_as::<Option<User>, String>(&none_user),
2742 Some(None)
2743 );
2744 }
2745
2746 #[test]
2747 fn test_akp_for_result() {
2748 #[derive(Debug)]
2749 struct User {
2750 name: String,
2751 }
2752
2753 let ok_user: Result<User, String> = Ok(User {
2754 name: "Henry".to_string(),
2755 });
2756 let err_user: Result<User, String> = Err("Not found".to_string());
2757
2758 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2759 let name_akp = AKp::new(name_kp);
2760
2761 let result_akp = name_akp.for_result::<User, String>();
2763
2764 assert_eq!(
2765 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2766 Some(Some(&"Henry".to_string()))
2767 );
2768 assert_eq!(
2769 result_akp.get_as::<Result<User, String>, String>(&err_user),
2770 Some(None)
2771 );
2772 }
2773
2774 #[test]
2777 fn test_kp_map() {
2778 #[derive(Debug)]
2779 struct User {
2780 name: String,
2781 age: i32,
2782 }
2783
2784 let user = User {
2785 name: "Alice".to_string(),
2786 age: 30,
2787 };
2788
2789 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2791 let len_kp = name_kp.map(|name: &String| name.len());
2792
2793 assert_eq!(len_kp.get(&user), Some(5));
2794
2795 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2797 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2798
2799 assert_eq!(double_age_kp.get(&user), Some(60));
2800
2801 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2803 assert_eq!(is_adult_kp.get(&user), Some(true));
2804 }
2805
2806 #[test]
2807 fn test_kp_filter() {
2808 #[derive(Debug)]
2809 struct User {
2810 name: String,
2811 age: i32,
2812 }
2813
2814 let adult = User {
2815 name: "Alice".to_string(),
2816 age: 30,
2817 };
2818
2819 let minor = User {
2820 name: "Bob".to_string(),
2821 age: 15,
2822 };
2823
2824 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2825 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2826
2827 assert_eq!(adult_age_kp.get(&adult), Some(&30));
2828 assert_eq!(adult_age_kp.get(&minor), None);
2829
2830 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2832 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2833
2834 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2835 assert_eq!(short_name_kp.get(&adult), None);
2836 }
2837
2838 #[test]
2839 fn test_kp_map_and_filter() {
2840 #[derive(Debug)]
2841 struct User {
2842 scores: Vec<i32>,
2843 }
2844
2845 let user = User {
2846 scores: vec![85, 92, 78, 95],
2847 };
2848
2849 let scores_kp = KpType::new(
2850 |u: &User| Some(&u.scores),
2851 |u: &mut User| Some(&mut u.scores),
2852 );
2853
2854 let avg_kp =
2856 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2857
2858 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2860
2861 assert_eq!(high_avg_kp.get(&user), Some(87)); }
2863
2864 #[test]
2865 fn test_enum_kp_map() {
2866 let ok_result: Result<String, i32> = Ok("hello".to_string());
2867 let err_result: Result<String, i32> = Err(42);
2868
2869 let ok_kp = enum_ok::<String, i32>();
2870 let len_kp = ok_kp.map(|s: &String| s.len());
2871
2872 assert_eq!(len_kp.get(&ok_result), Some(5));
2873 assert_eq!(len_kp.get(&err_result), None);
2874
2875 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2877 let none_opt: Option<Vec<i32>> = None;
2878
2879 let some_kp = enum_some::<Vec<i32>>();
2880 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2881
2882 assert_eq!(count_kp.get(&some_opt), Some(5));
2883 assert_eq!(count_kp.get(&none_opt), None);
2884 }
2885
2886 #[test]
2887 fn test_enum_kp_filter() {
2888 let ok_result1: Result<i32, String> = Ok(42);
2889 let ok_result2: Result<i32, String> = Ok(-5);
2890 let err_result: Result<i32, String> = Err("error".to_string());
2891
2892 let ok_kp = enum_ok::<i32, String>();
2893 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2894
2895 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2896 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2901 let short_str = Some("hi".to_string());
2902
2903 let some_kp = enum_some::<String>();
2904 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2905
2906 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2907 assert_eq!(long_kp.get(&short_str), None);
2908 }
2909
2910 #[test]
2911 fn test_pkp_filter() {
2912 #[derive(Debug)]
2913 struct User {
2914 name: String,
2915 age: i32,
2916 }
2917
2918 let adult = User {
2919 name: "Alice".to_string(),
2920 age: 30,
2921 };
2922
2923 let minor = User {
2924 name: "Bob".to_string(),
2925 age: 15,
2926 };
2927
2928 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2929 let age_pkp = PKp::new(age_kp);
2930
2931 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2933
2934 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2935 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2936
2937 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2939 let name_pkp = PKp::new(name_kp);
2940 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2941
2942 assert_eq!(
2943 short_name_pkp.get_as::<String>(&minor),
2944 Some(&"Bob".to_string())
2945 );
2946 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2947 }
2948
2949 #[test]
2950 fn test_akp_filter() {
2951 #[derive(Debug)]
2952 struct User {
2953 age: i32,
2954 }
2955
2956 #[derive(Debug)]
2957 struct Product {
2958 price: f64,
2959 }
2960
2961 let adult = User { age: 30 };
2962 let minor = User { age: 15 };
2963 let expensive = Product { price: 99.99 };
2964 let cheap = Product { price: 5.0 };
2965
2966 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2968 let age_akp = AKp::new(age_kp);
2969 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2970
2971 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2972 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2973
2974 let price_kp = KpType::new(
2976 |p: &Product| Some(&p.price),
2977 |p: &mut Product| Some(&mut p.price),
2978 );
2979 let price_akp = AKp::new(price_kp);
2980 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2981
2982 assert_eq!(
2983 expensive_akp.get_as::<Product, f64>(&expensive),
2984 Some(Some(&99.99))
2985 );
2986 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2987 }
2988
2989 #[test]
2992 fn test_kp_filter_map() {
2993 #[derive(Debug)]
2994 struct User {
2995 middle_name: Option<String>,
2996 }
2997
2998 let user_with = User {
2999 middle_name: Some("Marie".to_string()),
3000 };
3001 let user_without = User { middle_name: None };
3002
3003 let middle_kp = KpType::new(
3004 |u: &User| Some(&u.middle_name),
3005 |u: &mut User| Some(&mut u.middle_name),
3006 );
3007
3008 let first_char_kp = middle_kp
3009 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
3010
3011 assert_eq!(first_char_kp.get(&user_with), Some('M'));
3012 assert_eq!(first_char_kp.get(&user_without), None);
3013 }
3014
3015 #[test]
3016 fn test_kp_inspect() {
3017 #[derive(Debug)]
3018 struct User {
3019 name: String,
3020 }
3021
3022 let user = User {
3023 name: "Alice".to_string(),
3024 };
3025
3026 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3030
3031 let result = name_kp.get(&user);
3034 assert_eq!(result, Some(&"Alice".to_string()));
3035
3036 }
3039
3040 #[test]
3041 fn test_kp_fold_value() {
3042 #[derive(Debug)]
3043 struct User {
3044 scores: Vec<i32>,
3045 }
3046
3047 let user = User {
3048 scores: vec![85, 92, 78, 95],
3049 };
3050
3051 let scores_kp = KpType::new(
3052 |u: &User| Some(&u.scores),
3053 |u: &mut User| Some(&mut u.scores),
3054 );
3055
3056 let sum_fn =
3058 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
3059
3060 assert_eq!(sum_fn(&user), 350);
3061 }
3062
3063 #[test]
3064 fn test_kp_any_all() {
3065 #[derive(Debug)]
3066 struct User {
3067 scores: Vec<i32>,
3068 }
3069
3070 let user_high = User {
3071 scores: vec![85, 92, 88],
3072 };
3073 let user_mixed = User {
3074 scores: vec![65, 92, 78],
3075 };
3076
3077 let scores_kp = KpType::new(
3078 |u: &User| Some(&u.scores),
3079 |u: &mut User| Some(&mut u.scores),
3080 );
3081
3082 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
3084 assert!(has_high_fn(&user_high));
3085 assert!(has_high_fn(&user_mixed));
3086
3087 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
3089 assert!(all_passing_fn(&user_high));
3090 assert!(!all_passing_fn(&user_mixed));
3091 }
3092
3093 #[test]
3094 fn test_kp_count_items() {
3095 #[derive(Debug)]
3096 struct User {
3097 tags: Vec<String>,
3098 }
3099
3100 let user = User {
3101 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
3102 };
3103
3104 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3105 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
3106
3107 assert_eq!(count_fn(&user), Some(3));
3108 }
3109
3110 #[test]
3111 fn test_kp_find_in() {
3112 #[derive(Debug)]
3113 struct User {
3114 scores: Vec<i32>,
3115 }
3116
3117 let user = User {
3118 scores: vec![85, 92, 78, 95, 88],
3119 };
3120
3121 let scores_kp = KpType::new(
3122 |u: &User| Some(&u.scores),
3123 |u: &mut User| Some(&mut u.scores),
3124 );
3125
3126 let first_high_fn =
3128 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3129
3130 assert_eq!(first_high_fn(&user), Some(92));
3131
3132 let perfect_fn =
3134 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3135
3136 assert_eq!(perfect_fn(&user), None);
3137 }
3138
3139 #[test]
3140 fn test_kp_take_skip() {
3141 #[derive(Debug)]
3142 struct User {
3143 tags: Vec<String>,
3144 }
3145
3146 let user = User {
3147 tags: vec![
3148 "a".to_string(),
3149 "b".to_string(),
3150 "c".to_string(),
3151 "d".to_string(),
3152 ],
3153 };
3154
3155 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3156
3157 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3159 tags.iter().take(n).cloned().collect::<Vec<_>>()
3160 });
3161
3162 let taken = take_fn(&user).unwrap();
3163 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3164
3165 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3167 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3168 });
3169
3170 let skipped = skip_fn(&user).unwrap();
3171 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3172 }
3173
3174 #[test]
3175 fn test_kp_partition() {
3176 #[derive(Debug)]
3177 struct User {
3178 scores: Vec<i32>,
3179 }
3180
3181 let user = User {
3182 scores: vec![85, 92, 65, 95, 72, 58],
3183 };
3184
3185 let scores_kp = KpType::new(
3186 |u: &User| Some(&u.scores),
3187 |u: &mut User| Some(&mut u.scores),
3188 );
3189
3190 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3191 scores.iter().copied().partition(|&s| s >= 70)
3192 });
3193
3194 let (passing, failing) = partition_fn(&user).unwrap();
3195 assert_eq!(passing, vec![85, 92, 95, 72]);
3196 assert_eq!(failing, vec![65, 58]);
3197 }
3198
3199 #[test]
3200 fn test_kp_min_max() {
3201 #[derive(Debug)]
3202 struct User {
3203 scores: Vec<i32>,
3204 }
3205
3206 let user = User {
3207 scores: vec![85, 92, 78, 95, 88],
3208 };
3209
3210 let scores_kp = KpType::new(
3211 |u: &User| Some(&u.scores),
3212 |u: &mut User| Some(&mut u.scores),
3213 );
3214
3215 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3217 assert_eq!(min_fn(&user), Some(78));
3218
3219 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3221 assert_eq!(max_fn(&user), Some(95));
3222 }
3223
3224 #[test]
3225 fn test_kp_sum() {
3226 #[derive(Debug)]
3227 struct User {
3228 scores: Vec<i32>,
3229 }
3230
3231 let user = User {
3232 scores: vec![85, 92, 78],
3233 };
3234
3235 let scores_kp = KpType::new(
3236 |u: &User| Some(&u.scores),
3237 |u: &mut User| Some(&mut u.scores),
3238 );
3239
3240 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3241 assert_eq!(sum_fn(&user), Some(255));
3242
3243 let avg_fn =
3245 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3246 assert_eq!(avg_fn.get(&user), Some(85));
3247 }
3248
3249 #[test]
3250 fn test_kp_chain() {
3251 #[derive(Debug)]
3252 struct User {
3253 profile: Profile,
3254 }
3255
3256 #[derive(Debug)]
3257 struct Profile {
3258 settings: Settings,
3259 }
3260
3261 #[derive(Debug)]
3262 struct Settings {
3263 theme: String,
3264 }
3265
3266 let user = User {
3267 profile: Profile {
3268 settings: Settings {
3269 theme: "dark".to_string(),
3270 },
3271 },
3272 };
3273
3274 let profile_kp = KpType::new(
3275 |u: &User| Some(&u.profile),
3276 |u: &mut User| Some(&mut u.profile),
3277 );
3278 let settings_kp = KpType::new(
3279 |p: &Profile| Some(&p.settings),
3280 |p: &mut Profile| Some(&mut p.settings),
3281 );
3282 let theme_kp = KpType::new(
3283 |s: &Settings| Some(&s.theme),
3284 |s: &mut Settings| Some(&mut s.theme),
3285 );
3286
3287 let profile_settings = profile_kp.chain(settings_kp);
3289 let theme_path = profile_settings.chain(theme_kp);
3290 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3291 }
3292
3293 #[test]
3294 fn test_kp_zip() {
3295 #[derive(Debug)]
3296 struct User {
3297 name: String,
3298 age: i32,
3299 }
3300
3301 let user = User {
3302 name: "Alice".to_string(),
3303 age: 30,
3304 };
3305
3306 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3307 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3308
3309 let zipped_fn = zip_kps(&name_kp, &age_kp);
3310 let result = zipped_fn(&user);
3311
3312 assert_eq!(result, Some((&"Alice".to_string(), &30)));
3313 }
3314
3315 #[test]
3316 fn test_kp_complex_pipeline() {
3317 #[derive(Debug)]
3318 struct User {
3319 transactions: Vec<Transaction>,
3320 }
3321
3322 #[derive(Debug)]
3323 struct Transaction {
3324 amount: f64,
3325 category: String,
3326 }
3327
3328 let user = User {
3329 transactions: vec![
3330 Transaction {
3331 amount: 50.0,
3332 category: "food".to_string(),
3333 },
3334 Transaction {
3335 amount: 100.0,
3336 category: "transport".to_string(),
3337 },
3338 Transaction {
3339 amount: 25.0,
3340 category: "food".to_string(),
3341 },
3342 Transaction {
3343 amount: 200.0,
3344 category: "shopping".to_string(),
3345 },
3346 ],
3347 };
3348
3349 let txns_kp = KpType::new(
3350 |u: &User| Some(&u.transactions),
3351 |u: &mut User| Some(&mut u.transactions),
3352 );
3353
3354 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3356 txns.iter()
3357 .filter(|t| t.category == "food")
3358 .map(|t| t.amount)
3359 .sum::<f64>()
3360 });
3361
3362 assert_eq!(food_total.get(&user), Some(75.0));
3363
3364 let has_large =
3366 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3367
3368 assert!(has_large(&user));
3369
3370 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3372 assert_eq!(count(&user), Some(4));
3373 }
3374
3375 #[test]
3379 fn test_no_clone_required_for_root() {
3380 use std::sync::Arc;
3381 use std::sync::atomic::{AtomicUsize, Ordering};
3382
3383 struct NonCloneableRoot {
3386 data: Arc<AtomicUsize>,
3387 cached_value: usize,
3388 }
3389
3390 impl NonCloneableRoot {
3391 fn new() -> Self {
3392 Self {
3393 data: Arc::new(AtomicUsize::new(42)),
3394 cached_value: 42,
3395 }
3396 }
3397
3398 fn increment(&mut self) {
3399 self.data.fetch_add(1, Ordering::SeqCst);
3400 self.cached_value = self.data.load(Ordering::SeqCst);
3401 }
3402
3403 fn get_value(&self) -> &usize {
3404 &self.cached_value
3405 }
3406
3407 fn get_value_mut(&mut self) -> &mut usize {
3408 &mut self.cached_value
3409 }
3410 }
3411
3412 let mut root = NonCloneableRoot::new();
3413
3414 let data_kp = KpType::new(
3416 |r: &NonCloneableRoot| Some(r.get_value()),
3417 |r: &mut NonCloneableRoot| {
3418 r.increment();
3419 Some(r.get_value_mut())
3420 },
3421 );
3422
3423 assert_eq!(data_kp.get(&root), Some(&42));
3425
3426 {
3427 let doubled = data_kp.map(|val: &usize| val * 2);
3429 assert_eq!(doubled.get(&root), Some(84));
3430
3431 let filtered = data_kp.filter(|val: &usize| *val > 0);
3433 assert_eq!(filtered.get(&root), Some(&42));
3434 } let value_ref = data_kp.get_mut(&mut root);
3438 assert!(value_ref.is_some());
3439 }
3440
3441 #[test]
3442 fn test_no_clone_required_for_value() {
3443 use std::sync::Arc;
3444 use std::sync::atomic::{AtomicUsize, Ordering};
3445
3446 struct NonCloneableValue {
3448 counter: Arc<AtomicUsize>,
3449 }
3450
3451 impl NonCloneableValue {
3452 fn new(val: usize) -> Self {
3453 Self {
3454 counter: Arc::new(AtomicUsize::new(val)),
3455 }
3456 }
3457
3458 fn get(&self) -> usize {
3459 self.counter.load(Ordering::SeqCst)
3460 }
3461 }
3462
3463 struct Root {
3464 value: NonCloneableValue,
3465 }
3466
3467 let root = Root {
3468 value: NonCloneableValue::new(100),
3469 };
3470
3471 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3473
3474 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3476 assert_eq!(counter_kp.get(&root), Some(100));
3477
3478 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3480 assert!(filtered.get(&root).is_some());
3481 }
3482
3483 #[test]
3484 fn test_static_does_not_leak_memory() {
3485 use std::sync::Arc;
3486 use std::sync::atomic::{AtomicUsize, Ordering};
3487
3488 static CREATED: AtomicUsize = AtomicUsize::new(0);
3490 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3491
3492 struct Tracked {
3493 id: usize,
3494 }
3495
3496 impl Tracked {
3497 fn new() -> Self {
3498 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3499 Self { id }
3500 }
3501 }
3502
3503 impl Drop for Tracked {
3504 fn drop(&mut self) {
3505 DROPPED.fetch_add(1, Ordering::SeqCst);
3506 }
3507 }
3508
3509 struct Root {
3510 data: Tracked,
3511 }
3512
3513 CREATED.store(0, Ordering::SeqCst);
3515 DROPPED.store(0, Ordering::SeqCst);
3516
3517 {
3518 let root = Root {
3519 data: Tracked::new(),
3520 };
3521
3522 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3523
3524 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3526 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3527 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3528
3529 assert_eq!(mapped1.get(&root), Some(0));
3530 assert_eq!(mapped2.get(&root), Some(1));
3531 assert_eq!(mapped3.get(&root), Some(2));
3532
3533 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3535 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3536 }
3537
3538 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3540 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3541
3542 }
3544
3545 #[test]
3546 fn test_references_not_cloned() {
3547 use std::sync::Arc;
3548
3549 struct ExpensiveData {
3551 large_vec: Vec<u8>,
3552 }
3553
3554 impl ExpensiveData {
3555 fn new(size: usize) -> Self {
3556 Self {
3557 large_vec: vec![0u8; size],
3558 }
3559 }
3560
3561 fn size(&self) -> usize {
3562 self.large_vec.len()
3563 }
3564 }
3565
3566 struct Root {
3567 expensive: ExpensiveData,
3568 }
3569
3570 let root = Root {
3571 expensive: ExpensiveData::new(1_000_000), };
3573
3574 let expensive_kp = KpType::new(
3575 |r: &Root| Some(&r.expensive),
3576 |r: &mut Root| Some(&mut r.expensive),
3577 );
3578
3579 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3581 assert_eq!(size_kp.get(&root), Some(1_000_000));
3582
3583 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3585 assert!(large_filter.get(&root).is_some());
3586
3587 }
3589
3590 #[test]
3591 fn test_hof_with_arc_no_extra_clones() {
3592 use std::sync::Arc;
3593
3594 #[derive(Debug)]
3595 struct SharedData {
3596 value: String,
3597 }
3598
3599 struct Root {
3600 shared: Arc<SharedData>,
3601 }
3602
3603 let shared = Arc::new(SharedData {
3604 value: "shared".to_string(),
3605 });
3606
3607 assert_eq!(Arc::strong_count(&shared), 1);
3609
3610 {
3611 let root = Root {
3612 shared: Arc::clone(&shared),
3613 };
3614
3615 assert_eq!(Arc::strong_count(&shared), 2);
3617
3618 let shared_kp = KpType::new(
3619 |r: &Root| Some(&r.shared),
3620 |r: &mut Root| Some(&mut r.shared),
3621 );
3622
3623 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3625
3626 assert_eq!(value_kp.get(&root), Some(6));
3628 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3632 assert!(filtered.get(&root).is_some());
3633 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3638
3639 #[test]
3640 fn test_closure_captures_not_root_values() {
3641 use std::sync::Arc;
3642 use std::sync::atomic::{AtomicUsize, Ordering};
3643
3644 let call_count = Arc::new(AtomicUsize::new(0));
3646 let call_count_clone = Arc::clone(&call_count);
3647
3648 struct Root {
3649 value: i32,
3650 }
3651
3652 let root = Root { value: 42 };
3653
3654 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3655
3656 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3659 call_count_clone.fetch_add(1, Ordering::SeqCst);
3660 v * 2
3661 });
3662
3663 assert_eq!(doubled(&root), 84);
3665 assert_eq!(doubled(&root), 84);
3666 assert_eq!(doubled(&root), 84);
3667
3668 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3670
3671 }
3673
3674 #[test]
3675 fn test_static_with_borrowed_data() {
3676 struct Root {
3680 data: String,
3681 }
3682
3683 {
3684 let root = Root {
3685 data: "temporary".to_string(),
3686 };
3687
3688 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3689
3690 let len_kp = data_kp.map(|s: &String| s.len());
3692 assert_eq!(len_kp.get(&root), Some(9));
3693
3694 } }
3699
3700 #[test]
3701 fn test_multiple_hof_operations_no_accumulation() {
3702 use std::sync::Arc;
3703 use std::sync::atomic::{AtomicUsize, Ordering};
3704
3705 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3706
3707 struct Tracked {
3708 id: usize,
3709 }
3710
3711 impl Drop for Tracked {
3712 fn drop(&mut self) {
3713 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3714 }
3715 }
3716
3717 struct Root {
3718 values: Vec<Tracked>,
3719 }
3720
3721 DROP_COUNT.store(0, Ordering::SeqCst);
3722
3723 {
3724 let root = Root {
3725 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3726 };
3727
3728 let values_kp = KpType::new(
3729 |r: &Root| Some(&r.values),
3730 |r: &mut Root| Some(&mut r.values),
3731 );
3732
3733 let count = values_kp.count_items(|v| v.len());
3735 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3736 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3737 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3738
3739 assert_eq!(count(&root), Some(3));
3740 assert_eq!(sum(&root), Some(6));
3741 assert!(has_2(&root));
3742 assert!(all_positive(&root));
3743
3744 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3746 }
3747
3748 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3750 }
3751
3752 #[test]
3753 fn test_copy_bound_only_for_function_not_data() {
3754 #[derive(Debug)]
3758 struct NonCopyData {
3759 value: String,
3760 }
3761
3762 struct Root {
3763 data: NonCopyData,
3764 }
3765
3766 let root = Root {
3767 data: NonCopyData {
3768 value: "test".to_string(),
3769 },
3770 };
3771
3772 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3773
3774 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3777 assert_eq!(len_kp.get(&root), Some(4));
3778
3779 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3781 assert!(filtered.get(&root).is_some());
3782 }
3783
3784 #[test]
3785 fn test_no_memory_leak_with_cyclic_references() {
3786 use std::sync::atomic::{AtomicUsize, Ordering};
3787 use std::sync::{Arc, Weak};
3788
3789 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3790
3791 struct Node {
3792 id: usize,
3793 parent: Option<Weak<Node>>,
3794 }
3795
3796 impl Drop for Node {
3797 fn drop(&mut self) {
3798 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3799 }
3800 }
3801
3802 struct Root {
3803 node: Arc<Node>,
3804 }
3805
3806 DROP_COUNT.store(0, Ordering::SeqCst);
3807
3808 {
3809 let root = Root {
3810 node: Arc::new(Node {
3811 id: 1,
3812 parent: None,
3813 }),
3814 };
3815
3816 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3817
3818 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3820 assert_eq!(id_kp.get(&root), Some(1));
3821
3822 assert_eq!(Arc::strong_count(&root.node), 1);
3824
3825 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3827 }
3828
3829 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3831 }
3832
3833 #[test]
3834 fn test_hof_operations_are_zero_cost_abstractions() {
3835 struct Root {
3839 value: i32,
3840 }
3841
3842 let root = Root { value: 10 };
3843
3844 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3845
3846 let direct_result = value_kp.get(&root).map(|v| v * 2);
3848 assert_eq!(direct_result, Some(20));
3849
3850 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3852 let hof_result = mapped_kp.get(&root);
3853 assert_eq!(hof_result, Some(20));
3854
3855 assert_eq!(direct_result, hof_result);
3857 }
3858
3859 #[test]
3860 fn test_complex_closure_captures_allowed() {
3861 use std::sync::Arc;
3862
3863 struct Root {
3865 scores: Vec<i32>,
3866 }
3867
3868 let root = Root {
3869 scores: vec![85, 92, 78, 95, 88],
3870 };
3871
3872 let scores_kp = KpType::new(
3873 |r: &Root| Some(&r.scores),
3874 |r: &mut Root| Some(&mut r.scores),
3875 );
3876
3877 let threshold = 90;
3879 let multiplier = Arc::new(2);
3880
3881 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3883 let high: i32 = scores
3884 .iter()
3885 .filter(|&&s| s >= threshold)
3886 .map(|&s| s * *multiplier)
3887 .sum();
3888 acc + high
3889 });
3890
3891 assert_eq!(high_scores_doubled(&root), 374);
3893 }
3894
3895 #[test]
3899 fn test_pkp_filter_by_value_type() {
3900 use std::any::TypeId;
3901
3902 #[derive(Debug)]
3903 struct User {
3904 name: String,
3905 age: i32,
3906 score: f64,
3907 active: bool,
3908 }
3909
3910 let user = User {
3911 name: "Alice".to_string(),
3912 age: 30,
3913 score: 95.5,
3914 active: true,
3915 };
3916
3917 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3919 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3920 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3921 let active_kp = KpType::new(
3922 |u: &User| Some(&u.active),
3923 |u: &mut User| Some(&mut u.active),
3924 );
3925
3926 let all_keypaths: Vec<PKp<User>> = vec![
3928 PKp::new(name_kp),
3929 PKp::new(age_kp),
3930 PKp::new(score_kp),
3931 PKp::new(active_kp),
3932 ];
3933
3934 let string_kps: Vec<_> = all_keypaths
3936 .iter()
3937 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3938 .collect();
3939
3940 assert_eq!(string_kps.len(), 1);
3941 assert_eq!(
3942 string_kps[0].get_as::<String>(&user),
3943 Some(&"Alice".to_string())
3944 );
3945
3946 let i32_kps: Vec<_> = all_keypaths
3948 .iter()
3949 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3950 .collect();
3951
3952 assert_eq!(i32_kps.len(), 1);
3953 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3954
3955 let f64_kps: Vec<_> = all_keypaths
3957 .iter()
3958 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3959 .collect();
3960
3961 assert_eq!(f64_kps.len(), 1);
3962 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3963
3964 let bool_kps: Vec<_> = all_keypaths
3966 .iter()
3967 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3968 .collect();
3969
3970 assert_eq!(bool_kps.len(), 1);
3971 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3972 }
3973
3974 #[test]
3975 fn test_pkp_filter_by_struct_type() {
3976 use std::any::TypeId;
3977
3978 #[derive(Debug, PartialEq)]
3979 struct Address {
3980 street: String,
3981 city: String,
3982 }
3983
3984 #[derive(Debug)]
3985 struct User {
3986 name: String,
3987 age: i32,
3988 address: Address,
3989 }
3990
3991 let user = User {
3992 name: "Bob".to_string(),
3993 age: 25,
3994 address: Address {
3995 street: "123 Main St".to_string(),
3996 city: "NYC".to_string(),
3997 },
3998 };
3999
4000 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4002 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4003 let address_kp = KpType::new(
4004 |u: &User| Some(&u.address),
4005 |u: &mut User| Some(&mut u.address),
4006 );
4007
4008 let all_keypaths: Vec<PKp<User>> =
4009 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
4010
4011 let struct_kps: Vec<_> = all_keypaths
4013 .iter()
4014 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
4015 .collect();
4016
4017 assert_eq!(struct_kps.len(), 1);
4018 assert_eq!(
4019 struct_kps[0].get_as::<Address>(&user),
4020 Some(&Address {
4021 street: "123 Main St".to_string(),
4022 city: "NYC".to_string(),
4023 })
4024 );
4025
4026 let primitive_kps: Vec<_> = all_keypaths
4028 .iter()
4029 .filter(|pkp| {
4030 pkp.value_type_id() == TypeId::of::<String>()
4031 || pkp.value_type_id() == TypeId::of::<i32>()
4032 })
4033 .collect();
4034
4035 assert_eq!(primitive_kps.len(), 2);
4036 }
4037
4038 #[test]
4039 fn test_pkp_filter_by_arc_type() {
4040 use std::any::TypeId;
4041 use std::sync::Arc;
4042
4043 #[derive(Debug)]
4044 struct User {
4045 name: String,
4046 shared_data: Arc<String>,
4047 shared_number: Arc<i32>,
4048 }
4049
4050 let user = User {
4051 name: "Charlie".to_string(),
4052 shared_data: Arc::new("shared".to_string()),
4053 shared_number: Arc::new(42),
4054 };
4055
4056 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4058 let shared_data_kp = KpType::new(
4059 |u: &User| Some(&u.shared_data),
4060 |u: &mut User| Some(&mut u.shared_data),
4061 );
4062 let shared_number_kp = KpType::new(
4063 |u: &User| Some(&u.shared_number),
4064 |u: &mut User| Some(&mut u.shared_number),
4065 );
4066
4067 let all_keypaths: Vec<PKp<User>> = vec![
4068 PKp::new(name_kp),
4069 PKp::new(shared_data_kp),
4070 PKp::new(shared_number_kp),
4071 ];
4072
4073 let arc_string_kps: Vec<_> = all_keypaths
4075 .iter()
4076 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
4077 .collect();
4078
4079 assert_eq!(arc_string_kps.len(), 1);
4080 assert_eq!(
4081 arc_string_kps[0]
4082 .get_as::<Arc<String>>(&user)
4083 .map(|arc| arc.as_str()),
4084 Some("shared")
4085 );
4086
4087 let arc_i32_kps: Vec<_> = all_keypaths
4089 .iter()
4090 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
4091 .collect();
4092
4093 assert_eq!(arc_i32_kps.len(), 1);
4094 assert_eq!(
4095 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
4096 Some(42)
4097 );
4098
4099 let all_arc_kps: Vec<_> = all_keypaths
4101 .iter()
4102 .filter(|pkp| {
4103 pkp.value_type_id() == TypeId::of::<Arc<String>>()
4104 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
4105 })
4106 .collect();
4107
4108 assert_eq!(all_arc_kps.len(), 2);
4109 }
4110
4111 #[test]
4112 fn test_pkp_filter_by_box_type() {
4113 use std::any::TypeId;
4114
4115 #[derive(Debug)]
4116 struct User {
4117 name: String,
4118 boxed_value: Box<i32>,
4119 boxed_string: Box<String>,
4120 }
4121
4122 let user = User {
4123 name: "Diana".to_string(),
4124 boxed_value: Box::new(100),
4125 boxed_string: Box::new("boxed".to_string()),
4126 };
4127
4128 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4130 let boxed_value_kp = KpType::new(
4131 |u: &User| Some(&u.boxed_value),
4132 |u: &mut User| Some(&mut u.boxed_value),
4133 );
4134 let boxed_string_kp = KpType::new(
4135 |u: &User| Some(&u.boxed_string),
4136 |u: &mut User| Some(&mut u.boxed_string),
4137 );
4138
4139 let all_keypaths: Vec<PKp<User>> = vec![
4140 PKp::new(name_kp),
4141 PKp::new(boxed_value_kp),
4142 PKp::new(boxed_string_kp),
4143 ];
4144
4145 let box_i32_kps: Vec<_> = all_keypaths
4147 .iter()
4148 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4149 .collect();
4150
4151 assert_eq!(box_i32_kps.len(), 1);
4152 assert_eq!(
4153 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4154 Some(100)
4155 );
4156
4157 let box_string_kps: Vec<_> = all_keypaths
4159 .iter()
4160 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4161 .collect();
4162
4163 assert_eq!(box_string_kps.len(), 1);
4164 assert_eq!(
4165 box_string_kps[0]
4166 .get_as::<Box<String>>(&user)
4167 .map(|b| b.as_str()),
4168 Some("boxed")
4169 );
4170 }
4171
4172 #[test]
4173 fn test_akp_filter_by_root_and_value_type() {
4174 use std::any::TypeId;
4175
4176 #[derive(Debug)]
4177 struct User {
4178 name: String,
4179 age: i32,
4180 }
4181
4182 #[derive(Debug)]
4183 struct Product {
4184 title: String,
4185 price: f64,
4186 }
4187
4188 let user = User {
4189 name: "Eve".to_string(),
4190 age: 28,
4191 };
4192
4193 let product = Product {
4194 title: "Book".to_string(),
4195 price: 19.99,
4196 };
4197
4198 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4200 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4201 let product_title_kp = KpType::new(
4202 |p: &Product| Some(&p.title),
4203 |p: &mut Product| Some(&mut p.title),
4204 );
4205 let product_price_kp = KpType::new(
4206 |p: &Product| Some(&p.price),
4207 |p: &mut Product| Some(&mut p.price),
4208 );
4209
4210 let all_keypaths: Vec<AKp> = vec![
4211 AKp::new(user_name_kp),
4212 AKp::new(user_age_kp),
4213 AKp::new(product_title_kp),
4214 AKp::new(product_price_kp),
4215 ];
4216
4217 let user_kps: Vec<_> = all_keypaths
4219 .iter()
4220 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4221 .collect();
4222
4223 assert_eq!(user_kps.len(), 2);
4224
4225 let product_kps: Vec<_> = all_keypaths
4227 .iter()
4228 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4229 .collect();
4230
4231 assert_eq!(product_kps.len(), 2);
4232
4233 let string_value_kps: Vec<_> = all_keypaths
4235 .iter()
4236 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4237 .collect();
4238
4239 assert_eq!(string_value_kps.len(), 2);
4240
4241 let user_string_kps: Vec<_> = all_keypaths
4243 .iter()
4244 .filter(|akp| {
4245 akp.root_type_id() == TypeId::of::<User>()
4246 && akp.value_type_id() == TypeId::of::<String>()
4247 })
4248 .collect();
4249
4250 assert_eq!(user_string_kps.len(), 1);
4251 assert_eq!(
4252 user_string_kps[0].get_as::<User, String>(&user),
4253 Some(Some(&"Eve".to_string()))
4254 );
4255
4256 let product_f64_kps: Vec<_> = all_keypaths
4258 .iter()
4259 .filter(|akp| {
4260 akp.root_type_id() == TypeId::of::<Product>()
4261 && akp.value_type_id() == TypeId::of::<f64>()
4262 })
4263 .collect();
4264
4265 assert_eq!(product_f64_kps.len(), 1);
4266 assert_eq!(
4267 product_f64_kps[0].get_as::<Product, f64>(&product),
4268 Some(Some(&19.99))
4269 );
4270 }
4271
4272 #[test]
4273 fn test_akp_filter_by_arc_root_type() {
4274 use std::any::TypeId;
4275 use std::sync::Arc;
4276
4277 #[derive(Debug)]
4278 struct User {
4279 name: String,
4280 }
4281
4282 #[derive(Debug)]
4283 struct Product {
4284 title: String,
4285 }
4286
4287 let user = User {
4288 name: "Frank".to_string(),
4289 };
4290 let product = Product {
4291 title: "Laptop".to_string(),
4292 };
4293
4294 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4296 let product_title_kp = KpType::new(
4297 |p: &Product| Some(&p.title),
4298 |p: &mut Product| Some(&mut p.title),
4299 );
4300
4301 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4303 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4304
4305 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4306
4307 let arc_user_kps: Vec<_> = all_keypaths
4309 .iter()
4310 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4311 .collect();
4312
4313 assert_eq!(arc_user_kps.len(), 1);
4314
4315 let arc_user = Arc::new(user);
4317 assert_eq!(
4318 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4319 Some(Some(&"Frank".to_string()))
4320 );
4321
4322 let arc_product_kps: Vec<_> = all_keypaths
4324 .iter()
4325 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4326 .collect();
4327
4328 assert_eq!(arc_product_kps.len(), 1);
4329
4330 let arc_product = Arc::new(product);
4332 assert_eq!(
4333 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4334 Some(Some(&"Laptop".to_string()))
4335 );
4336 }
4337
4338 #[test]
4339 fn test_akp_filter_by_box_root_type() {
4340 use std::any::TypeId;
4341
4342 #[derive(Debug)]
4343 struct Config {
4344 setting: String,
4345 }
4346
4347 let config = Config {
4348 setting: "enabled".to_string(),
4349 };
4350
4351 let config_kp1 = KpType::new(
4353 |c: &Config| Some(&c.setting),
4354 |c: &mut Config| Some(&mut c.setting),
4355 );
4356 let config_kp2 = KpType::new(
4357 |c: &Config| Some(&c.setting),
4358 |c: &mut Config| Some(&mut c.setting),
4359 );
4360
4361 let regular_akp = AKp::new(config_kp1);
4363 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4364
4365 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4366
4367 let config_kps: Vec<_> = all_keypaths
4369 .iter()
4370 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4371 .collect();
4372
4373 assert_eq!(config_kps.len(), 1);
4374 assert_eq!(
4375 config_kps[0].get_as::<Config, String>(&config),
4376 Some(Some(&"enabled".to_string()))
4377 );
4378
4379 let box_config_kps: Vec<_> = all_keypaths
4381 .iter()
4382 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4383 .collect();
4384
4385 assert_eq!(box_config_kps.len(), 1);
4386
4387 let box_config = Box::new(Config {
4389 setting: "enabled".to_string(),
4390 });
4391 assert_eq!(
4392 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4393 Some(Some(&"enabled".to_string()))
4394 );
4395 }
4396
4397 #[test]
4398 fn test_mixed_collection_type_filtering() {
4399 use std::any::TypeId;
4400 use std::sync::Arc;
4401
4402 #[derive(Debug)]
4403 struct User {
4404 name: String,
4405 email: String,
4406 }
4407
4408 #[derive(Debug)]
4409 struct Product {
4410 title: String,
4411 sku: String,
4412 }
4413
4414 let user = User {
4415 name: "Grace".to_string(),
4416 email: "grace@example.com".to_string(),
4417 };
4418
4419 let product = Product {
4420 title: "Widget".to_string(),
4421 sku: "WID-001".to_string(),
4422 };
4423
4424 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4426 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4427 let user_email_kp1 =
4428 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4429 let user_email_kp2 =
4430 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4431 let product_title_kp = KpType::new(
4432 |p: &Product| Some(&p.title),
4433 |p: &mut Product| Some(&mut p.title),
4434 );
4435 let product_sku_kp = KpType::new(
4436 |p: &Product| Some(&p.sku),
4437 |p: &mut Product| Some(&mut p.sku),
4438 );
4439
4440 let all_keypaths: Vec<AKp> = vec![
4441 AKp::new(user_name_kp1),
4442 AKp::new(user_email_kp1),
4443 AKp::new(product_title_kp),
4444 AKp::new(product_sku_kp),
4445 AKp::new(user_name_kp2).for_arc::<User>(),
4446 AKp::new(user_email_kp2).for_box::<User>(),
4447 ];
4448
4449 let string_value_kps: Vec<_> = all_keypaths
4451 .iter()
4452 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4453 .collect();
4454
4455 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4459 .iter()
4460 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4461 .collect();
4462
4463 assert_eq!(user_root_kps.len(), 2);
4464
4465 let arc_user_kps: Vec<_> = all_keypaths
4467 .iter()
4468 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4469 .collect();
4470
4471 assert_eq!(arc_user_kps.len(), 1);
4472
4473 let box_user_kps: Vec<_> = all_keypaths
4475 .iter()
4476 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4477 .collect();
4478
4479 assert_eq!(box_user_kps.len(), 1);
4480
4481 let product_kps: Vec<_> = all_keypaths
4483 .iter()
4484 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4485 .collect();
4486
4487 assert_eq!(product_kps.len(), 2);
4488
4489 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4491 assert!(user_value.is_some());
4492 assert!(user_value.unwrap().is_some());
4493 }
4494
4495 #[test]
4500 fn test_kp_with_pin() {
4501 use std::pin::Pin;
4502
4503 #[derive(Debug)]
4507 struct SelfReferential {
4508 value: String,
4509 ptr_to_value: *const String, }
4511
4512 impl SelfReferential {
4513 fn new(s: String) -> Self {
4514 let mut sr = Self {
4515 value: s,
4516 ptr_to_value: std::ptr::null(),
4517 };
4518 sr.ptr_to_value = &sr.value as *const String;
4520 sr
4521 }
4522
4523 fn get_value(&self) -> &str {
4524 &self.value
4525 }
4526 }
4527
4528 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4530 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4531
4532 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4534 |p: &Pin<Box<SelfReferential>>| {
4535 Some(&p.as_ref().get_ref().value)
4537 },
4538 |p: &mut Pin<Box<SelfReferential>>| {
4539 unsafe {
4542 let sr = Pin::get_unchecked_mut(p.as_mut());
4543 Some(&mut sr.value)
4544 }
4545 },
4546 );
4547
4548 let result = kp.get(&pinned);
4550 assert_eq!(result, Some(&"pinned_data".to_string()));
4551
4552 assert_eq!(pinned.get_value(), "pinned_data");
4554 }
4555
4556 #[test]
4557 fn test_kp_with_pin_arc() {
4558 use std::pin::Pin;
4559 use std::sync::Arc;
4560
4561 struct AsyncState {
4562 status: String,
4563 data: Vec<i32>,
4564 }
4565
4566 let state = AsyncState {
4568 status: "ready".to_string(),
4569 data: vec![1, 2, 3, 4, 5],
4570 };
4571
4572 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4573
4574 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4576 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4577 |_: &mut Pin<Arc<AsyncState>>| {
4578 None::<&mut String>
4580 },
4581 );
4582
4583 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4585 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4586 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4587 );
4588
4589 let status = status_kp.get(&pinned_arc);
4590 assert_eq!(status, Some(&"ready".to_string()));
4591
4592 let data = data_kp.get(&pinned_arc);
4593 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4594 }
4595
4596 #[test]
4597 fn test_kp_with_maybe_uninit() {
4598 use std::mem::MaybeUninit;
4599
4600 struct Config {
4604 name: MaybeUninit<String>,
4605 value: MaybeUninit<i32>,
4606 initialized: bool,
4607 }
4608
4609 impl Config {
4610 fn new_uninit() -> Self {
4611 Self {
4612 name: MaybeUninit::uninit(),
4613 value: MaybeUninit::uninit(),
4614 initialized: false,
4615 }
4616 }
4617
4618 fn init(&mut self, name: String, value: i32) {
4619 self.name.write(name);
4620 self.value.write(value);
4621 self.initialized = true;
4622 }
4623
4624 fn get_name(&self) -> Option<&String> {
4625 if self.initialized {
4626 unsafe { Some(self.name.assume_init_ref()) }
4627 } else {
4628 None
4629 }
4630 }
4631
4632 fn get_value(&self) -> Option<&i32> {
4633 if self.initialized {
4634 unsafe { Some(self.value.assume_init_ref()) }
4635 } else {
4636 None
4637 }
4638 }
4639 }
4640
4641 let name_kp: KpType<Config, String> = Kp::new(
4643 |c: &Config| c.get_name(),
4644 |c: &mut Config| {
4645 if c.initialized {
4646 unsafe { Some(c.name.assume_init_mut()) }
4647 } else {
4648 None
4649 }
4650 },
4651 );
4652
4653 let value_kp: KpType<Config, i32> = Kp::new(
4654 |c: &Config| c.get_value(),
4655 |c: &mut Config| {
4656 if c.initialized {
4657 unsafe { Some(c.value.assume_init_mut()) }
4658 } else {
4659 None
4660 }
4661 },
4662 );
4663
4664 let uninit_config = Config::new_uninit();
4666 assert_eq!(name_kp.get(&uninit_config), None);
4667 assert_eq!(value_kp.get(&uninit_config), None);
4668
4669 let mut init_config = Config::new_uninit();
4671 init_config.init("test_config".to_string(), 42);
4672
4673 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4674 assert_eq!(value_kp.get(&init_config), Some(&42));
4675
4676 if let Some(val) = value_kp.get_mut(&mut init_config) {
4678 *val = 100;
4679 }
4680
4681 assert_eq!(value_kp.get(&init_config), Some(&100));
4682 }
4683
4684 #[test]
4685 fn test_kp_with_weak() {
4686 use std::sync::{Arc, Weak};
4687
4688 #[derive(Debug, Clone)]
4692 struct Node {
4693 value: i32,
4694 }
4695
4696 struct NodeWithParent {
4697 value: i32,
4698 parent: Option<Arc<Node>>, }
4700
4701 let parent = Arc::new(Node { value: 100 });
4702
4703 let child = NodeWithParent {
4704 value: 42,
4705 parent: Some(parent.clone()),
4706 };
4707
4708 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4710 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4711 |_: &mut NodeWithParent| None::<&mut i32>,
4712 );
4713
4714 let parent_val = parent_value_kp.get(&child);
4716 assert_eq!(parent_val, Some(&100));
4717 }
4718
4719 #[test]
4720 fn test_kp_with_rc_weak() {
4721 use std::rc::Rc;
4722
4723 struct TreeNode {
4726 value: String,
4727 parent: Option<Rc<TreeNode>>, }
4729
4730 let root = Rc::new(TreeNode {
4731 value: "root".to_string(),
4732 parent: None,
4733 });
4734
4735 let child1 = TreeNode {
4736 value: "child1".to_string(),
4737 parent: Some(root.clone()),
4738 };
4739
4740 let child2 = TreeNode {
4741 value: "child2".to_string(),
4742 parent: Some(root.clone()),
4743 };
4744
4745 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4747 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4748 |_: &mut TreeNode| None::<&mut String>,
4749 );
4750
4751 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4753 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4754
4755 assert_eq!(parent_name_kp.get(&root), None);
4757 }
4758
4759 #[test]
4760 fn test_kp_with_complex_weak_structure() {
4761 use std::sync::Arc;
4762
4763 struct Cache {
4766 data: String,
4767 backup: Option<Arc<Cache>>, }
4769
4770 let primary = Arc::new(Cache {
4771 data: "primary_data".to_string(),
4772 backup: None,
4773 });
4774
4775 let backup = Arc::new(Cache {
4776 data: "backup_data".to_string(),
4777 backup: Some(primary.clone()),
4778 });
4779
4780 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4782 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4783 |_: &mut Arc<Cache>| None::<&mut String>,
4784 );
4785
4786 let data = backup_data_kp.get(&backup);
4788 assert_eq!(data, Some(&"primary_data".to_string()));
4789
4790 let no_backup = backup_data_kp.get(&primary);
4792 assert_eq!(no_backup, None);
4793 }
4794
4795 #[test]
4796 fn test_kp_chain_with_pin_and_arc() {
4797 use std::pin::Pin;
4798 use std::sync::Arc;
4799
4800 struct Outer {
4803 inner: Arc<Inner>,
4804 }
4805
4806 struct Inner {
4807 value: String,
4808 }
4809
4810 let outer = Outer {
4811 inner: Arc::new(Inner {
4812 value: "nested_value".to_string(),
4813 }),
4814 };
4815
4816 let pinned_outer = Box::pin(outer);
4817
4818 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4820 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4821 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4822 );
4823
4824 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4826 |a: &Arc<Inner>| Some(&a.value),
4827 |_: &mut Arc<Inner>| None::<&mut String>,
4828 );
4829
4830 let chained = to_inner.then(to_value);
4832
4833 let result = chained.get(&pinned_outer);
4834 assert_eq!(result, Some(&"nested_value".to_string()));
4835 }
4836
4837 #[test]
4838 fn test_kp_with_maybe_uninit_array() {
4839 use std::mem::MaybeUninit;
4840
4841 struct Buffer {
4845 data: [MaybeUninit<u8>; 10],
4846 len: usize,
4847 }
4848
4849 impl Buffer {
4850 fn new() -> Self {
4851 Self {
4852 data: unsafe { MaybeUninit::uninit().assume_init() },
4853 len: 0,
4854 }
4855 }
4856
4857 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4858 if self.len >= self.data.len() {
4859 return Err("Buffer full");
4860 }
4861 self.data[self.len].write(byte);
4862 self.len += 1;
4863 Ok(())
4864 }
4865
4866 fn get(&self, idx: usize) -> Option<&u8> {
4867 if idx < self.len {
4868 unsafe { Some(self.data[idx].assume_init_ref()) }
4869 } else {
4870 None
4871 }
4872 }
4873
4874 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4875 if idx < self.len {
4876 unsafe { Some(self.data[idx].assume_init_mut()) }
4877 } else {
4878 None
4879 }
4880 }
4881 }
4882
4883 let len_kp: KpType<Buffer, usize> =
4885 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4886
4887 let mut buffer = Buffer::new();
4888
4889 assert_eq!(len_kp.get(&buffer), Some(&0));
4891
4892 buffer.push(1).unwrap();
4894 buffer.push(2).unwrap();
4895 buffer.push(3).unwrap();
4896
4897 assert_eq!(len_kp.get(&buffer), Some(&3));
4899
4900 assert_eq!(buffer.get(0), Some(&1));
4902 assert_eq!(buffer.get(1), Some(&2));
4903 assert_eq!(buffer.get(2), Some(&3));
4904 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4908 *elem = 20;
4909 }
4910 assert_eq!(buffer.get(1), Some(&20));
4911 }
4912
4913 #[test]
4914 fn test_kp_then_lock_deep_structs() {
4915 use std::sync::{Arc, Mutex};
4916
4917 #[derive(Clone)]
4918 struct Root {
4919 guard: Arc<Mutex<Level1>>,
4920 }
4921 #[derive(Clone)]
4922 struct Level1 {
4923 name: String,
4924 nested: Level2,
4925 }
4926 #[derive(Clone)]
4927 struct Level2 {
4928 count: i32,
4929 }
4930
4931 let root = Root {
4932 guard: Arc::new(Mutex::new(Level1 {
4933 name: "deep".to_string(),
4934 nested: Level2 { count: 42 },
4935 })),
4936 };
4937
4938 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4939 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4940
4941 let lock_kp = {
4942 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
4943 Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
4944 let next: KpType<Level1, Level1> =
4945 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4946 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4947 };
4948
4949 let chained = kp_to_guard.then_lock(lock_kp);
4950 let level1 = chained.get(&root);
4951 assert!(level1.is_some());
4952 assert_eq!(level1.unwrap().name, "deep");
4953 assert_eq!(level1.unwrap().nested.count, 42);
4954
4955 let mut_root = &mut root.clone();
4956 let mut_level1 = chained.get_mut(mut_root);
4957 assert!(mut_level1.is_some());
4958 mut_level1.unwrap().nested.count = 99;
4959 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4960 }
4961
4962 #[test]
4963 fn test_kp_then_lock_with_enum() {
4964 use std::sync::{Arc, Mutex};
4965
4966 #[derive(Clone)]
4967 enum Message {
4968 Request(LevelA),
4969 Response(i32),
4970 }
4971 #[derive(Clone)]
4972 struct LevelA {
4973 data: Arc<Mutex<i32>>,
4974 }
4975
4976 struct RootWithEnum {
4977 msg: Arc<Mutex<Message>>,
4978 }
4979
4980 let root = RootWithEnum {
4981 msg: Arc::new(Mutex::new(Message::Request(LevelA {
4982 data: Arc::new(Mutex::new(100)),
4983 }))),
4984 };
4985
4986 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
4987 Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
4988
4989 let lock_kp_msg = {
4990 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
4991 Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
4992 let next: KpType<Message, Message> =
4993 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4994 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4995 };
4996
4997 let chained = kp_msg.then_lock(lock_kp_msg);
4998 let msg = chained.get(&root);
4999 assert!(msg.is_some());
5000 match msg.unwrap() {
5001 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
5002 Message::Response(_) => panic!("expected Request"),
5003 }
5004 }
5005
5006 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5007 #[tokio::test]
5008 async fn test_kp_then_async_deep_chain() {
5009 use std::sync::Arc;
5010 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5011
5012 #[derive(Clone)]
5013 struct Root {
5014 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
5015 }
5016 #[derive(Clone)]
5017 struct Level1 {
5018 value: i32,
5019 }
5020
5021 let root = Root {
5022 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
5023 };
5024
5025 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
5026 |r: &Root| Some(&r.tokio_guard),
5027 |r: &mut Root| Some(&mut r.tokio_guard),
5028 );
5029
5030 let async_kp = {
5031 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
5032 Kp::new(
5033 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
5034 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
5035 );
5036 let next: KpType<Level1, Level1> =
5037 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5038 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5039 };
5040
5041 let chained = kp_to_guard.then_async(async_kp);
5042 let level1 = chained.get(&root).await;
5043 assert!(level1.is_some());
5044 assert_eq!(level1.unwrap().value, 7);
5045 }
5046
5047 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5050 #[tokio::test]
5051 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
5052 use std::sync::{Arc, Mutex};
5053 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5054 use crate::lock::{LockKp, ArcMutexAccess};
5055
5056 #[derive(Clone)]
5058 struct Root {
5059 sync_mutex: Arc<Mutex<Level1>>,
5060 }
5061 #[derive(Clone)]
5063 struct Level1 {
5064 inner: Level2,
5065 }
5066 #[derive(Clone)]
5068 struct Level2 {
5069 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
5070 }
5071 #[derive(Clone)]
5073 struct Level3 {
5074 leaf: i32,
5075 }
5076
5077 let mut root = Root {
5078 sync_mutex: Arc::new(Mutex::new(Level1 {
5079 inner: Level2 {
5080 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
5081 },
5082 })),
5083 };
5084
5085 let identity_l1: KpType<Level1, Level1> =
5087 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5088 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
5089 Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
5090 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
5091
5092 let kp_l1_inner: KpType<Level1, Level2> =
5094 Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
5095
5096 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
5098 |l: &Level2| Some(&l.tokio_mutex),
5099 |l: &mut Level2| Some(&mut l.tokio_mutex),
5100 );
5101
5102 let async_l3 = {
5104 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
5105 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
5106 let next: KpType<Level3, Level3> =
5107 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
5108 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5109 };
5110
5111 let kp_l3_leaf: KpType<Level3, i32> =
5113 Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
5114
5115 let step1 = lock_root_to_l1.then(kp_l1_inner);
5117 let step2 = step1.then(kp_l2_tokio);
5118 let step3 = step2.then_async(async_l3);
5119 let deep_chain = step3.then(kp_l3_leaf);
5120
5121 let leaf = deep_chain.get(&root).await;
5123 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5124 assert_eq!(leaf, Some(&100));
5125
5126 let mut root_mut = root.clone();
5128 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5129 assert!(leaf_mut.is_some());
5130 *leaf_mut.unwrap() = 99;
5131
5132 let leaf_after = deep_chain.get(&root_mut).await;
5134 assert_eq!(leaf_after, Some(&99));
5135 }
5136}