1use std::fmt;
14use std::sync::Arc;
15
16pub mod lock;
18pub mod prelude;
19
20pub use lock::{
21 ArcMutexAccess, ArcRwLockAccess, LockAccess, LockKp, LockKpType, RcRefCellAccess,
22 StdMutexAccess, StdRwLockAccess,
23};
24
25#[cfg(feature = "parking_lot")]
26pub use lock::{
27 DirectParkingLotMutexAccess, DirectParkingLotRwLockAccess, ParkingLotMutexAccess,
28 ParkingLotRwLockAccess,
29};
30
31pub mod async_lock;
33
34#[cfg(feature = "pin_project")]
77pub mod pin;
78
79pub trait KeyPathValueTarget {
83 type Target: Sized;
84}
85impl<T> KeyPathValueTarget for &T {
86 type Target = T;
87}
88impl<T> KeyPathValueTarget for &mut T {
89 type Target = T;
90}
91
92#[macro_export]
94macro_rules! keypath {
95 { $root:ident . $field:ident } => { $root::$field() };
96 { $root:ident . $field:ident . $($ty:ident . $f:ident).+ } => {
97 $root::$field() $(.then($ty::$f()))+
98 };
99 ($root:ident . $field:ident) => { $root::$field() };
100 ($root:ident . $field:ident . $($ty:ident . $f:ident).+) => {
101 $root::$field() $(.then($ty::$f()))+
102 };
103}
104
105#[macro_export]
109macro_rules! get_or {
110 ($kp:expr, $root:expr, $default:expr) => {
111 $kp.get($root).unwrap_or($default)
112 };
113 ($root:expr => $($path:tt)*, $default:expr) => {
114 $crate::get_or!($crate::keypath!($($path)*), $root, $default)
115 };
116}
117
118#[macro_export]
123macro_rules! get_or_else {
124 ($kp:expr, $root:expr, $closure:expr) => {
125 $kp.get($root).map(|r| r.clone()).unwrap_or_else($closure)
126 };
127 ($root:expr => ($($path:tt)*), $closure:expr) => {
128 $crate::get_or_else!($crate::keypath!($($path)*), $root, $closure)
129 };
130}
131
132#[macro_export]
153macro_rules! zip_with_kp {
154 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr) => {
155 match ($kp1.get($root), $kp2.get($root)) {
156 (Some(__a), Some(__b)) => Some($closure((__a, __b))),
157 _ => None,
158 }
159 };
160 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr) => {
161 match ($kp1.get($root), $kp2.get($root), $kp3.get($root)) {
162 (Some(__a), Some(__b), Some(__c)) => Some($closure((__a, __b, __c))),
163 _ => None,
164 }
165 };
166 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr) => {
167 match (
168 $kp1.get($root),
169 $kp2.get($root),
170 $kp3.get($root),
171 $kp4.get($root),
172 ) {
173 (Some(__a), Some(__b), Some(__c), Some(__d)) => Some($closure((__a, __b, __c, __d))),
174 _ => None,
175 }
176 };
177 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr) => {
178 match (
179 $kp1.get($root),
180 $kp2.get($root),
181 $kp3.get($root),
182 $kp4.get($root),
183 $kp5.get($root),
184 ) {
185 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e)) => {
186 Some($closure((__a, __b, __c, __d, __e)))
187 }
188 _ => None,
189 }
190 };
191 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr, $kp6:expr) => {
192 match (
193 $kp1.get($root),
194 $kp2.get($root),
195 $kp3.get($root),
196 $kp4.get($root),
197 $kp5.get($root),
198 $kp6.get($root),
199 ) {
200 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e), Some(__f)) => {
201 Some($closure((__a, __b, __c, __d, __e, __f)))
202 }
203 _ => None,
204 }
205 };
206}
207
208pub type KpValue<'a, R, V> = Kp<
210 R,
211 V,
212 &'a R,
213 V, &'a mut R,
215 V, for<'b> fn(&'b R) -> Option<V>,
217 for<'b> fn(&'b mut R) -> Option<V>,
218>;
219
220pub type KpOwned<R, V> = Kp<
222 R,
223 V,
224 R,
225 V, R,
227 V, fn(R) -> Option<V>,
229 fn(R) -> Option<V>,
230>;
231
232pub type KpRoot<R> = Kp<
234 R,
235 R,
236 R,
237 R, R,
239 R, fn(R) -> Option<R>,
241 fn(R) -> Option<R>,
242>;
243
244pub type KpVoid = Kp<(), (), (), (), (), (), fn() -> Option<()>, fn() -> Option<()>>;
246
247pub type KpDynamic<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<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
255 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
256>;
257
258pub type KpBox<'a, R, V> = Kp<
259 R,
260 V,
261 &'a R,
262 &'a V,
263 &'a mut R,
264 &'a mut V,
265 Box<dyn Fn(&'a R) -> Option<&'a V> + 'a>,
266 Box<dyn Fn(&'a mut R) -> Option<&'a mut V> + 'a>,
267>;
268
269pub type KpArc<'a, R, V> = Kp<
270 R,
271 V,
272 &'a R,
273 &'a V,
274 &'a mut R,
275 &'a mut V,
276 Arc<dyn Fn(&'a R) -> Option<&'a V> + Send + Sync + 'a>,
277 Arc<dyn Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync + 'a>,
278>;
279
280pub type KpType<'a, R, V> = Kp<
281 R,
282 V,
283 &'a R,
284 &'a V,
285 &'a mut R,
286 &'a mut V,
287 for<'b> fn(&'b R) -> Option<&'b V>,
288 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
289>;
290
291pub type KpTraitType<'a, R, V> = dyn KpTrait<
292 R,
293 V,
294 &'a R,
295 &'a V,
296 &'a mut R,
297 &'a mut V,
298 for<'b> fn(&'b R) -> Option<&'b V>,
299 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
300 >;
301
302pub type KpOptionRefCellType<'a, R, V> = Kp<
305 R,
306 V,
307 &'a R,
308 std::cell::Ref<'a, V>,
309 &'a mut R,
310 std::cell::RefMut<'a, V>,
311 for<'b> fn(&'b R) -> Option<std::cell::Ref<'b, V>>,
312 for<'b> fn(&'b mut R) -> Option<std::cell::RefMut<'b, V>>,
313>;
314
315impl<'a, R, V> KpType<'a, R, V> {
316 #[inline]
318 pub fn to_dynamic(self) -> KpDynamic<R, V> {
319 self.into()
320 }
321}
322
323impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V> {
324 #[inline]
325 fn from(kp: KpType<'a, R, V>) -> Self {
326 let get_fn = kp.get;
327 let set_fn = kp.set;
328 Kp::new(
329 Box::new(move |t: &R| get_fn(t)),
330 Box::new(move |t: &mut R| set_fn(t)),
331 )
332 }
333}
334
335impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
336where
337 Root: std::borrow::Borrow<R>,
338 Value: std::borrow::Borrow<V>,
339 MutRoot: std::borrow::BorrowMut<R>,
340 MutValue: std::borrow::BorrowMut<V>,
341 G: Fn(Root) -> Option<Value> + Send + Sync + 'static,
342 S: Fn(MutRoot) -> Option<MutValue> + Send + Sync + 'static,
343 R: 'static,
344 V: 'static,
345{
346 #[inline]
360 pub fn into_dynamic(self) -> KpDynamic<R, V> {
361 let g = self.get;
362 let s = self.set;
363 Kp::new(
364 Box::new(move |t: &R| unsafe {
365 debug_assert_eq!(std::mem::size_of::<Root>(), std::mem::size_of::<&R>());
367 let root: Root = std::mem::transmute_copy(&t);
368 match g(root) {
369 None => None,
370 Some(v) => {
371 let r: &V = std::borrow::Borrow::borrow(&v);
372 Some(std::mem::transmute::<&V, &V>(r))
374 }
375 }
376 }),
377 Box::new(move |t: &mut R| unsafe {
378 debug_assert_eq!(std::mem::size_of::<MutRoot>(), std::mem::size_of::<&mut R>());
379 let root: MutRoot = std::mem::transmute_copy(&t);
380 match s(root) {
381 None => None,
382 Some(mut v) => {
383 let r: &mut V = std::borrow::BorrowMut::borrow_mut(&mut v);
384 Some(std::mem::transmute::<&mut V, &mut V>(r))
385 }
386 }
387 }),
388 )
389 }
390}
391
392pub type KpComposed<R, V> = Kp<
428 R,
429 V,
430 &'static R,
431 &'static V,
432 &'static mut R,
433 &'static mut V,
434 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
435 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
436>;
437
438impl<R, V>
439 Kp<
440 R,
441 V,
442 &'static R,
443 &'static V,
444 &'static mut R,
445 &'static mut V,
446 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
447 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
448 >
449{
450 pub fn from_closures<G, S>(get: G, set: S) -> Self
453 where
454 G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
455 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
456 {
457 Self::new(Box::new(get), Box::new(set))
458 }
459}
460
461pub struct AKp {
462 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
463 root_type_id: TypeId,
464 value_type_id: TypeId,
465}
466
467impl AKp {
468 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
470 where
471 R: Any + 'static,
472 V: Any + 'static,
473 {
474 let root_type_id = TypeId::of::<R>();
475 let value_type_id = TypeId::of::<V>();
476 let getter_fn = keypath.get;
477
478 Self {
479 getter: Rc::new(move |any: &dyn Any| {
480 if let Some(root) = any.downcast_ref::<R>() {
481 getter_fn(root).map(|value: &V| value as &dyn Any)
482 } else {
483 None
484 }
485 }),
486 root_type_id,
487 value_type_id,
488 }
489 }
490
491 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
493 where
494 R: Any + 'static,
495 V: Any + 'static,
496 {
497 Self::new(keypath)
498 }
499
500 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
502 (self.getter)(root)
503 }
504
505 pub fn root_type_id(&self) -> TypeId {
507 self.root_type_id
508 }
509
510 pub fn value_type_id(&self) -> TypeId {
512 self.value_type_id
513 }
514
515 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
517 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
518 {
519 Some(
520 self.get(root as &dyn Any)
521 .and_then(|any| any.downcast_ref::<Value>()),
522 )
523 } else {
524 None
525 }
526 }
527
528 pub fn kind_name(&self) -> String {
530 format!("{:?}", self.value_type_id)
531 }
532
533 pub fn root_kind_name(&self) -> String {
535 format!("{:?}", self.root_type_id)
536 }
537
538 pub fn for_arc<Root>(&self) -> AKp
540 where
541 Root: Any + 'static,
542 {
543 let value_type_id = self.value_type_id;
544 let getter = self.getter.clone();
545
546 AKp {
547 getter: Rc::new(move |any: &dyn Any| {
548 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
549 getter(arc.as_ref() as &dyn Any)
550 } else {
551 None
552 }
553 }),
554 root_type_id: TypeId::of::<Arc<Root>>(),
555 value_type_id,
556 }
557 }
558
559 pub fn for_box<Root>(&self) -> AKp
561 where
562 Root: Any + 'static,
563 {
564 let value_type_id = self.value_type_id;
565 let getter = self.getter.clone();
566
567 AKp {
568 getter: Rc::new(move |any: &dyn Any| {
569 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
570 getter(boxed.as_ref() as &dyn Any)
571 } else {
572 None
573 }
574 }),
575 root_type_id: TypeId::of::<Box<Root>>(),
576 value_type_id,
577 }
578 }
579
580 pub fn for_rc<Root>(&self) -> AKp
582 where
583 Root: Any + 'static,
584 {
585 let value_type_id = self.value_type_id;
586 let getter = self.getter.clone();
587
588 AKp {
589 getter: Rc::new(move |any: &dyn Any| {
590 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
591 getter(rc.as_ref() as &dyn Any)
592 } else {
593 None
594 }
595 }),
596 root_type_id: TypeId::of::<Rc<Root>>(),
597 value_type_id,
598 }
599 }
600
601 pub fn for_option<Root>(&self) -> AKp
603 where
604 Root: Any + 'static,
605 {
606 let value_type_id = self.value_type_id;
607 let getter = self.getter.clone();
608
609 AKp {
610 getter: Rc::new(move |any: &dyn Any| {
611 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
612 opt.as_ref().and_then(|root| getter(root as &dyn Any))
613 } else {
614 None
615 }
616 }),
617 root_type_id: TypeId::of::<Option<Root>>(),
618 value_type_id,
619 }
620 }
621
622 pub fn for_result<Root, E>(&self) -> AKp
624 where
625 Root: Any + 'static,
626 E: Any + 'static,
627 {
628 let value_type_id = self.value_type_id;
629 let getter = self.getter.clone();
630
631 AKp {
632 getter: Rc::new(move |any: &dyn Any| {
633 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
634 result
635 .as_ref()
636 .ok()
637 .and_then(|root| getter(root as &dyn Any))
638 } else {
639 None
640 }
641 }),
642 root_type_id: TypeId::of::<Result<Root, E>>(),
643 value_type_id,
644 }
645 }
646
647 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
660 where
661 Root: Any + 'static,
662 OrigValue: Any + 'static,
663 MappedValue: Any + 'static,
664 F: Fn(&OrigValue) -> MappedValue + 'static,
665 {
666 let orig_root_type_id = self.root_type_id;
667 let orig_value_type_id = self.value_type_id;
668 let getter = self.getter.clone();
669 let mapped_type_id = TypeId::of::<MappedValue>();
670
671 AKp {
672 getter: Rc::new(move |any_root: &dyn Any| {
673 if any_root.type_id() == orig_root_type_id {
675 getter(any_root).and_then(|any_value| {
676 if orig_value_type_id == TypeId::of::<OrigValue>() {
678 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
679 let mapped = mapper(orig_val);
680 Box::leak(Box::new(mapped)) as &dyn Any
682 })
683 } else {
684 None
685 }
686 })
687 } else {
688 None
689 }
690 }),
691 root_type_id: orig_root_type_id,
692 value_type_id: mapped_type_id,
693 }
694 }
695
696 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
709 where
710 Root: Any + 'static,
711 Value: Any + 'static,
712 F: Fn(&Value) -> bool + 'static,
713 {
714 let orig_root_type_id = self.root_type_id;
715 let orig_value_type_id = self.value_type_id;
716 let getter = self.getter.clone();
717
718 AKp {
719 getter: Rc::new(move |any_root: &dyn Any| {
720 if any_root.type_id() == orig_root_type_id {
722 getter(any_root).filter(|any_value| {
723 if orig_value_type_id == TypeId::of::<Value>() {
725 any_value
726 .downcast_ref::<Value>()
727 .map(|val| predicate(val))
728 .unwrap_or(false)
729 } else {
730 false
731 }
732 })
733 } else {
734 None
735 }
736 }),
737 root_type_id: orig_root_type_id,
738 value_type_id: orig_value_type_id,
739 }
740 }
741}
742
743impl fmt::Debug for AKp {
744 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
745 f.debug_struct("AKp")
746 .field("root_type_id", &self.root_type_id)
747 .field("value_type_id", &self.value_type_id)
748 .finish_non_exhaustive()
749 }
750}
751
752impl fmt::Display for AKp {
753 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
754 write!(
755 f,
756 "AKp(root_type_id={:?}, value_type_id={:?})",
757 self.root_type_id, self.value_type_id
758 )
759 }
760}
761
762pub struct PKp<Root> {
763 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
764 value_type_id: TypeId,
765 _phantom: std::marker::PhantomData<Root>,
766}
767
768impl<Root> PKp<Root>
769where
770 Root: 'static,
771{
772 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
774 where
775 V: Any + 'static,
776 {
777 let value_type_id = TypeId::of::<V>();
778 let getter_fn = keypath.get;
779
780 Self {
781 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
782 value_type_id,
783 _phantom: std::marker::PhantomData,
784 }
785 }
786
787 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
789 where
790 V: Any + 'static,
791 {
792 Self::new(keypath)
793 }
794
795 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
797 (self.getter)(root)
798 }
799
800 pub fn value_type_id(&self) -> TypeId {
802 self.value_type_id
803 }
804
805 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
807 if self.value_type_id == TypeId::of::<Value>() {
808 self.get(root).and_then(|any| any.downcast_ref::<Value>())
809 } else {
810 None
811 }
812 }
813
814 pub fn kind_name(&self) -> String {
816 format!("{:?}", self.value_type_id)
817 }
818
819 pub fn for_arc(&self) -> PKp<Arc<Root>> {
821 let getter = self.getter.clone();
822 let value_type_id = self.value_type_id;
823
824 PKp {
825 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
826 value_type_id,
827 _phantom: std::marker::PhantomData,
828 }
829 }
830
831 pub fn for_box(&self) -> PKp<Box<Root>> {
833 let getter = self.getter.clone();
834 let value_type_id = self.value_type_id;
835
836 PKp {
837 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
838 value_type_id,
839 _phantom: std::marker::PhantomData,
840 }
841 }
842
843 pub fn for_rc(&self) -> PKp<Rc<Root>> {
845 let getter = self.getter.clone();
846 let value_type_id = self.value_type_id;
847
848 PKp {
849 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
850 value_type_id,
851 _phantom: std::marker::PhantomData,
852 }
853 }
854
855 pub fn for_option(&self) -> PKp<Option<Root>> {
857 let getter = self.getter.clone();
858 let value_type_id = self.value_type_id;
859
860 PKp {
861 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
862 value_type_id,
863 _phantom: std::marker::PhantomData,
864 }
865 }
866
867 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
869 where
870 E: 'static,
871 {
872 let getter = self.getter.clone();
873 let value_type_id = self.value_type_id;
874
875 PKp {
876 getter: Rc::new(move |result: &Result<Root, E>| {
877 result.as_ref().ok().and_then(|root| getter(root))
878 }),
879 value_type_id,
880 _phantom: std::marker::PhantomData,
881 }
882 }
883
884 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
898 where
899 OrigValue: Any + 'static,
900 MappedValue: Any + 'static,
901 F: Fn(&OrigValue) -> MappedValue + 'static,
902 {
903 let orig_type_id = self.value_type_id;
904 let getter = self.getter.clone();
905 let mapped_type_id = TypeId::of::<MappedValue>();
906
907 PKp {
908 getter: Rc::new(move |root: &Root| {
909 getter(root).and_then(|any_value| {
910 if orig_type_id == TypeId::of::<OrigValue>() {
912 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
913 let mapped = mapper(orig_val);
914 Box::leak(Box::new(mapped)) as &dyn Any
917 })
918 } else {
919 None
920 }
921 })
922 }),
923 value_type_id: mapped_type_id,
924 _phantom: std::marker::PhantomData,
925 }
926 }
927
928 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
942 where
943 Value: Any + 'static,
944 F: Fn(&Value) -> bool + 'static,
945 {
946 let orig_type_id = self.value_type_id;
947 let getter = self.getter.clone();
948
949 PKp {
950 getter: Rc::new(move |root: &Root| {
951 getter(root).filter(|any_value| {
952 if orig_type_id == TypeId::of::<Value>() {
954 any_value
955 .downcast_ref::<Value>()
956 .map(|val| predicate(val))
957 .unwrap_or(false)
958 } else {
959 false
960 }
961 })
962 }),
963 value_type_id: orig_type_id,
964 _phantom: std::marker::PhantomData,
965 }
966 }
967}
968
969impl<Root> fmt::Debug for PKp<Root> {
970 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
971 f.debug_struct("PKp")
972 .field("root_ty", &std::any::type_name::<Root>())
973 .field("value_type_id", &self.value_type_id)
974 .finish_non_exhaustive()
975 }
976}
977
978impl<Root> fmt::Display for PKp<Root> {
979 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
980 write!(
981 f,
982 "PKp<{}, value_type_id={:?}>",
983 std::any::type_name::<Root>(),
984 self.value_type_id
985 )
986 }
987}
988
989pub trait KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S> {
992 fn type_id_of_root() -> TypeId
993 where
994 R: 'static,
995 {
996 std::any::TypeId::of::<R>()
997 }
998 fn type_id_of_value() -> TypeId
999 where
1000 V: 'static,
1001 {
1002 std::any::TypeId::of::<V>()
1003 }
1004 fn get(&self, root: Root) -> Option<Value>;
1005 fn get_mut(&self, root: MutRoot) -> Option<MutValue>;
1006 fn then<SV, SubValue, MutSubValue, G2, S2>(
1007 self,
1008 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1009 ) -> Kp<
1010 R,
1011 SV,
1012 Root,
1013 SubValue,
1014 MutRoot,
1015 MutSubValue,
1016 impl Fn(Root) -> Option<SubValue>,
1017 impl Fn(MutRoot) -> Option<MutSubValue>,
1018 >
1019 where
1020 Self: Sized,
1021 Root: std::borrow::Borrow<R>,
1022 Value: std::borrow::Borrow<V>,
1023 MutRoot: std::borrow::BorrowMut<R>,
1024 MutValue: std::borrow::BorrowMut<V>,
1025 SubValue: std::borrow::Borrow<SV>,
1026 MutSubValue: std::borrow::BorrowMut<SV>,
1027 G2: Fn(Value) -> Option<SubValue>,
1028 S2: Fn(MutValue) -> Option<MutSubValue>,;
1029}
1030
1031pub trait ChainExt<R, V, Root, Value, MutRoot, MutValue> {
1032 fn then_lock<
1034 Lock,
1035 Mid,
1036 V2,
1037 LockValue,
1038 MidValue,
1039 Value2,
1040 MutLock,
1041 MutMid,
1042 MutValue2,
1043 G1,
1044 S1,
1045 L,
1046 G2,
1047 S2,
1048 >(
1049 self,
1050 lock_kp: crate::lock::LockKp<
1051 V,
1052 Lock,
1053 Mid,
1054 V2,
1055 Value,
1056 LockValue,
1057 MidValue,
1058 Value2,
1059 MutValue,
1060 MutLock,
1061 MutMid,
1062 MutValue2,
1063 G1,
1064 S1,
1065 L,
1066 G2,
1067 S2,
1068 >,
1069 ) -> crate::lock::KpThenLockKp<
1070 R,
1071 V,
1072 V2,
1073 Root,
1074 Value,
1075 Value2,
1076 MutRoot,
1077 MutValue,
1078 MutValue2,
1079 Self,
1080 crate::lock::LockKp<
1081 V,
1082 Lock,
1083 Mid,
1084 V2,
1085 Value,
1086 LockValue,
1087 MidValue,
1088 Value2,
1089 MutValue,
1090 MutLock,
1091 MutMid,
1092 MutValue2,
1093 G1,
1094 S1,
1095 L,
1096 G2,
1097 S2,
1098 >,
1099 >
1100 where
1101 V: 'static + Clone,
1102 V2: 'static,
1103 Value: std::borrow::Borrow<V>,
1104 Value2: std::borrow::Borrow<V2>,
1105 MutValue: std::borrow::BorrowMut<V>,
1106 MutValue2: std::borrow::BorrowMut<V2>,
1107 LockValue: std::borrow::Borrow<Lock>,
1108 MidValue: std::borrow::Borrow<Mid>,
1109 MutLock: std::borrow::BorrowMut<Lock>,
1110 MutMid: std::borrow::BorrowMut<Mid>,
1111 G1: Fn(Value) -> Option<LockValue>,
1112 S1: Fn(MutValue) -> Option<MutLock>,
1113 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
1114 G2: Fn(MidValue) -> Option<Value2>,
1115 S2: Fn(MutMid) -> Option<MutValue2>,
1116 Self: Sized;
1117
1118 #[cfg(feature = "pin_project")]
1120 fn then_pin_future<Struct, Output, L>(
1121 self,
1122 pin_fut: L,
1123 ) -> crate::pin::KpThenPinFuture<R, Struct, Output, Root, MutRoot, Value, MutValue, Self, L>
1124 where
1125 Struct: Unpin + 'static,
1126 Output: 'static,
1127 Value: std::borrow::Borrow<Struct>,
1128 MutValue: std::borrow::BorrowMut<Struct>,
1129 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
1130 Self: Sized;
1131
1132 fn then_async<AsyncKp>(
1134 self,
1135 async_kp: AsyncKp,
1136 ) -> crate::async_lock::KpThenAsyncKeyPath<
1137 R,
1138 V,
1139 <AsyncKp::Value as KeyPathValueTarget>::Target,
1140 Root,
1141 Value,
1142 AsyncKp::Value,
1143 MutRoot,
1144 MutValue,
1145 AsyncKp::MutValue,
1146 Self,
1147 AsyncKp,
1148 >
1149 where
1150 Value: std::borrow::Borrow<V>,
1151 MutValue: std::borrow::BorrowMut<V>,
1152 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
1153 AsyncKp::Value: KeyPathValueTarget
1154 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1155 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1156 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
1157 Self: Sized;
1158}
1159
1160impl<R, V, Root, Value, MutRoot, MutValue, G, S> ChainExt<R, V, Root, Value, MutRoot, MutValue>
1161 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1162where
1163 Root: std::borrow::Borrow<R>,
1164 Value: std::borrow::Borrow<V>,
1165 MutRoot: std::borrow::BorrowMut<R>,
1166 MutValue: std::borrow::BorrowMut<V>,
1167 G: Fn(Root) -> Option<Value>,
1168 S: Fn(MutRoot) -> Option<MutValue>,
1169{
1170 fn then_lock<
1171 Lock,
1172 Mid,
1173 V2,
1174 LockValue,
1175 MidValue,
1176 Value2,
1177 MutLock,
1178 MutMid,
1179 MutValue2,
1180 G1,
1181 S1,
1182 L,
1183 G2,
1184 S2,
1185 >(
1186 self,
1187 lock_kp: crate::lock::LockKp<
1188 V,
1189 Lock,
1190 Mid,
1191 V2,
1192 Value,
1193 LockValue,
1194 MidValue,
1195 Value2,
1196 MutValue,
1197 MutLock,
1198 MutMid,
1199 MutValue2,
1200 G1,
1201 S1,
1202 L,
1203 G2,
1204 S2,
1205 >,
1206 ) -> crate::lock::KpThenLockKp<
1207 R,
1208 V,
1209 V2,
1210 Root,
1211 Value,
1212 Value2,
1213 MutRoot,
1214 MutValue,
1215 MutValue2,
1216 Self,
1217 crate::lock::LockKp<
1218 V,
1219 Lock,
1220 Mid,
1221 V2,
1222 Value,
1223 LockValue,
1224 MidValue,
1225 Value2,
1226 MutValue,
1227 MutLock,
1228 MutMid,
1229 MutValue2,
1230 G1,
1231 S1,
1232 L,
1233 G2,
1234 S2,
1235 >,
1236 >
1237 where
1238 V: 'static + Clone,
1239 V2: 'static,
1240 Value: std::borrow::Borrow<V>,
1241 Value2: std::borrow::Borrow<V2>,
1242 MutValue: std::borrow::BorrowMut<V>,
1243 MutValue2: std::borrow::BorrowMut<V2>,
1244 LockValue: std::borrow::Borrow<Lock>,
1245 MidValue: std::borrow::Borrow<Mid>,
1246 MutLock: std::borrow::BorrowMut<Lock>,
1247 MutMid: std::borrow::BorrowMut<Mid>,
1248 G1: Fn(Value) -> Option<LockValue>,
1249 S1: Fn(MutValue) -> Option<MutLock>,
1250 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
1251 G2: Fn(MidValue) -> Option<Value2>,
1252 S2: Fn(MutMid) -> Option<MutValue2>,
1253 {
1254 crate::lock::KpThenLockKp {
1255 first: self,
1256 second: lock_kp,
1257 _p: std::marker::PhantomData,
1258 }
1259 }
1260
1261 #[cfg(feature = "pin_project")]
1262 fn then_pin_future<Struct, Output, L>(
1263 self,
1264 pin_fut: L,
1265 ) -> crate::pin::KpThenPinFuture<R, Struct, Output, Root, MutRoot, Value, MutValue, Self, L>
1266 where
1267 Struct: Unpin + 'static,
1268 Output: 'static,
1269 Value: std::borrow::Borrow<Struct>,
1270 MutValue: std::borrow::BorrowMut<Struct>,
1271 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
1272 {
1273 crate::pin::KpThenPinFuture {
1274 first: self,
1275 second: pin_fut,
1276 _p: std::marker::PhantomData,
1277 }
1278 }
1279
1280 fn then_async<AsyncKp>(
1281 self,
1282 async_kp: AsyncKp,
1283 ) -> crate::async_lock::KpThenAsyncKeyPath<
1284 R,
1285 V,
1286 <AsyncKp::Value as KeyPathValueTarget>::Target,
1287 Root,
1288 Value,
1289 AsyncKp::Value,
1290 MutRoot,
1291 MutValue,
1292 AsyncKp::MutValue,
1293 Self,
1294 AsyncKp,
1295 >
1296 where
1297 Value: std::borrow::Borrow<V>,
1298 MutValue: std::borrow::BorrowMut<V>,
1299 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
1300 AsyncKp::Value: KeyPathValueTarget
1301 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1302 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1303 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
1304 {
1305 crate::async_lock::KpThenAsyncKeyPath {
1306 first: self,
1307 second: async_kp,
1308 _p: std::marker::PhantomData,
1309 }
1310 }
1311}
1312
1313pub trait AccessorTrait<R, V, Root, Value, MutRoot, MutValue, G, S> {
1314 fn get_optional(&self, root: Option<Root>) -> Option<Value>;
1316 fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue>;
1322 fn get_or_else<F>(&self, root: Root, f: F) -> Value
1328 where
1329 F: FnOnce() -> Value;
1330 #[inline]
1336 fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
1337 where
1338 F: FnOnce() -> MutValue;
1339 }
1343
1344pub trait CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1345where
1346 Root: std::borrow::Borrow<R>,
1347 Value: std::borrow::Borrow<V>,
1348 MutRoot: std::borrow::BorrowMut<R>,
1349 MutValue: std::borrow::BorrowMut<V>,
1350 G: Fn(Root) -> Option<Value>,
1351 S: Fn(MutRoot) -> Option<MutValue>,
1352{
1353 fn for_arc<'b>(
1354 &self,
1355 ) -> Kp<
1356 std::sync::Arc<R>,
1357 V,
1358 std::sync::Arc<R>,
1359 Value,
1360 std::sync::Arc<R>,
1361 MutValue,
1362 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1363 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1364 >
1365 where
1366 R: 'b,
1367 V: 'b,
1368 Root: for<'a> From<&'a R>,
1369 MutRoot: for<'a> From<&'a mut R>;
1370
1371 fn for_box<'a>(
1372 &self,
1373 ) -> Kp<
1374 Box<R>,
1375 V,
1376 Box<R>,
1377 Value,
1378 Box<R>,
1379 MutValue,
1380 impl Fn(Box<R>) -> Option<Value>,
1381 impl Fn(Box<R>) -> Option<MutValue>,
1382 >
1383 where
1384 R: 'a,
1385 V: 'a,
1386 Root: for<'b> From<&'b R>,
1387 MutRoot: for<'b> From<&'b mut R>;
1388
1389 fn into_set(self) -> impl Fn(MutRoot) -> Option<MutValue>;
1391
1392 fn into_get(self) -> impl Fn(Root) -> Option<Value>;
1394}
1395
1396pub trait HofTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
1397 KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1398where
1399 Root: std::borrow::Borrow<R>,
1400 Value: std::borrow::Borrow<V>,
1401 MutRoot: std::borrow::BorrowMut<R>,
1402 MutValue: std::borrow::BorrowMut<V>,
1403 G: Fn(Root) -> Option<Value>,
1404 S: Fn(MutRoot) -> Option<MutValue>,
1405{
1406 fn map<MappedValue, F>(
1456 &self,
1457 mapper: F,
1458 ) -> Kp<
1459 R,
1460 MappedValue,
1461 Root,
1462 MappedValue,
1463 MutRoot,
1464 MappedValue,
1465 impl Fn(Root) -> Option<MappedValue> + '_,
1466 impl Fn(MutRoot) -> Option<MappedValue> + '_,
1467 >
1468 where
1469 F: Fn(&V) -> MappedValue + Copy + 'static,
1470 MappedValue: 'static,
1471 {
1472 Kp::new(
1473 move |root: Root| {
1474 self.get(root).map(|value| {
1475 let v: &V = value.borrow();
1476 mapper(v)
1477 })
1478 },
1479 move |root: MutRoot| {
1480 self.get_mut(root).map(|value| {
1481 let v: &V = value.borrow();
1482 mapper(v)
1483 })
1484 },
1485 )
1486 }
1487
1488 fn filter<F>(
1490 &self,
1491 predicate: F,
1492 ) -> Kp<
1493 R,
1494 V,
1495 Root,
1496 Value,
1497 MutRoot,
1498 MutValue,
1499 impl Fn(Root) -> Option<Value> + '_,
1500 impl Fn(MutRoot) -> Option<MutValue> + '_,
1501 >
1502 where
1503 F: Fn(&V) -> bool + Copy + 'static,
1504 {
1505 Kp::new(
1506 move |root: Root| {
1507 self.get(root).filter(|value| {
1508 let v: &V = value.borrow();
1509 predicate(v)
1510 })
1511 },
1512 move |root: MutRoot| {
1513 self.get_mut(root).filter(|value| {
1514 let v: &V = value.borrow();
1515 predicate(v)
1516 })
1517 },
1518 )
1519 }
1520
1521 fn filter_map<MappedValue, F>(
1523 &self,
1524 mapper: F,
1525 ) -> Kp<
1526 R,
1527 MappedValue,
1528 Root,
1529 MappedValue,
1530 MutRoot,
1531 MappedValue,
1532 impl Fn(Root) -> Option<MappedValue> + '_,
1533 impl Fn(MutRoot) -> Option<MappedValue> + '_,
1534 >
1535 where
1536 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1537 {
1538 Kp::new(
1539 move |root: Root| {
1540 self.get(root).and_then(|value| {
1541 let v: &V = value.borrow();
1542 mapper(v)
1543 })
1544 },
1545 move |root: MutRoot| {
1546 self.get_mut(root).and_then(|value| {
1547 let v: &V = value.borrow();
1548 mapper(v)
1549 })
1550 },
1551 )
1552 }
1553
1554 fn inspect<F>(
1556 &self,
1557 inspector: F,
1558 ) -> Kp<
1559 R,
1560 V,
1561 Root,
1562 Value,
1563 MutRoot,
1564 MutValue,
1565 impl Fn(Root) -> Option<Value> + '_,
1566 impl Fn(MutRoot) -> Option<MutValue> + '_,
1567 >
1568 where
1569 F: Fn(&V) + Copy + 'static,
1570 {
1571 Kp::new(
1572 move |root: Root| {
1573 self.get(root).map(|value| {
1574 let v: &V = value.borrow();
1575 inspector(v);
1576 value
1577 })
1578 },
1579 move |root: MutRoot| {
1580 self.get_mut(root).map(|value| {
1581 let v: &V = value.borrow();
1582 inspector(v);
1583 value
1584 })
1585 },
1586 )
1587 }
1588
1589 fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item> + '_
1591 where
1592 F: Fn(&V) -> I + 'static,
1593 I: IntoIterator<Item = Item>,
1594 {
1595 move |root: Root| {
1596 self.get(root)
1597 .map(|value| {
1598 let v: &V = value.borrow();
1599 mapper(v).into_iter().collect()
1600 })
1601 .unwrap_or_else(Vec::new)
1602 }
1603 }
1604
1605 fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc + '_
1607 where
1608 F: Fn(Acc, &V) -> Acc + 'static,
1609 Acc: Copy + 'static,
1610 {
1611 move |root: Root| {
1612 self.get(root)
1613 .map(|value| {
1614 let v: &V = value.borrow();
1615 folder(init, v)
1616 })
1617 .unwrap_or(init)
1618 }
1619 }
1620
1621 fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
1623 where
1624 F: Fn(&V) -> bool + 'static,
1625 {
1626 move |root: Root| {
1627 self.get(root)
1628 .map(|value| {
1629 let v: &V = value.borrow();
1630 predicate(v)
1631 })
1632 .unwrap_or(false)
1633 }
1634 }
1635
1636 fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
1638 where
1639 F: Fn(&V) -> bool + 'static,
1640 {
1641 move |root: Root| {
1642 self.get(root)
1643 .map(|value| {
1644 let v: &V = value.borrow();
1645 predicate(v)
1646 })
1647 .unwrap_or(true)
1648 }
1649 }
1650
1651 fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize> + '_
1653 where
1654 F: Fn(&V) -> usize + 'static,
1655 {
1656 move |root: Root| {
1657 self.get(root).map(|value| {
1658 let v: &V = value.borrow();
1659 counter(v)
1660 })
1661 }
1662 }
1663
1664 fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item> + '_
1666 where
1667 F: Fn(&V) -> Option<Item> + 'static,
1668 {
1669 move |root: Root| {
1670 self.get(root).and_then(|value| {
1671 let v: &V = value.borrow();
1672 finder(v)
1673 })
1674 }
1675 }
1676
1677 fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output> + '_
1679 where
1680 F: Fn(&V, usize) -> Output + 'static,
1681 {
1682 move |root: Root| {
1683 self.get(root).map(|value| {
1684 let v: &V = value.borrow();
1685 taker(v, n)
1686 })
1687 }
1688 }
1689
1690 fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output> + '_
1692 where
1693 F: Fn(&V, usize) -> Output + 'static,
1694 {
1695 move |root: Root| {
1696 self.get(root).map(|value| {
1697 let v: &V = value.borrow();
1698 skipper(v, n)
1699 })
1700 }
1701 }
1702
1703 fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output> + '_
1705 where
1706 F: Fn(&V) -> Output + 'static,
1707 {
1708 move |root: Root| {
1709 self.get(root).map(|value| {
1710 let v: &V = value.borrow();
1711 partitioner(v)
1712 })
1713 }
1714 }
1715
1716 fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item> + '_
1718 where
1719 F: Fn(&V) -> Option<Item> + 'static,
1720 {
1721 move |root: Root| {
1722 self.get(root).and_then(|value| {
1723 let v: &V = value.borrow();
1724 min_fn(v)
1725 })
1726 }
1727 }
1728
1729 fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item> + '_
1731 where
1732 F: Fn(&V) -> Option<Item> + 'static,
1733 {
1734 move |root: Root| {
1735 self.get(root).and_then(|value| {
1736 let v: &V = value.borrow();
1737 max_fn(v)
1738 })
1739 }
1740 }
1741
1742 fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum> + '_
1744 where
1745 F: Fn(&V) -> Sum + 'static,
1746 {
1747 move |root: Root| {
1748 self.get(root).map(|value| {
1749 let v: &V = value.borrow();
1750 sum_fn(v)
1751 })
1752 }
1753 }
1754
1755 }
1806
1807impl<R, V, Root, Value, MutRoot, MutValue, G, S> KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1808 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1809where
1810 Root: std::borrow::Borrow<R>,
1811 Value: std::borrow::Borrow<V>,
1812 MutRoot: std::borrow::BorrowMut<R>,
1813 MutValue: std::borrow::BorrowMut<V>,
1814 G: Fn(Root) -> Option<Value>,
1815 S: Fn(MutRoot) -> Option<MutValue>,
1816{
1817 fn then<SV, SubValue, MutSubValue, G2, S2>(
1818 self,
1819 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1820 ) -> Kp<
1821 R,
1822 SV,
1823 Root,
1824 SubValue,
1825 MutRoot,
1826 MutSubValue,
1827 impl Fn(Root) -> Option<SubValue>,
1828 impl Fn(MutRoot) -> Option<MutSubValue>,
1829 >
1830 where
1831 SubValue: std::borrow::Borrow<SV>,
1832 MutSubValue: std::borrow::BorrowMut<SV>,
1833 G2: Fn(Value) -> Option<SubValue>,
1834 S2: Fn(MutValue) -> Option<MutSubValue>,
1835 {
1836 Kp::new(
1837 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
1838 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
1839 )
1840 }
1841
1842 fn get(&self, root: Root) -> Option<Value> {
1843 (self.get)(root)
1844 }
1845
1846 fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1847 (self.set)(root)
1848 }
1849}
1850
1851impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1852 CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1853 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1854where
1855 Root: std::borrow::Borrow<R>,
1856 Value: std::borrow::Borrow<V>,
1857 MutRoot: std::borrow::BorrowMut<R>,
1858 MutValue: std::borrow::BorrowMut<V>,
1859 G: Fn(Root) -> Option<Value>,
1860 S: Fn(MutRoot) -> Option<MutValue>,
1861{
1862 fn for_arc<'b>(
1863 &self,
1864 ) -> Kp<
1865 std::sync::Arc<R>,
1866 V,
1867 std::sync::Arc<R>,
1868 Value,
1869 std::sync::Arc<R>,
1870 MutValue,
1871 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1872 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1873 >
1874 where
1875 R: 'b,
1876 V: 'b,
1877 Root: for<'a> From<&'a R>,
1878 MutRoot: for<'a> From<&'a mut R>,
1879 {
1880 Kp::new(
1881 move |arc_root: std::sync::Arc<R>| {
1882 let r_ref: &R = &*arc_root;
1883 (self.get)(Root::from(r_ref))
1884 },
1885 move |mut arc_root: std::sync::Arc<R>| {
1886 std::sync::Arc::get_mut(&mut arc_root)
1888 .and_then(|r_mut| (self.set)(MutRoot::from(r_mut)))
1889 },
1890 )
1891 }
1892
1893 fn for_box<'a>(
1894 &self,
1895 ) -> Kp<
1896 Box<R>,
1897 V,
1898 Box<R>,
1899 Value,
1900 Box<R>,
1901 MutValue,
1902 impl Fn(Box<R>) -> Option<Value>,
1903 impl Fn(Box<R>) -> Option<MutValue>,
1904 >
1905 where
1906 R: 'a,
1907 V: 'a,
1908 Root: for<'b> From<&'b R>,
1909 MutRoot: for<'b> From<&'b mut R>,
1910 {
1911 Kp::new(
1912 move |r: Box<R>| {
1913 let r_ref: &R = r.as_ref();
1914 (self.get)(Root::from(r_ref))
1915 },
1916 move |mut r: Box<R>| {
1917 (self.set)(MutRoot::from(r.as_mut()))
1919 },
1920 )
1921 }
1922
1923 #[inline]
1925 fn into_set(self) -> impl Fn(MutRoot) -> Option<MutValue> {
1926 self.set
1927 }
1928
1929 #[inline]
1931 fn into_get(self) -> impl Fn(Root) -> Option<Value> {
1932 self.get
1933 }
1934}
1935
1936impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1937 HofTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1938 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1939where
1940 Root: std::borrow::Borrow<R>,
1941 Value: std::borrow::Borrow<V>,
1942 MutRoot: std::borrow::BorrowMut<R>,
1943 MutValue: std::borrow::BorrowMut<V>,
1944 G: Fn(Root) -> Option<Value>,
1945 S: Fn(MutRoot) -> Option<MutValue>,
1946{
1947}
1948
1949impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1950 AccessorTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1951 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1952where
1953 Root: std::borrow::Borrow<R>,
1954 Value: std::borrow::Borrow<V>,
1955 MutRoot: std::borrow::BorrowMut<R>,
1956 MutValue: std::borrow::BorrowMut<V>,
1957 G: Fn(Root) -> Option<Value>,
1958 S: Fn(MutRoot) -> Option<MutValue>,
1959{
1960 #[inline]
1962 fn get_optional(&self, root: Option<Root>) -> Option<Value> {
1963 root.and_then(|r| (self.get)(r))
1964 }
1965
1966 #[inline]
1968 fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue> {
1969 root.and_then(|r| (self.set)(r))
1970 }
1971
1972 #[inline]
1974 fn get_or_else<F>(&self, root: Root, f: F) -> Value
1975 where
1976 F: FnOnce() -> Value,
1977 {
1978 (self.get)(root).unwrap_or_else(f)
1979 }
1980
1981 #[inline]
1983 fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
1984 where
1985 F: FnOnce() -> MutValue,
1986 {
1987 (self.set)(root).unwrap_or_else(f)
1988 }
1989}
1990
1991#[derive(Clone)]
2003pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2004where
2005 Root: std::borrow::Borrow<R>,
2006 MutRoot: std::borrow::BorrowMut<R>,
2007 MutValue: std::borrow::BorrowMut<V>,
2008 G: Fn(Root) -> Option<Value>,
2009 S: Fn(MutRoot) -> Option<MutValue>,
2010{
2011 pub get: G,
2013 pub set: S,
2015 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
2016}
2017
2018unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Send
2020 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2021where
2022 Root: std::borrow::Borrow<R>,
2023 MutRoot: std::borrow::BorrowMut<R>,
2024 MutValue: std::borrow::BorrowMut<V>,
2025 G: Fn(Root) -> Option<Value> + Send,
2026 S: Fn(MutRoot) -> Option<MutValue> + Send,
2027{
2028}
2029unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Sync
2030 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2031where
2032 Root: std::borrow::Borrow<R>,
2033 MutRoot: std::borrow::BorrowMut<R>,
2034 MutValue: std::borrow::BorrowMut<V>,
2035 G: Fn(Root) -> Option<Value> + Sync,
2036 S: Fn(MutRoot) -> Option<MutValue> + Sync,
2037{
2038}
2039
2040impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2041where
2042 Root: std::borrow::Borrow<R>,
2043 Value: std::borrow::Borrow<V>,
2044 MutRoot: std::borrow::BorrowMut<R>,
2045 MutValue: std::borrow::BorrowMut<V>,
2046 G: Fn(Root) -> Option<Value>,
2047 S: Fn(MutRoot) -> Option<MutValue>,
2048{
2049 pub fn new(get: G, set: S) -> Self {
2050 Self {
2051 get: get,
2052 set: set,
2053 _p: std::marker::PhantomData,
2054 }
2055 }
2056
2057 #[inline]
2068 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
2069 self,
2070 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
2071 ) -> Kp<
2072 R,
2073 SV,
2074 Root,
2075 SubValue,
2076 MutRoot,
2077 MutSubValue,
2078 impl Fn(Root) -> Option<SubValue>,
2079 impl Fn(MutRoot) -> Option<MutSubValue>,
2080 >
2081 where
2082 SubValue: std::borrow::Borrow<SV>,
2083 MutSubValue: std::borrow::BorrowMut<SV>,
2084 G2: Fn(Value) -> Option<SubValue>,
2085 S2: Fn(MutValue) -> Option<MutSubValue>,
2086 {
2087
2088 Kp::new(
2089 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
2090 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
2091 )
2092 }
2093}
2094
2095impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Debug
2096 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2097where
2098 Root: std::borrow::Borrow<R>,
2099 Value: std::borrow::Borrow<V>,
2100 MutRoot: std::borrow::BorrowMut<R>,
2101 MutValue: std::borrow::BorrowMut<V>,
2102 G: Fn(Root) -> Option<Value>,
2103 S: Fn(MutRoot) -> Option<MutValue>,
2104{
2105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2106 f.debug_struct("Kp")
2107 .field("root_ty", &std::any::type_name::<R>())
2108 .field("value_ty", &std::any::type_name::<V>())
2109 .finish_non_exhaustive()
2110 }
2111}
2112
2113impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Display
2114 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2115where
2116 Root: std::borrow::Borrow<R>,
2117 Value: std::borrow::Borrow<V>,
2118 MutRoot: std::borrow::BorrowMut<R>,
2119 MutValue: std::borrow::BorrowMut<V>,
2120 G: Fn(Root) -> Option<Value>,
2121 S: Fn(MutRoot) -> Option<MutValue>,
2122{
2123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2124 write!(
2125 f,
2126 "Kp<{}, {}>",
2127 std::any::type_name::<R>(),
2128 std::any::type_name::<V>()
2129 )
2130 }
2131}
2132
2133pub fn zip_kps<'a, RootType, Value1, Value2>(
2147 kp1: &'a KpType<'a, RootType, Value1>,
2148 kp2: &'a KpType<'a, RootType, Value2>,
2149) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
2150where
2151 RootType: 'a,
2152 Value1: 'a,
2153 Value2: 'a,
2154{
2155 move |root: &'a RootType| {
2156 let val1 = (kp1.get)(root)?;
2157 let val2 = (kp2.get)(root)?;
2158 Some((val1, val2))
2159 }
2160}
2161
2162impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
2163where
2164 Root: std::borrow::Borrow<R>,
2165 MutRoot: std::borrow::BorrowMut<R>,
2166 G: Fn(Root) -> Option<Root>,
2167 S: Fn(MutRoot) -> Option<MutRoot>,
2168{
2169 pub fn identity_typed() -> Kp<
2170 R,
2171 R,
2172 Root,
2173 Root,
2174 MutRoot,
2175 MutRoot,
2176 fn(Root) -> Option<Root>,
2177 fn(MutRoot) -> Option<MutRoot>,
2178 > {
2179 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
2180 }
2181
2182 pub fn identity<'a>() -> KpType<'a, R, R> {
2183 KpType::new(|r| Some(r), |r| Some(r))
2184 }
2185}
2186
2187pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2196where
2197 Root: std::borrow::Borrow<Enum>,
2198 Value: std::borrow::Borrow<Variant>,
2199 MutRoot: std::borrow::BorrowMut<Enum>,
2200 MutValue: std::borrow::BorrowMut<Variant>,
2201 G: Fn(Root) -> Option<Value>,
2202 S: Fn(MutRoot) -> Option<MutValue>,
2203 E: Fn(Variant) -> Enum,
2204{
2205 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
2206 embedder: E,
2207}
2208
2209unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
2211 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2212where
2213 Root: std::borrow::Borrow<Enum>,
2214 Value: std::borrow::Borrow<Variant>,
2215 MutRoot: std::borrow::BorrowMut<Enum>,
2216 MutValue: std::borrow::BorrowMut<Variant>,
2217 G: Fn(Root) -> Option<Value> + Send,
2218 S: Fn(MutRoot) -> Option<MutValue> + Send,
2219 E: Fn(Variant) -> Enum + Send,
2220{
2221}
2222unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
2223 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2224where
2225 Root: std::borrow::Borrow<Enum>,
2226 Value: std::borrow::Borrow<Variant>,
2227 MutRoot: std::borrow::BorrowMut<Enum>,
2228 MutValue: std::borrow::BorrowMut<Variant>,
2229 G: Fn(Root) -> Option<Value> + Sync,
2230 S: Fn(MutRoot) -> Option<MutValue> + Sync,
2231 E: Fn(Variant) -> Enum + Sync,
2232{
2233}
2234
2235impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2236 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2237where
2238 Root: std::borrow::Borrow<Enum>,
2239 Value: std::borrow::Borrow<Variant>,
2240 MutRoot: std::borrow::BorrowMut<Enum>,
2241 MutValue: std::borrow::BorrowMut<Variant>,
2242 G: Fn(Root) -> Option<Value>,
2243 S: Fn(MutRoot) -> Option<MutValue>,
2244 E: Fn(Variant) -> Enum,
2245{
2246 pub fn new(
2248 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
2249 embedder: E,
2250 ) -> Self {
2251 Self {
2252 extractor,
2253 embedder,
2254 }
2255 }
2256
2257 pub fn get(&self, enum_value: Root) -> Option<Value> {
2259 (self.extractor.get)(enum_value)
2260 }
2261
2262 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
2264 (self.extractor.set)(enum_value)
2265 }
2266
2267 pub fn embed(&self, value: Variant) -> Enum {
2269 (self.embedder)(value)
2270 }
2271
2272 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2274 &self.extractor
2275 }
2276
2277 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2279 self.extractor
2280 }
2281
2282 pub fn map<MappedValue, F>(
2293 &self,
2294 mapper: F,
2295 ) -> EnumKp<
2296 Enum,
2297 MappedValue,
2298 Root,
2299 MappedValue,
2300 MutRoot,
2301 MappedValue,
2302 impl Fn(Root) -> Option<MappedValue>,
2303 impl Fn(MutRoot) -> Option<MappedValue>,
2304 impl Fn(MappedValue) -> Enum,
2305 >
2306 where
2307 F: Fn(&Variant) -> MappedValue + Copy + 'static,
2310 Variant: 'static,
2311 MappedValue: 'static,
2312 E: Fn(Variant) -> Enum + Copy + 'static,
2314 {
2315 let mapped_extractor = self.extractor.map(mapper);
2316
2317 let new_embedder = move |_value: MappedValue| -> Enum {
2321 panic!(
2322 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
2323 )
2324 };
2325
2326 EnumKp::new(mapped_extractor, new_embedder)
2327 }
2328
2329 pub fn filter<F>(
2341 &self,
2342 predicate: F,
2343 ) -> EnumKp<
2344 Enum,
2345 Variant,
2346 Root,
2347 Value,
2348 MutRoot,
2349 MutValue,
2350 impl Fn(Root) -> Option<Value>,
2351 impl Fn(MutRoot) -> Option<MutValue>,
2352 E,
2353 >
2354 where
2355 F: Fn(&Variant) -> bool + Copy + 'static,
2358 Variant: 'static,
2359 E: Copy,
2361 {
2362 let filtered_extractor = self.extractor.filter(predicate);
2363 EnumKp::new(filtered_extractor, self.embedder)
2364 }
2365}
2366
2367impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Debug
2368 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2369where
2370 Root: std::borrow::Borrow<Enum>,
2371 Value: std::borrow::Borrow<Variant>,
2372 MutRoot: std::borrow::BorrowMut<Enum>,
2373 MutValue: std::borrow::BorrowMut<Variant>,
2374 G: Fn(Root) -> Option<Value>,
2375 S: Fn(MutRoot) -> Option<MutValue>,
2376 E: Fn(Variant) -> Enum,
2377{
2378 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2379 f.debug_struct("EnumKp")
2380 .field("enum_ty", &std::any::type_name::<Enum>())
2381 .field("variant_ty", &std::any::type_name::<Variant>())
2382 .finish_non_exhaustive()
2383 }
2384}
2385
2386impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Display
2387 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2388where
2389 Root: std::borrow::Borrow<Enum>,
2390 Value: std::borrow::Borrow<Variant>,
2391 MutRoot: std::borrow::BorrowMut<Enum>,
2392 MutValue: std::borrow::BorrowMut<Variant>,
2393 G: Fn(Root) -> Option<Value>,
2394 S: Fn(MutRoot) -> Option<MutValue>,
2395 E: Fn(Variant) -> Enum,
2396{
2397 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2398 write!(
2399 f,
2400 "EnumKp<{}, {}>",
2401 std::any::type_name::<Enum>(),
2402 std::any::type_name::<Variant>()
2403 )
2404 }
2405}
2406
2407pub type EnumKpType<'a, Enum, Variant> = EnumKp<
2409 Enum,
2410 Variant,
2411 &'a Enum,
2412 &'a Variant,
2413 &'a mut Enum,
2414 &'a mut Variant,
2415 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2416 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2417 fn(Variant) -> Enum,
2418>;
2419
2420pub fn enum_variant<'a, Enum, Variant>(
2438 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2439 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2440 embedder: fn(Variant) -> Enum,
2441) -> EnumKpType<'a, Enum, Variant> {
2442 EnumKp::new(Kp::new(getter, setter), embedder)
2443}
2444
2445pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
2455 EnumKp::new(
2456 Kp::new(
2457 |r: &Result<T, E>| r.as_ref().ok(),
2458 |r: &mut Result<T, E>| r.as_mut().ok(),
2459 ),
2460 |t: T| Ok(t),
2461 )
2462}
2463
2464pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
2474 EnumKp::new(
2475 Kp::new(
2476 |r: &Result<T, E>| r.as_ref().err(),
2477 |r: &mut Result<T, E>| r.as_mut().err(),
2478 ),
2479 |e: E| Err(e),
2480 )
2481}
2482
2483pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
2493 EnumKp::new(
2494 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
2495 |t: T| Some(t),
2496 )
2497}
2498
2499pub fn variant_of<'a, Enum, Variant>(
2517 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2518 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2519 embedder: fn(Variant) -> Enum,
2520) -> EnumKpType<'a, Enum, Variant> {
2521 enum_variant(getter, setter, embedder)
2522}
2523
2524pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
2537 Kp::new(
2538 |b: &Box<T>| Some(b.as_ref()),
2539 |b: &mut Box<T>| Some(b.as_mut()),
2540 )
2541}
2542
2543pub fn kp_arc<'a, T>() -> Kp<
2554 Arc<T>,
2555 T,
2556 &'a Arc<T>,
2557 &'a T,
2558 &'a mut Arc<T>,
2559 &'a mut T,
2560 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
2561 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
2562> {
2563 Kp::new(
2564 |arc: &Arc<T>| Some(arc.as_ref()),
2565 |arc: &mut Arc<T>| Arc::get_mut(arc),
2566 )
2567}
2568
2569pub fn kp_rc<'a, T>() -> Kp<
2580 std::rc::Rc<T>,
2581 T,
2582 &'a std::rc::Rc<T>,
2583 &'a T,
2584 &'a mut std::rc::Rc<T>,
2585 &'a mut T,
2586 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
2587 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
2588> {
2589 Kp::new(
2590 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
2591 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
2592 )
2593}
2594
2595use std::any::{Any, TypeId};
2598use std::rc::Rc;
2599
2600#[cfg(test)]
2615mod tests {
2616 use super::*;
2617 use std::collections::HashMap;
2618
2619 fn kp_adaptable<T, Root, Value, MutRoot, MutValue, G, S>(kp: T)
2620 where
2621 T: KpTrait<TestKP, String, Root, Value, MutRoot, MutValue, G, S>,
2622 {
2623 }
2626 fn test_kp_trait() {}
2627
2628 #[derive(Debug)]
2629 struct TestKP {
2630 a: String,
2631 b: String,
2632 c: std::sync::Arc<String>,
2633 d: std::sync::Mutex<String>,
2634 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
2635 f: Option<TestKP2>,
2636 g: HashMap<i32, TestKP2>,
2637 }
2638
2639 impl TestKP {
2640 fn new() -> Self {
2641 Self {
2642 a: String::from("a"),
2643 b: String::from("b"),
2644 c: std::sync::Arc::new(String::from("c")),
2645 d: std::sync::Mutex::new(String::from("d")),
2646 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2647 f: Some(TestKP2 {
2648 a: String::from("a3"),
2649 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2650 }),
2651 g: HashMap::new(),
2652 }
2653 }
2654
2655 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2656 KpComposed::from_closures(
2657 move |r: &TestKP| r.g.get(&index),
2658 move |r: &mut TestKP| r.g.get_mut(&index),
2659 )
2660 }
2661
2662 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2665 TestKP2,
2666 String,
2667 Root,
2668 Value,
2669 MutRoot,
2670 MutValue,
2671 impl Fn(Root) -> Option<Value>,
2672 impl Fn(MutRoot) -> Option<MutValue>,
2673 >
2674 where
2675 Root: std::borrow::Borrow<TestKP2>,
2676 MutRoot: std::borrow::BorrowMut<TestKP2>,
2677 Value: std::borrow::Borrow<String> + From<String>,
2678 MutValue: std::borrow::BorrowMut<String> + From<String>,
2679 {
2680 Kp::new(
2681 |r: Root| Some(Value::from(r.borrow().a.clone())),
2682 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2683 )
2684 }
2685
2686 fn c<'a>() -> KpType<'a, TestKP, String> {
2689 KpType::new(
2690 |r: &TestKP| Some(r.c.as_ref()),
2691 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2692 Some(arc_str) => Some(arc_str),
2693 None => None,
2694 },
2695 )
2696 }
2697
2698 fn a<'a>() -> KpType<'a, TestKP, String> {
2699 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2700 }
2701
2702 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2703 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2704 }
2705
2706 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2707 KpType::identity()
2708 }
2709 }
2710
2711 #[test]
2712 fn kp_debug_display_uses_type_names() {
2713 let kp = TestKP::a();
2714 let dbg = format!("{kp:?}");
2715 assert!(dbg.starts_with("Kp {"), "{dbg}");
2716 assert!(dbg.contains("root_ty") && dbg.contains("value_ty"), "{dbg}");
2717 let disp = format!("{kp}");
2718 assert!(disp.contains("TestKP"), "{disp}");
2719 assert!(disp.contains("String"), "{disp}");
2720 }
2721
2722 #[test]
2723 fn akp_and_pkp_debug_display() {
2724 let akp = AKp::new(TestKP::a());
2725 assert!(format!("{akp:?}").starts_with("AKp"));
2726 let pkp = PKp::new(TestKP::a());
2727 let pkp_dbg = format!("{pkp:?}");
2728 assert!(pkp_dbg.starts_with("PKp"), "{pkp_dbg}");
2729 assert!(format!("{pkp}").contains("TestKP"));
2730 }
2731
2732 #[test]
2733 fn enum_kp_debug_display() {
2734 let ok_kp = enum_ok::<i32, String>();
2735 assert!(format!("{ok_kp:?}").contains("EnumKp"));
2736 let s = format!("{ok_kp}");
2737 assert!(s.contains("Result") && s.contains("i32"), "{s}");
2738 }
2739
2740 #[test]
2741 fn composed_kp_into_dynamic_stores_as_kp_dynamic() {
2742 let path: KpDynamic<TestKP, String> = TestKP::f().then(TestKP2::a()).into_dynamic();
2743 let mut t = TestKP::new();
2744 assert_eq!(path.get(&t), Some(&"a3".to_string()));
2745 path.get_mut(&mut t).map(|s| *s = "x".into());
2746 assert_eq!(t.f.as_ref().unwrap().a, "x");
2747 }
2748
2749 #[derive(Debug)]
2750 struct TestKP2 {
2751 a: String,
2752 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2753 }
2754
2755 impl TestKP2 {
2756 fn new() -> Self {
2757 TestKP2 {
2758 a: String::from("a2"),
2759 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2760 }
2761 }
2762
2763 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2764 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2771 fn(MutRoot) -> Option<MutRoot>,
2772 >
2773 where
2774 Root: std::borrow::Borrow<TestKP2>,
2775 MutRoot: std::borrow::BorrowMut<TestKP2>,
2776 G: Fn(Root) -> Option<Root>,
2777 S: Fn(MutRoot) -> Option<MutRoot>,
2778 {
2779 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2780 }
2781
2782 fn a<'a>() -> KpType<'a, TestKP2, String> {
2783 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2784 }
2785
2786 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2787 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2788 }
2789
2790 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2795 KpType::identity()
2796 }
2797 }
2798
2799 #[derive(Debug)]
2800 struct TestKP3 {
2801 a: String,
2802 b: std::sync::Arc<std::sync::Mutex<String>>,
2803 }
2804
2805 impl TestKP3 {
2806 fn new() -> Self {
2807 TestKP3 {
2808 a: String::from("a2"),
2809 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2810 }
2811 }
2812
2813 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2814 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2821 fn(MutRoot) -> Option<MutRoot>,
2822 >
2823 where
2824 Root: std::borrow::Borrow<TestKP3>,
2825 MutRoot: std::borrow::BorrowMut<TestKP3>,
2826 G: Fn(Root) -> Option<Root>,
2827 S: Fn(MutRoot) -> Option<MutRoot>,
2828 {
2829 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2830 }
2831
2832 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2833 KpType::identity()
2834 }
2835 }
2836
2837 impl TestKP3 {}
2838
2839 impl TestKP {}
2840 #[test]
2841 fn test_a() {
2842 let instance2 = TestKP2::new();
2843 let mut instance = TestKP::new();
2844 let kp = TestKP::identity();
2845 let kp_a = TestKP::a();
2846 let wres = TestKP::f()
2848 .then(TestKP2::a())
2849 .get_mut(&mut instance)
2850 .unwrap();
2851 *wres = String::from("a3 changed successfully");
2852 let res = (TestKP::f().then(TestKP2::a()).get)(&instance);
2853 println!("{:?}", res);
2854 let res = (TestKP::f().then(TestKP2::identity()).get)(&instance);
2855 println!("{:?}", res);
2856 let res = (kp.get)(&instance);
2857 println!("{:?}", res);
2858
2859 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2860 println!("{:?}", (new_kp_from_hashmap.get)(&instance));
2861 }
2862
2863 #[test]
2942 fn test_enum_kp_result_ok() {
2943 let ok_result: Result<String, i32> = Ok("success".to_string());
2944 let mut err_result: Result<String, i32> = Err(42);
2945
2946 let ok_kp = enum_ok();
2947
2948 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2950 assert_eq!(ok_kp.get(&err_result), None);
2951
2952 let embedded = ok_kp.embed("embedded".to_string());
2954 assert_eq!(embedded, Ok("embedded".to_string()));
2955
2956 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2958 *val = "modified".to_string();
2959 }
2960 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2963 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2964 *val = "modified".to_string();
2965 }
2966 assert_eq!(ok_result2, Ok("modified".to_string()));
2967 }
2968
2969 #[test]
2970 fn test_enum_kp_result_err() {
2971 let ok_result: Result<String, i32> = Ok("success".to_string());
2972 let mut err_result: Result<String, i32> = Err(42);
2973
2974 let err_kp = enum_err();
2975
2976 assert_eq!(err_kp.get(&err_result), Some(&42));
2978 assert_eq!(err_kp.get(&ok_result), None);
2979
2980 let embedded = err_kp.embed(99);
2982 assert_eq!(embedded, Err(99));
2983
2984 if let Some(val) = err_kp.get_mut(&mut err_result) {
2986 *val = 100;
2987 }
2988 assert_eq!(err_result, Err(100));
2989 }
2990
2991 #[test]
2992 fn test_enum_kp_option_some() {
2993 let some_opt = Some("value".to_string());
2994 let mut none_opt: Option<String> = None;
2995
2996 let some_kp = enum_some();
2997
2998 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
3000 assert_eq!(some_kp.get(&none_opt), None);
3001
3002 let embedded = some_kp.embed("embedded".to_string());
3004 assert_eq!(embedded, Some("embedded".to_string()));
3005
3006 let mut some_opt2 = Some("original".to_string());
3008 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
3009 *val = "modified".to_string();
3010 }
3011 assert_eq!(some_opt2, Some("modified".to_string()));
3012 }
3013
3014 #[test]
3015 fn test_enum_kp_custom_enum() {
3016 #[derive(Debug, PartialEq)]
3017 enum MyEnum {
3018 A(String),
3019 B(i32),
3020 C,
3021 }
3022
3023 let mut enum_a = MyEnum::A("hello".to_string());
3024 let enum_b = MyEnum::B(42);
3025 let enum_c = MyEnum::C;
3026
3027 let kp_a = enum_variant(
3029 |e: &MyEnum| match e {
3030 MyEnum::A(s) => Some(s),
3031 _ => None,
3032 },
3033 |e: &mut MyEnum| match e {
3034 MyEnum::A(s) => Some(s),
3035 _ => None,
3036 },
3037 |s: String| MyEnum::A(s),
3038 );
3039
3040 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
3042 assert_eq!(kp_a.get(&enum_b), None);
3043 assert_eq!(kp_a.get(&enum_c), None);
3044
3045 let embedded = kp_a.embed("world".to_string());
3047 assert_eq!(embedded, MyEnum::A("world".to_string()));
3048
3049 if let Some(val) = kp_a.get_mut(&mut enum_a) {
3051 *val = "modified".to_string();
3052 }
3053 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
3054 }
3055
3056 #[test]
3057 fn test_container_kp_box() {
3058 let boxed = Box::new("value".to_string());
3059 let mut boxed_mut = Box::new("original".to_string());
3060
3061 let box_kp = kp_box();
3062
3063 assert_eq!((box_kp.get)(&boxed), Some(&"value".to_string()));
3065
3066 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
3068 *val = "modified".to_string();
3069 }
3070 assert_eq!(*boxed_mut, "modified".to_string());
3071 }
3072
3073 #[test]
3074 fn test_container_kp_arc() {
3075 let arc = Arc::new("value".to_string());
3076 let mut arc_mut = Arc::new("original".to_string());
3077
3078 let arc_kp = kp_arc();
3079
3080 assert_eq!((arc_kp.get)(&arc), Some(&"value".to_string()));
3082
3083 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
3085 *val = "modified".to_string();
3086 }
3087 assert_eq!(*arc_mut, "modified".to_string());
3088
3089 let arc_shared = Arc::new("shared".to_string());
3091 let arc_shared2 = Arc::clone(&arc_shared);
3092 let mut arc_shared_mut = arc_shared;
3093 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
3094 }
3095
3096 #[test]
3097 fn test_enum_kp_composition() {
3098 #[derive(Debug, PartialEq)]
3100 struct Inner {
3101 value: String,
3102 }
3103
3104 let result: Result<Inner, i32> = Ok(Inner {
3105 value: "nested".to_string(),
3106 });
3107
3108 let inner_kp = KpType::new(
3110 |i: &Inner| Some(&i.value),
3111 |i: &mut Inner| Some(&mut i.value),
3112 );
3113
3114 let ok_kp = enum_ok::<Inner, i32>();
3116 let ok_kp_base = ok_kp.into_kp();
3117 let composed = ok_kp_base.then(inner_kp);
3118
3119 assert_eq!((composed.get)(&result), Some(&"nested".to_string()));
3120 }
3121
3122 #[test]
3123 fn test_pkp_basic() {
3124 #[derive(Debug)]
3125 struct User {
3126 name: String,
3127 age: i32,
3128 }
3129
3130 let user = User {
3131 name: "Akash".to_string(),
3132 age: 30,
3133 };
3134
3135 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3137 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3138
3139 let name_pkp = PKp::new(name_kp);
3141 let age_pkp = PKp::new(age_kp);
3142
3143 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Akash".to_string()));
3145 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
3146
3147 assert_eq!(name_pkp.get_as::<i32>(&user), None);
3149 assert_eq!(age_pkp.get_as::<String>(&user), None);
3150
3151 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
3153 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
3154 }
3155
3156 #[test]
3157 fn test_pkp_collection() {
3158 #[derive(Debug)]
3159 struct User {
3160 name: String,
3161 age: i32,
3162 }
3163
3164 let user = User {
3165 name: "Bob".to_string(),
3166 age: 25,
3167 };
3168
3169 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3171 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3172
3173 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
3174
3175 let name_value = keypaths[0].get_as::<String>(&user);
3177 let age_value = keypaths[1].get_as::<i32>(&user);
3178
3179 assert_eq!(name_value, Some(&"Bob".to_string()));
3180 assert_eq!(age_value, Some(&25));
3181 }
3182
3183 #[test]
3184 fn test_pkp_for_arc() {
3185 #[derive(Debug)]
3186 struct User {
3187 name: String,
3188 }
3189
3190 let user = Arc::new(User {
3191 name: "Charlie".to_string(),
3192 });
3193
3194 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3195 let name_pkp = PKp::new(name_kp);
3196
3197 let arc_pkp = name_pkp.for_arc();
3199
3200 assert_eq!(
3201 arc_pkp.get_as::<String>(&user),
3202 Some(&"Charlie".to_string())
3203 );
3204 }
3205
3206 #[test]
3207 fn test_pkp_for_option() {
3208 #[derive(Debug)]
3209 struct User {
3210 name: String,
3211 }
3212
3213 let some_user = Some(User {
3214 name: "Diana".to_string(),
3215 });
3216 let none_user: Option<User> = None;
3217
3218 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3219 let name_pkp = PKp::new(name_kp);
3220
3221 let opt_pkp = name_pkp.for_option();
3223
3224 assert_eq!(
3225 opt_pkp.get_as::<String>(&some_user),
3226 Some(&"Diana".to_string())
3227 );
3228 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
3229 }
3230
3231 #[test]
3232 fn test_akp_basic() {
3233 #[derive(Debug)]
3234 struct User {
3235 name: String,
3236 age: i32,
3237 }
3238
3239 #[derive(Debug)]
3240 struct Product {
3241 title: String,
3242 price: f64,
3243 }
3244
3245 let user = User {
3246 name: "Eve".to_string(),
3247 age: 28,
3248 };
3249
3250 let product = Product {
3251 title: "Book".to_string(),
3252 price: 19.99,
3253 };
3254
3255 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3257 let user_name_akp = AKp::new(user_name_kp);
3258
3259 let product_title_kp = KpType::new(
3260 |p: &Product| Some(&p.title),
3261 |p: &mut Product| Some(&mut p.title),
3262 );
3263 let product_title_akp = AKp::new(product_title_kp);
3264
3265 assert_eq!(
3267 user_name_akp.get_as::<User, String>(&user),
3268 Some(Some(&"Eve".to_string()))
3269 );
3270 assert_eq!(
3271 product_title_akp.get_as::<Product, String>(&product),
3272 Some(Some(&"Book".to_string()))
3273 );
3274
3275 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
3277 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
3278
3279 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
3281 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
3282 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
3283 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
3284 }
3285
3286 #[test]
3287 fn test_akp_heterogeneous_collection() {
3288 #[derive(Debug)]
3289 struct User {
3290 name: String,
3291 }
3292
3293 #[derive(Debug)]
3294 struct Product {
3295 title: String,
3296 }
3297
3298 let user = User {
3299 name: "Frank".to_string(),
3300 };
3301 let product = Product {
3302 title: "Laptop".to_string(),
3303 };
3304
3305 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3307 let product_title_kp = KpType::new(
3308 |p: &Product| Some(&p.title),
3309 |p: &mut Product| Some(&mut p.title),
3310 );
3311
3312 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
3313
3314 let user_any: &dyn Any = &user;
3316 let product_any: &dyn Any = &product;
3317
3318 let user_value = keypaths[0].get(user_any);
3319 let product_value = keypaths[1].get(product_any);
3320
3321 assert!(user_value.is_some());
3322 assert!(product_value.is_some());
3323
3324 assert_eq!(
3326 user_value.and_then(|v| v.downcast_ref::<String>()),
3327 Some(&"Frank".to_string())
3328 );
3329 assert_eq!(
3330 product_value.and_then(|v| v.downcast_ref::<String>()),
3331 Some(&"Laptop".to_string())
3332 );
3333 }
3334
3335 #[test]
3336 fn test_akp_for_option() {
3337 #[derive(Debug)]
3338 struct User {
3339 name: String,
3340 }
3341
3342 let some_user = Some(User {
3343 name: "Grace".to_string(),
3344 });
3345 let none_user: Option<User> = None;
3346
3347 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3348 let name_akp = AKp::new(name_kp);
3349
3350 let opt_akp = name_akp.for_option::<User>();
3352
3353 assert_eq!(
3354 opt_akp.get_as::<Option<User>, String>(&some_user),
3355 Some(Some(&"Grace".to_string()))
3356 );
3357 assert_eq!(
3358 opt_akp.get_as::<Option<User>, String>(&none_user),
3359 Some(None)
3360 );
3361 }
3362
3363 #[test]
3364 fn test_akp_for_result() {
3365 #[derive(Debug)]
3366 struct User {
3367 name: String,
3368 }
3369
3370 let ok_user: Result<User, String> = Ok(User {
3371 name: "Henry".to_string(),
3372 });
3373 let err_user: Result<User, String> = Err("Not found".to_string());
3374
3375 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3376 let name_akp = AKp::new(name_kp);
3377
3378 let result_akp = name_akp.for_result::<User, String>();
3380
3381 assert_eq!(
3382 result_akp.get_as::<Result<User, String>, String>(&ok_user),
3383 Some(Some(&"Henry".to_string()))
3384 );
3385 assert_eq!(
3386 result_akp.get_as::<Result<User, String>, String>(&err_user),
3387 Some(None)
3388 );
3389 }
3390
3391 #[test]
3394 fn test_kp_map() {
3395 #[derive(Debug)]
3396 struct User {
3397 name: String,
3398 age: i32,
3399 }
3400
3401 let user = User {
3402 name: "Akash".to_string(),
3403 age: 30,
3404 };
3405
3406 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3408 let len_kp = name_kp.map(|name: &String| name.len());
3409
3410 assert_eq!((len_kp.get)(&user), Some(5));
3411
3412 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3414 let double_age_kp = age_kp.map(|age: &i32| age * 2);
3415
3416 assert_eq!((double_age_kp.get)(&user), Some(60));
3417
3418 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
3420 assert_eq!((is_adult_kp.get)(&user), Some(true));
3421 }
3422
3423 #[test]
3424 fn test_kp_filter() {
3425 #[derive(Debug)]
3426 struct User {
3427 name: String,
3428 age: i32,
3429 }
3430
3431 let adult = User {
3432 name: "Akash".to_string(),
3433 age: 30,
3434 };
3435
3436 let minor = User {
3437 name: "Bob".to_string(),
3438 age: 15,
3439 };
3440
3441 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3442 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
3443
3444 assert_eq!((adult_age_kp.get)(&adult), Some(&30));
3445 assert_eq!((adult_age_kp.get)(&minor), None);
3446
3447 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3449 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
3450
3451 assert_eq!((short_name_kp.get)(&minor), Some(&"Bob".to_string()));
3452 assert_eq!((short_name_kp.get)(&adult), None);
3453 }
3454
3455 #[test]
3456 fn test_kp_map_and_filter() {
3457 #[derive(Debug)]
3458 struct User {
3459 scores: Vec<i32>,
3460 }
3461
3462 let user = User {
3463 scores: vec![85, 92, 78, 95],
3464 };
3465
3466 let scores_kp = KpType::new(
3467 |u: &User| Some(&u.scores),
3468 |u: &mut User| Some(&mut u.scores),
3469 );
3470
3471 let avg_kp =
3473 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3474
3475 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
3477
3478 assert_eq!((high_avg_kp.get)(&user), Some(87)); }
3480
3481 #[test]
3482 fn test_enum_kp_map() {
3483 let ok_result: Result<String, i32> = Ok("hello".to_string());
3484 let err_result: Result<String, i32> = Err(42);
3485
3486 let ok_kp = enum_ok::<String, i32>();
3487 let len_kp = ok_kp.map(|s: &String| s.len());
3488
3489 assert_eq!(len_kp.get(&ok_result), Some(5));
3490 assert_eq!(len_kp.get(&err_result), None);
3491
3492 let some_opt = Some(vec![1, 2, 3, 4, 5]);
3494 let none_opt: Option<Vec<i32>> = None;
3495
3496 let some_kp = enum_some::<Vec<i32>>();
3497 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
3498
3499 assert_eq!(count_kp.get(&some_opt), Some(5));
3500 assert_eq!(count_kp.get(&none_opt), None);
3501 }
3502
3503 #[test]
3504 fn test_enum_kp_filter() {
3505 let ok_result1: Result<i32, String> = Ok(42);
3506 let ok_result2: Result<i32, String> = Ok(-5);
3507 let err_result: Result<i32, String> = Err("error".to_string());
3508
3509 let ok_kp = enum_ok::<i32, String>();
3510 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
3511
3512 assert_eq!((positive_kp.extractor.get)(&ok_result1), Some(&42));
3513 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
3518 let short_str = Some("hi".to_string());
3519
3520 let some_kp = enum_some::<String>();
3521 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
3522
3523 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
3524 assert_eq!(long_kp.get(&short_str), None);
3525 }
3526
3527 #[test]
3528 fn test_pkp_filter() {
3529 #[derive(Debug)]
3530 struct User {
3531 name: String,
3532 age: i32,
3533 }
3534
3535 let adult = User {
3536 name: "Akash".to_string(),
3537 age: 30,
3538 };
3539
3540 let minor = User {
3541 name: "Bob".to_string(),
3542 age: 15,
3543 };
3544
3545 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3546 let age_pkp = PKp::new(age_kp);
3547
3548 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
3550
3551 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
3552 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
3553
3554 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3556 let name_pkp = PKp::new(name_kp);
3557 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
3558
3559 assert_eq!(
3560 short_name_pkp.get_as::<String>(&minor),
3561 Some(&"Bob".to_string())
3562 );
3563 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
3564 }
3565
3566 #[test]
3567 fn test_akp_filter() {
3568 #[derive(Debug)]
3569 struct User {
3570 age: i32,
3571 }
3572
3573 #[derive(Debug)]
3574 struct Product {
3575 price: f64,
3576 }
3577
3578 let adult = User { age: 30 };
3579 let minor = User { age: 15 };
3580 let expensive = Product { price: 99.99 };
3581 let cheap = Product { price: 5.0 };
3582
3583 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3585 let age_akp = AKp::new(age_kp);
3586 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
3587
3588 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
3589 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
3590
3591 let price_kp = KpType::new(
3593 |p: &Product| Some(&p.price),
3594 |p: &mut Product| Some(&mut p.price),
3595 );
3596 let price_akp = AKp::new(price_kp);
3597 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
3598
3599 assert_eq!(
3600 expensive_akp.get_as::<Product, f64>(&expensive),
3601 Some(Some(&99.99))
3602 );
3603 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
3604 }
3605
3606 #[test]
3609 fn test_kp_filter_map() {
3610 #[derive(Debug)]
3611 struct User {
3612 middle_name: Option<String>,
3613 }
3614
3615 let user_with = User {
3616 middle_name: Some("Marie".to_string()),
3617 };
3618 let user_without = User { middle_name: None };
3619
3620 let middle_kp = KpType::new(
3621 |u: &User| Some(&u.middle_name),
3622 |u: &mut User| Some(&mut u.middle_name),
3623 );
3624
3625 let first_char_kp = middle_kp
3626 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
3627
3628 assert_eq!((first_char_kp.get)(&user_with), Some('M'));
3629 assert_eq!((first_char_kp.get)(&user_without), None);
3630 }
3631
3632 #[test]
3633 fn test_kp_inspect() {
3634 #[derive(Debug)]
3635 struct User {
3636 name: String,
3637 }
3638
3639 let user = User {
3640 name: "Akash".to_string(),
3641 };
3642
3643 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3647
3648 let result = (name_kp.get)(&user);
3651 assert_eq!(result, Some(&"Akash".to_string()));
3652
3653 }
3656
3657 #[test]
3658 fn test_kp_fold_value() {
3659 #[derive(Debug)]
3660 struct User {
3661 scores: Vec<i32>,
3662 }
3663
3664 let user = User {
3665 scores: vec![85, 92, 78, 95],
3666 };
3667
3668 let scores_kp = KpType::new(
3669 |u: &User| Some(&u.scores),
3670 |u: &mut User| Some(&mut u.scores),
3671 );
3672
3673 let sum_fn =
3675 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
3676
3677 assert_eq!(sum_fn(&user), 350);
3678 }
3679
3680 #[test]
3681 fn test_kp_any_all() {
3682 #[derive(Debug)]
3683 struct User {
3684 scores: Vec<i32>,
3685 }
3686
3687 let user_high = User {
3688 scores: vec![85, 92, 88],
3689 };
3690 let user_mixed = User {
3691 scores: vec![65, 92, 78],
3692 };
3693
3694 let scores_kp = KpType::new(
3695 |u: &User| Some(&u.scores),
3696 |u: &mut User| Some(&mut u.scores),
3697 );
3698
3699 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
3701 assert!(has_high_fn(&user_high));
3702 assert!(has_high_fn(&user_mixed));
3703
3704 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
3706 assert!(all_passing_fn(&user_high));
3707 assert!(!all_passing_fn(&user_mixed));
3708 }
3709
3710 #[test]
3711 fn test_kp_count_items() {
3712 #[derive(Debug)]
3713 struct User {
3714 tags: Vec<String>,
3715 }
3716
3717 let user = User {
3718 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
3719 };
3720
3721 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3722 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
3723
3724 assert_eq!(count_fn(&user), Some(3));
3725 }
3726
3727 #[test]
3728 fn test_kp_find_in() {
3729 #[derive(Debug)]
3730 struct User {
3731 scores: Vec<i32>,
3732 }
3733
3734 let user = User {
3735 scores: vec![85, 92, 78, 95, 88],
3736 };
3737
3738 let scores_kp = KpType::new(
3739 |u: &User| Some(&u.scores),
3740 |u: &mut User| Some(&mut u.scores),
3741 );
3742
3743 let first_high_fn =
3745 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3746
3747 assert_eq!(first_high_fn(&user), Some(92));
3748
3749 let perfect_fn =
3751 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3752
3753 assert_eq!(perfect_fn(&user), None);
3754 }
3755
3756 #[test]
3757 fn test_kp_take_skip() {
3758 #[derive(Debug)]
3759 struct User {
3760 tags: Vec<String>,
3761 }
3762
3763 let user = User {
3764 tags: vec![
3765 "a".to_string(),
3766 "b".to_string(),
3767 "c".to_string(),
3768 "d".to_string(),
3769 ],
3770 };
3771
3772 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3773
3774 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3776 tags.iter().take(n).cloned().collect::<Vec<_>>()
3777 });
3778
3779 let taken = take_fn(&user).unwrap();
3780 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3781
3782 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3784 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3785 });
3786
3787 let skipped = skip_fn(&user).unwrap();
3788 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3789 }
3790
3791 #[test]
3792 fn test_kp_partition() {
3793 #[derive(Debug)]
3794 struct User {
3795 scores: Vec<i32>,
3796 }
3797
3798 let user = User {
3799 scores: vec![85, 92, 65, 95, 72, 58],
3800 };
3801
3802 let scores_kp = KpType::new(
3803 |u: &User| Some(&u.scores),
3804 |u: &mut User| Some(&mut u.scores),
3805 );
3806
3807 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3808 scores.iter().copied().partition(|&s| s >= 70)
3809 });
3810
3811 let (passing, failing) = partition_fn(&user).unwrap();
3812 assert_eq!(passing, vec![85, 92, 95, 72]);
3813 assert_eq!(failing, vec![65, 58]);
3814 }
3815
3816 #[test]
3817 fn test_kp_min_max() {
3818 #[derive(Debug)]
3819 struct User {
3820 scores: Vec<i32>,
3821 }
3822
3823 let user = User {
3824 scores: vec![85, 92, 78, 95, 88],
3825 };
3826
3827 let scores_kp = KpType::new(
3828 |u: &User| Some(&u.scores),
3829 |u: &mut User| Some(&mut u.scores),
3830 );
3831
3832 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3834 assert_eq!(min_fn(&user), Some(78));
3835
3836 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3838 assert_eq!(max_fn(&user), Some(95));
3839 }
3840
3841 #[test]
3842 fn test_kp_sum() {
3843 #[derive(Debug)]
3844 struct User {
3845 scores: Vec<i32>,
3846 }
3847
3848 let user = User {
3849 scores: vec![85, 92, 78],
3850 };
3851
3852 let scores_kp = KpType::new(
3853 |u: &User| Some(&u.scores),
3854 |u: &mut User| Some(&mut u.scores),
3855 );
3856
3857 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3858 assert_eq!(sum_fn(&user), Some(255));
3859
3860 let avg_fn =
3862 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3863 assert_eq!(avg_fn.get(&user), Some(85));
3864 }
3865
3866 #[test]
3867 fn test_kp_chain() {
3868 #[derive(Debug)]
3869 struct User {
3870 profile: Profile,
3871 }
3872
3873 #[derive(Debug)]
3874 struct Profile {
3875 settings: Settings,
3876 }
3877
3878 #[derive(Debug)]
3879 struct Settings {
3880 theme: String,
3881 }
3882
3883 let user = User {
3884 profile: Profile {
3885 settings: Settings {
3886 theme: "dark".to_string(),
3887 },
3888 },
3889 };
3890
3891 let profile_kp = KpType::new(
3892 |u: &User| Some(&u.profile),
3893 |u: &mut User| Some(&mut u.profile),
3894 );
3895 let settings_kp = KpType::new(
3896 |p: &Profile| Some(&p.settings),
3897 |p: &mut Profile| Some(&mut p.settings),
3898 );
3899 let theme_kp = KpType::new(
3900 |s: &Settings| Some(&s.theme),
3901 |s: &mut Settings| Some(&mut s.theme),
3902 );
3903
3904 let profile_settings = profile_kp.then(settings_kp);
3906 let theme_path = profile_settings.then(theme_kp);
3907 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3908 }
3909
3910 #[test]
3911 fn test_kp_zip() {
3912 #[derive(Debug)]
3913 struct User {
3914 name: String,
3915 age: i32,
3916 }
3917
3918 let user = User {
3919 name: "Akash".to_string(),
3920 age: 30,
3921 };
3922
3923 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3924 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3925
3926 let zipped_fn = zip_kps(&name_kp, &age_kp);
3927 let result = zipped_fn(&user);
3928
3929 assert_eq!(result, Some((&"Akash".to_string(), &30)));
3930 }
3931
3932 #[test]
3933 fn test_kp_complex_pipeline() {
3934 #[derive(Debug)]
3935 struct User {
3936 transactions: Vec<Transaction>,
3937 }
3938
3939 #[derive(Debug)]
3940 struct Transaction {
3941 amount: f64,
3942 category: String,
3943 }
3944
3945 let user = User {
3946 transactions: vec![
3947 Transaction {
3948 amount: 50.0,
3949 category: "food".to_string(),
3950 },
3951 Transaction {
3952 amount: 100.0,
3953 category: "transport".to_string(),
3954 },
3955 Transaction {
3956 amount: 25.0,
3957 category: "food".to_string(),
3958 },
3959 Transaction {
3960 amount: 200.0,
3961 category: "shopping".to_string(),
3962 },
3963 ],
3964 };
3965
3966 let txns_kp = KpType::new(
3967 |u: &User| Some(&u.transactions),
3968 |u: &mut User| Some(&mut u.transactions),
3969 );
3970
3971 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3973 txns.iter()
3974 .filter(|t| t.category == "food")
3975 .map(|t| t.amount)
3976 .sum::<f64>()
3977 });
3978
3979 assert_eq!(food_total.get(&user), Some(75.0));
3980
3981 let has_large =
3983 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3984
3985 assert!(has_large(&user));
3986
3987 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3989 assert_eq!(count(&user), Some(4));
3990 }
3991
3992 #[test]
3996 fn test_no_clone_required_for_root() {
3997 use std::sync::Arc;
3998 use std::sync::atomic::{AtomicUsize, Ordering};
3999
4000 struct NonCloneableRoot {
4003 data: Arc<AtomicUsize>,
4004 cached_value: usize,
4005 }
4006
4007 impl NonCloneableRoot {
4008 fn new() -> Self {
4009 Self {
4010 data: Arc::new(AtomicUsize::new(42)),
4011 cached_value: 42,
4012 }
4013 }
4014
4015 fn increment(&mut self) {
4016 self.data.fetch_add(1, Ordering::SeqCst);
4017 self.cached_value = self.data.load(Ordering::SeqCst);
4018 }
4019
4020 fn get_value(&self) -> &usize {
4021 &self.cached_value
4022 }
4023
4024 fn get_value_mut(&mut self) -> &mut usize {
4025 &mut self.cached_value
4026 }
4027 }
4028
4029 let mut root = NonCloneableRoot::new();
4030
4031 let data_kp = KpType::new(
4033 |r: &NonCloneableRoot| Some(r.get_value()),
4034 |r: &mut NonCloneableRoot| {
4035 r.increment();
4036 Some(r.get_value_mut())
4037 },
4038 );
4039
4040 assert_eq!(data_kp.get(&root), Some(&42));
4042
4043 {
4044 let doubled = data_kp.map(|val: &usize| val * 2);
4046 assert_eq!(doubled.get(&root), Some(84));
4047
4048 let filtered = data_kp.filter(|val: &usize| *val > 0);
4050 assert_eq!(filtered.get(&root), Some(&42));
4051 } let value_ref = data_kp.get_mut(&mut root);
4055 assert!(value_ref.is_some());
4056 }
4057
4058 #[test]
4059 fn test_no_clone_required_for_value() {
4060 use std::sync::Arc;
4061 use std::sync::atomic::{AtomicUsize, Ordering};
4062
4063 struct NonCloneableValue {
4065 counter: Arc<AtomicUsize>,
4066 }
4067
4068 impl NonCloneableValue {
4069 fn new(val: usize) -> Self {
4070 Self {
4071 counter: Arc::new(AtomicUsize::new(val)),
4072 }
4073 }
4074
4075 fn get(&self) -> usize {
4076 self.counter.load(Ordering::SeqCst)
4077 }
4078 }
4079
4080 struct Root {
4081 value: NonCloneableValue,
4082 }
4083
4084 let root = Root {
4085 value: NonCloneableValue::new(100),
4086 };
4087
4088 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4090
4091 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
4093 assert_eq!(counter_kp.get(&root), Some(100));
4094
4095 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
4097 assert!(filtered.get(&root).is_some());
4098 }
4099
4100 #[test]
4101 fn test_static_does_not_leak_memory() {
4102 use std::sync::Arc;
4103 use std::sync::atomic::{AtomicUsize, Ordering};
4104
4105 static CREATED: AtomicUsize = AtomicUsize::new(0);
4107 static DROPPED: AtomicUsize = AtomicUsize::new(0);
4108
4109 struct Tracked {
4110 id: usize,
4111 }
4112
4113 impl Tracked {
4114 fn new() -> Self {
4115 let id = CREATED.fetch_add(1, Ordering::SeqCst);
4116 Self { id }
4117 }
4118 }
4119
4120 impl Drop for Tracked {
4121 fn drop(&mut self) {
4122 DROPPED.fetch_add(1, Ordering::SeqCst);
4123 }
4124 }
4125
4126 struct Root {
4127 data: Tracked,
4128 }
4129
4130 CREATED.store(0, Ordering::SeqCst);
4132 DROPPED.store(0, Ordering::SeqCst);
4133
4134 {
4135 let root = Root {
4136 data: Tracked::new(),
4137 };
4138
4139 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4140
4141 let mapped1 = data_kp.map(|t: &Tracked| t.id);
4143 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
4144 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
4145
4146 assert_eq!(mapped1.get(&root), Some(0));
4147 assert_eq!(mapped2.get(&root), Some(1));
4148 assert_eq!(mapped3.get(&root), Some(2));
4149
4150 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
4152 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
4153 }
4154
4155 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
4157 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
4158
4159 }
4161
4162 #[test]
4163 fn test_references_not_cloned() {
4164 use std::sync::Arc;
4165
4166 struct ExpensiveData {
4168 large_vec: Vec<u8>,
4169 }
4170
4171 impl ExpensiveData {
4172 fn new(size: usize) -> Self {
4173 Self {
4174 large_vec: vec![0u8; size],
4175 }
4176 }
4177
4178 fn size(&self) -> usize {
4179 self.large_vec.len()
4180 }
4181 }
4182
4183 struct Root {
4184 expensive: ExpensiveData,
4185 }
4186
4187 let root = Root {
4188 expensive: ExpensiveData::new(1_000_000), };
4190
4191 let expensive_kp = KpType::new(
4192 |r: &Root| Some(&r.expensive),
4193 |r: &mut Root| Some(&mut r.expensive),
4194 );
4195
4196 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
4198 assert_eq!(size_kp.get(&root), Some(1_000_000));
4199
4200 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
4202 assert!(large_filter.get(&root).is_some());
4203
4204 }
4206
4207 #[test]
4208 fn test_hof_with_arc_no_extra_clones() {
4209 use std::sync::Arc;
4210
4211 #[derive(Debug)]
4212 struct SharedData {
4213 value: String,
4214 }
4215
4216 struct Root {
4217 shared: Arc<SharedData>,
4218 }
4219
4220 let shared = Arc::new(SharedData {
4221 value: "shared".to_string(),
4222 });
4223
4224 assert_eq!(Arc::strong_count(&shared), 1);
4226
4227 {
4228 let root = Root {
4229 shared: Arc::clone(&shared),
4230 };
4231
4232 assert_eq!(Arc::strong_count(&shared), 2);
4234
4235 let shared_kp = KpType::new(
4236 |r: &Root| Some(&r.shared),
4237 |r: &mut Root| Some(&mut r.shared),
4238 );
4239
4240 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
4242
4243 assert_eq!(value_kp.get(&root), Some(6));
4245 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
4249 assert!(filtered.get(&root).is_some());
4250 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
4255
4256 #[test]
4257 fn test_closure_captures_not_root_values() {
4258 use std::sync::Arc;
4259 use std::sync::atomic::{AtomicUsize, Ordering};
4260
4261 let call_count = Arc::new(AtomicUsize::new(0));
4263 let call_count_clone = Arc::clone(&call_count);
4264
4265 struct Root {
4266 value: i32,
4267 }
4268
4269 let root = Root { value: 42 };
4270
4271 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4272
4273 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
4276 call_count_clone.fetch_add(1, Ordering::SeqCst);
4277 v * 2
4278 });
4279
4280 assert_eq!(doubled(&root), 84);
4282 assert_eq!(doubled(&root), 84);
4283 assert_eq!(doubled(&root), 84);
4284
4285 assert_eq!(call_count.load(Ordering::SeqCst), 3);
4287
4288 }
4290
4291 #[test]
4292 fn test_static_with_borrowed_data() {
4293 struct Root {
4297 data: String,
4298 }
4299
4300 {
4301 let root = Root {
4302 data: "temporary".to_string(),
4303 };
4304
4305 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4306
4307 let len_kp = data_kp.map(|s: &String| s.len());
4309 assert_eq!(len_kp.get(&root), Some(9));
4310
4311 } }
4316
4317 #[test]
4318 fn test_multiple_hof_operations_no_accumulation() {
4319 use std::sync::Arc;
4320 use std::sync::atomic::{AtomicUsize, Ordering};
4321
4322 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
4323
4324 struct Tracked {
4325 id: usize,
4326 }
4327
4328 impl Drop for Tracked {
4329 fn drop(&mut self) {
4330 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4331 }
4332 }
4333
4334 struct Root {
4335 values: Vec<Tracked>,
4336 }
4337
4338 DROP_COUNT.store(0, Ordering::SeqCst);
4339
4340 {
4341 let root = Root {
4342 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
4343 };
4344
4345 let values_kp = KpType::new(
4346 |r: &Root| Some(&r.values),
4347 |r: &mut Root| Some(&mut r.values),
4348 );
4349
4350 let count = values_kp.count_items(|v| v.len());
4352 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
4353 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
4354 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
4355
4356 assert_eq!(count(&root), Some(3));
4357 assert_eq!(sum(&root), Some(6));
4358 assert!(has_2(&root));
4359 assert!(all_positive(&root));
4360
4361 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4363 }
4364
4365 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
4367 }
4368
4369 #[test]
4370 fn test_copy_bound_only_for_function_not_data() {
4371 #[derive(Debug)]
4375 struct NonCopyData {
4376 value: String,
4377 }
4378
4379 struct Root {
4380 data: NonCopyData,
4381 }
4382
4383 let root = Root {
4384 data: NonCopyData {
4385 value: "test".to_string(),
4386 },
4387 };
4388
4389 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4390
4391 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
4394 assert_eq!(len_kp.get(&root), Some(4));
4395
4396 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
4398 assert!(filtered.get(&root).is_some());
4399 }
4400
4401 #[test]
4402 fn test_no_memory_leak_with_cyclic_references() {
4403 use std::sync::atomic::{AtomicUsize, Ordering};
4404 use std::sync::{Arc, Weak};
4405
4406 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
4407
4408 struct Node {
4409 id: usize,
4410 parent: Option<Weak<Node>>,
4411 }
4412
4413 impl Drop for Node {
4414 fn drop(&mut self) {
4415 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4416 }
4417 }
4418
4419 struct Root {
4420 node: Arc<Node>,
4421 }
4422
4423 DROP_COUNT.store(0, Ordering::SeqCst);
4424
4425 {
4426 let root = Root {
4427 node: Arc::new(Node {
4428 id: 1,
4429 parent: None,
4430 }),
4431 };
4432
4433 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
4434
4435 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
4437 assert_eq!(id_kp.get(&root), Some(1));
4438
4439 assert_eq!(Arc::strong_count(&root.node), 1);
4441
4442 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4444 }
4445
4446 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
4448 }
4449
4450 #[test]
4451 fn test_hof_operations_are_zero_cost_abstractions() {
4452 struct Root {
4456 value: i32,
4457 }
4458
4459 let root = Root { value: 10 };
4460
4461 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4462
4463 let direct_result = value_kp.get(&root).map(|v| v * 2);
4465 assert_eq!(direct_result, Some(20));
4466
4467 let mapped_kp = value_kp.map(|v: &i32| v * 2);
4469 let hof_result = mapped_kp.get(&root);
4470 assert_eq!(hof_result, Some(20));
4471
4472 assert_eq!(direct_result, hof_result);
4474 }
4475
4476 #[test]
4477 fn test_complex_closure_captures_allowed() {
4478 use std::sync::Arc;
4479
4480 struct Root {
4482 scores: Vec<i32>,
4483 }
4484
4485 let root = Root {
4486 scores: vec![85, 92, 78, 95, 88],
4487 };
4488
4489 let scores_kp = KpType::new(
4490 |r: &Root| Some(&r.scores),
4491 |r: &mut Root| Some(&mut r.scores),
4492 );
4493
4494 let threshold = 90;
4496 let multiplier = Arc::new(2);
4497
4498 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
4500 let high: i32 = scores
4501 .iter()
4502 .filter(|&&s| s >= threshold)
4503 .map(|&s| s * *multiplier)
4504 .sum();
4505 acc + high
4506 });
4507
4508 assert_eq!(high_scores_doubled(&root), 374);
4510 }
4511
4512 #[test]
4516 fn test_pkp_filter_by_value_type() {
4517 use std::any::TypeId;
4518
4519 #[derive(Debug)]
4520 struct User {
4521 name: String,
4522 age: i32,
4523 score: f64,
4524 active: bool,
4525 }
4526
4527 let user = User {
4528 name: "Akash".to_string(),
4529 age: 30,
4530 score: 95.5,
4531 active: true,
4532 };
4533
4534 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4536 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4537 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
4538 let active_kp = KpType::new(
4539 |u: &User| Some(&u.active),
4540 |u: &mut User| Some(&mut u.active),
4541 );
4542
4543 let all_keypaths: Vec<PKp<User>> = vec![
4545 PKp::new(name_kp),
4546 PKp::new(age_kp),
4547 PKp::new(score_kp),
4548 PKp::new(active_kp),
4549 ];
4550
4551 let string_kps: Vec<_> = all_keypaths
4553 .iter()
4554 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
4555 .collect();
4556
4557 assert_eq!(string_kps.len(), 1);
4558 assert_eq!(
4559 string_kps[0].get_as::<String>(&user),
4560 Some(&"Akash".to_string())
4561 );
4562
4563 let i32_kps: Vec<_> = all_keypaths
4565 .iter()
4566 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
4567 .collect();
4568
4569 assert_eq!(i32_kps.len(), 1);
4570 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
4571
4572 let f64_kps: Vec<_> = all_keypaths
4574 .iter()
4575 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
4576 .collect();
4577
4578 assert_eq!(f64_kps.len(), 1);
4579 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
4580
4581 let bool_kps: Vec<_> = all_keypaths
4583 .iter()
4584 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
4585 .collect();
4586
4587 assert_eq!(bool_kps.len(), 1);
4588 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
4589 }
4590
4591 #[test]
4592 fn test_pkp_filter_by_struct_type() {
4593 use std::any::TypeId;
4594
4595 #[derive(Debug, PartialEq)]
4596 struct Address {
4597 street: String,
4598 city: String,
4599 }
4600
4601 #[derive(Debug)]
4602 struct User {
4603 name: String,
4604 age: i32,
4605 address: Address,
4606 }
4607
4608 let user = User {
4609 name: "Bob".to_string(),
4610 age: 25,
4611 address: Address {
4612 street: "123 Main St".to_string(),
4613 city: "NYC".to_string(),
4614 },
4615 };
4616
4617 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4619 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4620 let address_kp = KpType::new(
4621 |u: &User| Some(&u.address),
4622 |u: &mut User| Some(&mut u.address),
4623 );
4624
4625 let all_keypaths: Vec<PKp<User>> =
4626 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
4627
4628 let struct_kps: Vec<_> = all_keypaths
4630 .iter()
4631 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
4632 .collect();
4633
4634 assert_eq!(struct_kps.len(), 1);
4635 assert_eq!(
4636 struct_kps[0].get_as::<Address>(&user),
4637 Some(&Address {
4638 street: "123 Main St".to_string(),
4639 city: "NYC".to_string(),
4640 })
4641 );
4642
4643 let primitive_kps: Vec<_> = all_keypaths
4645 .iter()
4646 .filter(|pkp| {
4647 pkp.value_type_id() == TypeId::of::<String>()
4648 || pkp.value_type_id() == TypeId::of::<i32>()
4649 })
4650 .collect();
4651
4652 assert_eq!(primitive_kps.len(), 2);
4653 }
4654
4655 #[test]
4656 fn test_pkp_filter_by_arc_type() {
4657 use std::any::TypeId;
4658 use std::sync::Arc;
4659
4660 #[derive(Debug)]
4661 struct User {
4662 name: String,
4663 shared_data: Arc<String>,
4664 shared_number: Arc<i32>,
4665 }
4666
4667 let user = User {
4668 name: "Charlie".to_string(),
4669 shared_data: Arc::new("shared".to_string()),
4670 shared_number: Arc::new(42),
4671 };
4672
4673 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4675 let shared_data_kp = KpType::new(
4676 |u: &User| Some(&u.shared_data),
4677 |u: &mut User| Some(&mut u.shared_data),
4678 );
4679 let shared_number_kp = KpType::new(
4680 |u: &User| Some(&u.shared_number),
4681 |u: &mut User| Some(&mut u.shared_number),
4682 );
4683
4684 let all_keypaths: Vec<PKp<User>> = vec![
4685 PKp::new(name_kp),
4686 PKp::new(shared_data_kp),
4687 PKp::new(shared_number_kp),
4688 ];
4689
4690 let arc_string_kps: Vec<_> = all_keypaths
4692 .iter()
4693 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
4694 .collect();
4695
4696 assert_eq!(arc_string_kps.len(), 1);
4697 assert_eq!(
4698 arc_string_kps[0]
4699 .get_as::<Arc<String>>(&user)
4700 .map(|arc| arc.as_str()),
4701 Some("shared")
4702 );
4703
4704 let arc_i32_kps: Vec<_> = all_keypaths
4706 .iter()
4707 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
4708 .collect();
4709
4710 assert_eq!(arc_i32_kps.len(), 1);
4711 assert_eq!(
4712 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
4713 Some(42)
4714 );
4715
4716 let all_arc_kps: Vec<_> = all_keypaths
4718 .iter()
4719 .filter(|pkp| {
4720 pkp.value_type_id() == TypeId::of::<Arc<String>>()
4721 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
4722 })
4723 .collect();
4724
4725 assert_eq!(all_arc_kps.len(), 2);
4726 }
4727
4728 #[test]
4729 fn test_pkp_filter_by_box_type() {
4730 use std::any::TypeId;
4731
4732 #[derive(Debug)]
4733 struct User {
4734 name: String,
4735 boxed_value: Box<i32>,
4736 boxed_string: Box<String>,
4737 }
4738
4739 let user = User {
4740 name: "Diana".to_string(),
4741 boxed_value: Box::new(100),
4742 boxed_string: Box::new("boxed".to_string()),
4743 };
4744
4745 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4747 let boxed_value_kp = KpType::new(
4748 |u: &User| Some(&u.boxed_value),
4749 |u: &mut User| Some(&mut u.boxed_value),
4750 );
4751 let boxed_string_kp = KpType::new(
4752 |u: &User| Some(&u.boxed_string),
4753 |u: &mut User| Some(&mut u.boxed_string),
4754 );
4755
4756 let all_keypaths: Vec<PKp<User>> = vec![
4757 PKp::new(name_kp),
4758 PKp::new(boxed_value_kp),
4759 PKp::new(boxed_string_kp),
4760 ];
4761
4762 let box_i32_kps: Vec<_> = all_keypaths
4764 .iter()
4765 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4766 .collect();
4767
4768 assert_eq!(box_i32_kps.len(), 1);
4769 assert_eq!(
4770 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4771 Some(100)
4772 );
4773
4774 let box_string_kps: Vec<_> = all_keypaths
4776 .iter()
4777 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4778 .collect();
4779
4780 assert_eq!(box_string_kps.len(), 1);
4781 assert_eq!(
4782 box_string_kps[0]
4783 .get_as::<Box<String>>(&user)
4784 .map(|b| b.as_str()),
4785 Some("boxed")
4786 );
4787 }
4788
4789 #[test]
4790 fn test_akp_filter_by_root_and_value_type() {
4791 use std::any::TypeId;
4792
4793 #[derive(Debug)]
4794 struct User {
4795 name: String,
4796 age: i32,
4797 }
4798
4799 #[derive(Debug)]
4800 struct Product {
4801 title: String,
4802 price: f64,
4803 }
4804
4805 let user = User {
4806 name: "Eve".to_string(),
4807 age: 28,
4808 };
4809
4810 let product = Product {
4811 title: "Book".to_string(),
4812 price: 19.99,
4813 };
4814
4815 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4817 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4818 let product_title_kp = KpType::new(
4819 |p: &Product| Some(&p.title),
4820 |p: &mut Product| Some(&mut p.title),
4821 );
4822 let product_price_kp = KpType::new(
4823 |p: &Product| Some(&p.price),
4824 |p: &mut Product| Some(&mut p.price),
4825 );
4826
4827 let all_keypaths: Vec<AKp> = vec![
4828 AKp::new(user_name_kp),
4829 AKp::new(user_age_kp),
4830 AKp::new(product_title_kp),
4831 AKp::new(product_price_kp),
4832 ];
4833
4834 let user_kps: Vec<_> = all_keypaths
4836 .iter()
4837 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4838 .collect();
4839
4840 assert_eq!(user_kps.len(), 2);
4841
4842 let product_kps: Vec<_> = all_keypaths
4844 .iter()
4845 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4846 .collect();
4847
4848 assert_eq!(product_kps.len(), 2);
4849
4850 let string_value_kps: Vec<_> = all_keypaths
4852 .iter()
4853 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4854 .collect();
4855
4856 assert_eq!(string_value_kps.len(), 2);
4857
4858 let user_string_kps: Vec<_> = all_keypaths
4860 .iter()
4861 .filter(|akp| {
4862 akp.root_type_id() == TypeId::of::<User>()
4863 && akp.value_type_id() == TypeId::of::<String>()
4864 })
4865 .collect();
4866
4867 assert_eq!(user_string_kps.len(), 1);
4868 assert_eq!(
4869 user_string_kps[0].get_as::<User, String>(&user),
4870 Some(Some(&"Eve".to_string()))
4871 );
4872
4873 let product_f64_kps: Vec<_> = all_keypaths
4875 .iter()
4876 .filter(|akp| {
4877 akp.root_type_id() == TypeId::of::<Product>()
4878 && akp.value_type_id() == TypeId::of::<f64>()
4879 })
4880 .collect();
4881
4882 assert_eq!(product_f64_kps.len(), 1);
4883 assert_eq!(
4884 product_f64_kps[0].get_as::<Product, f64>(&product),
4885 Some(Some(&19.99))
4886 );
4887 }
4888
4889 #[test]
4890 fn test_akp_filter_by_arc_root_type() {
4891 use std::any::TypeId;
4892 use std::sync::Arc;
4893
4894 #[derive(Debug)]
4895 struct User {
4896 name: String,
4897 }
4898
4899 #[derive(Debug)]
4900 struct Product {
4901 title: String,
4902 }
4903
4904 let user = User {
4905 name: "Frank".to_string(),
4906 };
4907 let product = Product {
4908 title: "Laptop".to_string(),
4909 };
4910
4911 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4913 let product_title_kp = KpType::new(
4914 |p: &Product| Some(&p.title),
4915 |p: &mut Product| Some(&mut p.title),
4916 );
4917
4918 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4920 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4921
4922 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4923
4924 let arc_user_kps: Vec<_> = all_keypaths
4926 .iter()
4927 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4928 .collect();
4929
4930 assert_eq!(arc_user_kps.len(), 1);
4931
4932 let arc_user = Arc::new(user);
4934 assert_eq!(
4935 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4936 Some(Some(&"Frank".to_string()))
4937 );
4938
4939 let arc_product_kps: Vec<_> = all_keypaths
4941 .iter()
4942 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4943 .collect();
4944
4945 assert_eq!(arc_product_kps.len(), 1);
4946
4947 let arc_product = Arc::new(product);
4949 assert_eq!(
4950 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4951 Some(Some(&"Laptop".to_string()))
4952 );
4953 }
4954
4955 #[test]
4956 fn test_akp_filter_by_box_root_type() {
4957 use std::any::TypeId;
4958
4959 #[derive(Debug)]
4960 struct Config {
4961 setting: String,
4962 }
4963
4964 let config = Config {
4965 setting: "enabled".to_string(),
4966 };
4967
4968 let config_kp1 = KpType::new(
4970 |c: &Config| Some(&c.setting),
4971 |c: &mut Config| Some(&mut c.setting),
4972 );
4973 let config_kp2 = KpType::new(
4974 |c: &Config| Some(&c.setting),
4975 |c: &mut Config| Some(&mut c.setting),
4976 );
4977
4978 let regular_akp = AKp::new(config_kp1);
4980 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4981
4982 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4983
4984 let config_kps: Vec<_> = all_keypaths
4986 .iter()
4987 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4988 .collect();
4989
4990 assert_eq!(config_kps.len(), 1);
4991 assert_eq!(
4992 config_kps[0].get_as::<Config, String>(&config),
4993 Some(Some(&"enabled".to_string()))
4994 );
4995
4996 let box_config_kps: Vec<_> = all_keypaths
4998 .iter()
4999 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
5000 .collect();
5001
5002 assert_eq!(box_config_kps.len(), 1);
5003
5004 let box_config = Box::new(Config {
5006 setting: "enabled".to_string(),
5007 });
5008 assert_eq!(
5009 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
5010 Some(Some(&"enabled".to_string()))
5011 );
5012 }
5013
5014 #[test]
5015 fn test_mixed_collection_type_filtering() {
5016 use std::any::TypeId;
5017 use std::sync::Arc;
5018
5019 #[derive(Debug)]
5020 struct User {
5021 name: String,
5022 email: String,
5023 }
5024
5025 #[derive(Debug)]
5026 struct Product {
5027 title: String,
5028 sku: String,
5029 }
5030
5031 let user = User {
5032 name: "Grace".to_string(),
5033 email: "grace@example.com".to_string(),
5034 };
5035
5036 let product = Product {
5037 title: "Widget".to_string(),
5038 sku: "WID-001".to_string(),
5039 };
5040
5041 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
5043 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
5044 let user_email_kp1 =
5045 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
5046 let user_email_kp2 =
5047 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
5048 let product_title_kp = KpType::new(
5049 |p: &Product| Some(&p.title),
5050 |p: &mut Product| Some(&mut p.title),
5051 );
5052 let product_sku_kp = KpType::new(
5053 |p: &Product| Some(&p.sku),
5054 |p: &mut Product| Some(&mut p.sku),
5055 );
5056
5057 let all_keypaths: Vec<AKp> = vec![
5058 AKp::new(user_name_kp1),
5059 AKp::new(user_email_kp1),
5060 AKp::new(product_title_kp),
5061 AKp::new(product_sku_kp),
5062 AKp::new(user_name_kp2).for_arc::<User>(),
5063 AKp::new(user_email_kp2).for_box::<User>(),
5064 ];
5065
5066 let string_value_kps: Vec<_> = all_keypaths
5068 .iter()
5069 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
5070 .collect();
5071
5072 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
5076 .iter()
5077 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
5078 .collect();
5079
5080 assert_eq!(user_root_kps.len(), 2);
5081
5082 let arc_user_kps: Vec<_> = all_keypaths
5084 .iter()
5085 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
5086 .collect();
5087
5088 assert_eq!(arc_user_kps.len(), 1);
5089
5090 let box_user_kps: Vec<_> = all_keypaths
5092 .iter()
5093 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
5094 .collect();
5095
5096 assert_eq!(box_user_kps.len(), 1);
5097
5098 let product_kps: Vec<_> = all_keypaths
5100 .iter()
5101 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
5102 .collect();
5103
5104 assert_eq!(product_kps.len(), 2);
5105
5106 let user_value = user_root_kps[0].get_as::<User, String>(&user);
5108 assert!(user_value.is_some());
5109 assert!(user_value.unwrap().is_some());
5110 }
5111
5112 #[test]
5117 fn test_kp_with_pin() {
5118 use std::pin::Pin;
5119
5120 #[derive(Debug)]
5124 struct SelfReferential {
5125 value: String,
5126 ptr_to_value: *const String, }
5128
5129 impl SelfReferential {
5130 fn new(s: String) -> Self {
5131 let mut sr = Self {
5132 value: s,
5133 ptr_to_value: std::ptr::null(),
5134 };
5135 sr.ptr_to_value = &sr.value as *const String;
5137 sr
5138 }
5139
5140 fn get_value(&self) -> &str {
5141 &self.value
5142 }
5143 }
5144
5145 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
5147 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
5148
5149 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
5151 |p: &Pin<Box<SelfReferential>>| {
5152 Some(&p.as_ref().get_ref().value)
5154 },
5155 |p: &mut Pin<Box<SelfReferential>>| {
5156 unsafe {
5159 let sr = Pin::get_unchecked_mut(p.as_mut());
5160 Some(&mut sr.value)
5161 }
5162 },
5163 );
5164
5165 let result = kp.get(&pinned);
5167 assert_eq!(result, Some(&"pinned_data".to_string()));
5168
5169 assert_eq!(pinned.get_value(), "pinned_data");
5171 }
5172
5173 #[test]
5174 fn test_kp_with_pin_arc() {
5175 use std::pin::Pin;
5176 use std::sync::Arc;
5177
5178 struct AsyncState {
5179 status: String,
5180 data: Vec<i32>,
5181 }
5182
5183 let state = AsyncState {
5185 status: "ready".to_string(),
5186 data: vec![1, 2, 3, 4, 5],
5187 };
5188
5189 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
5190
5191 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
5193 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
5194 |_: &mut Pin<Arc<AsyncState>>| {
5195 None::<&mut String>
5197 },
5198 );
5199
5200 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
5202 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
5203 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
5204 );
5205
5206 let status = status_kp.get(&pinned_arc);
5207 assert_eq!(status, Some(&"ready".to_string()));
5208
5209 let data = data_kp.get(&pinned_arc);
5210 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
5211 }
5212
5213 #[test]
5214 fn test_kp_with_maybe_uninit() {
5215 use std::mem::MaybeUninit;
5216
5217 struct Config {
5221 name: MaybeUninit<String>,
5222 value: MaybeUninit<i32>,
5223 initialized: bool,
5224 }
5225
5226 impl Config {
5227 fn new_uninit() -> Self {
5228 Self {
5229 name: MaybeUninit::uninit(),
5230 value: MaybeUninit::uninit(),
5231 initialized: false,
5232 }
5233 }
5234
5235 fn init(&mut self, name: String, value: i32) {
5236 self.name.write(name);
5237 self.value.write(value);
5238 self.initialized = true;
5239 }
5240
5241 fn get_name(&self) -> Option<&String> {
5242 if self.initialized {
5243 unsafe { Some(self.name.assume_init_ref()) }
5244 } else {
5245 None
5246 }
5247 }
5248
5249 fn get_value(&self) -> Option<&i32> {
5250 if self.initialized {
5251 unsafe { Some(self.value.assume_init_ref()) }
5252 } else {
5253 None
5254 }
5255 }
5256 }
5257
5258 let name_kp: KpType<Config, String> = Kp::new(
5260 |c: &Config| c.get_name(),
5261 |c: &mut Config| {
5262 if c.initialized {
5263 unsafe { Some(c.name.assume_init_mut()) }
5264 } else {
5265 None
5266 }
5267 },
5268 );
5269
5270 let value_kp: KpType<Config, i32> = Kp::new(
5271 |c: &Config| c.get_value(),
5272 |c: &mut Config| {
5273 if c.initialized {
5274 unsafe { Some(c.value.assume_init_mut()) }
5275 } else {
5276 None
5277 }
5278 },
5279 );
5280
5281 let uninit_config = Config::new_uninit();
5283 assert_eq!(name_kp.get(&uninit_config), None);
5284 assert_eq!(value_kp.get(&uninit_config), None);
5285
5286 let mut init_config = Config::new_uninit();
5288 init_config.init("test_config".to_string(), 42);
5289
5290 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
5291 assert_eq!(value_kp.get(&init_config), Some(&42));
5292
5293 if let Some(val) = value_kp.get_mut(&mut init_config) {
5295 *val = 100;
5296 }
5297
5298 assert_eq!(value_kp.get(&init_config), Some(&100));
5299 }
5300
5301 #[test]
5302 fn test_kp_with_weak() {
5303 use std::sync::{Arc, Weak};
5304
5305 #[derive(Debug, Clone)]
5309 struct Node {
5310 value: i32,
5311 }
5312
5313 struct NodeWithParent {
5314 value: i32,
5315 parent: Option<Arc<Node>>, }
5317
5318 let parent = Arc::new(Node { value: 100 });
5319
5320 let child = NodeWithParent {
5321 value: 42,
5322 parent: Some(parent.clone()),
5323 };
5324
5325 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
5327 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
5328 |_: &mut NodeWithParent| None::<&mut i32>,
5329 );
5330
5331 let parent_val = parent_value_kp.get(&child);
5333 assert_eq!(parent_val, Some(&100));
5334 }
5335
5336 #[test]
5337 fn test_kp_with_rc_weak() {
5338 use std::rc::Rc;
5339
5340 struct TreeNode {
5343 value: String,
5344 parent: Option<Rc<TreeNode>>, }
5346
5347 let root = Rc::new(TreeNode {
5348 value: "root".to_string(),
5349 parent: None,
5350 });
5351
5352 let child1 = TreeNode {
5353 value: "child1".to_string(),
5354 parent: Some(root.clone()),
5355 };
5356
5357 let child2 = TreeNode {
5358 value: "child2".to_string(),
5359 parent: Some(root.clone()),
5360 };
5361
5362 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
5364 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
5365 |_: &mut TreeNode| None::<&mut String>,
5366 );
5367
5368 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
5370 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
5371
5372 assert_eq!(parent_name_kp.get(&root), None);
5374 }
5375
5376 #[test]
5377 fn test_kp_with_complex_weak_structure() {
5378 use std::sync::Arc;
5379
5380 struct Cache {
5383 data: String,
5384 backup: Option<Arc<Cache>>, }
5386
5387 let primary = Arc::new(Cache {
5388 data: "primary_data".to_string(),
5389 backup: None,
5390 });
5391
5392 let backup = Arc::new(Cache {
5393 data: "backup_data".to_string(),
5394 backup: Some(primary.clone()),
5395 });
5396
5397 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
5399 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
5400 |_: &mut Arc<Cache>| None::<&mut String>,
5401 );
5402
5403 let data = backup_data_kp.get(&backup);
5405 assert_eq!(data, Some(&"primary_data".to_string()));
5406
5407 let no_backup = backup_data_kp.get(&primary);
5409 assert_eq!(no_backup, None);
5410 }
5411
5412 #[test]
5413 fn test_kp_chain_with_pin_and_arc() {
5414 use std::pin::Pin;
5415 use std::sync::Arc;
5416
5417 struct Outer {
5420 inner: Arc<Inner>,
5421 }
5422
5423 struct Inner {
5424 value: String,
5425 }
5426
5427 let outer = Outer {
5428 inner: Arc::new(Inner {
5429 value: "nested_value".to_string(),
5430 }),
5431 };
5432
5433 let pinned_outer = Box::pin(outer);
5434
5435 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
5437 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
5438 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
5439 );
5440
5441 let to_value: KpType<Arc<Inner>, String> = Kp::new(
5443 |a: &Arc<Inner>| Some(&a.value),
5444 |_: &mut Arc<Inner>| None::<&mut String>,
5445 );
5446
5447 let chained = to_inner.then(to_value);
5449
5450 let result = chained.get(&pinned_outer);
5451 assert_eq!(result, Some(&"nested_value".to_string()));
5452 }
5453
5454 #[test]
5455 fn test_kp_with_maybe_uninit_array() {
5456 use std::mem::MaybeUninit;
5457
5458 struct Buffer {
5462 data: [MaybeUninit<u8>; 10],
5463 len: usize,
5464 }
5465
5466 impl Buffer {
5467 fn new() -> Self {
5468 Self {
5469 data: unsafe { MaybeUninit::uninit().assume_init() },
5470 len: 0,
5471 }
5472 }
5473
5474 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
5475 if self.len >= self.data.len() {
5476 return Err("Buffer full");
5477 }
5478 self.data[self.len].write(byte);
5479 self.len += 1;
5480 Ok(())
5481 }
5482
5483 fn get(&self, idx: usize) -> Option<&u8> {
5484 if idx < self.len {
5485 unsafe { Some(self.data[idx].assume_init_ref()) }
5486 } else {
5487 None
5488 }
5489 }
5490
5491 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
5492 if idx < self.len {
5493 unsafe { Some(self.data[idx].assume_init_mut()) }
5494 } else {
5495 None
5496 }
5497 }
5498 }
5499
5500 let len_kp: KpType<Buffer, usize> =
5502 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
5503
5504 let mut buffer = Buffer::new();
5505
5506 assert_eq!(len_kp.get(&buffer), Some(&0));
5508
5509 buffer.push(1).unwrap();
5511 buffer.push(2).unwrap();
5512 buffer.push(3).unwrap();
5513
5514 assert_eq!(len_kp.get(&buffer), Some(&3));
5516
5517 assert_eq!(buffer.get(0), Some(&1));
5519 assert_eq!(buffer.get(1), Some(&2));
5520 assert_eq!(buffer.get(2), Some(&3));
5521 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
5525 *elem = 20;
5526 }
5527 assert_eq!(buffer.get(1), Some(&20));
5528 }
5529
5530 #[test]
5531 fn test_kp_then_lock_deep_structs() {
5532 use std::sync::{Arc, Mutex};
5533
5534 #[derive(Clone)]
5535 struct Root {
5536 guard: Arc<Mutex<Level1>>,
5537 }
5538 #[derive(Clone)]
5539 struct Level1 {
5540 name: String,
5541 nested: Level2,
5542 }
5543 #[derive(Clone)]
5544 struct Level2 {
5545 count: i32,
5546 }
5547
5548 let root = Root {
5549 guard: Arc::new(Mutex::new(Level1 {
5550 name: "deep".to_string(),
5551 nested: Level2 { count: 42 },
5552 })),
5553 };
5554
5555 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
5556 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
5557
5558 let lock_kp = {
5559 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> = Kp::new(
5560 |g: &Arc<Mutex<Level1>>| Some(g),
5561 |g: &mut Arc<Mutex<Level1>>| Some(g),
5562 );
5563 let next: KpType<Level1, Level1> =
5564 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5565 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5566 };
5567
5568 let chained = kp_to_guard.then_lock(lock_kp);
5569 let level1 = chained.get(&root);
5570 assert!(level1.is_some());
5571 assert_eq!(level1.unwrap().name, "deep");
5572 assert_eq!(level1.unwrap().nested.count, 42);
5573
5574 let mut_root = &mut root.clone();
5575 let mut_level1 = chained.get_mut(mut_root);
5576 assert!(mut_level1.is_some());
5577 mut_level1.unwrap().nested.count = 99;
5578 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
5579 }
5580
5581 #[test]
5582 fn test_kp_then_lock_with_enum() {
5583 use std::sync::{Arc, Mutex};
5584
5585 #[derive(Clone)]
5586 enum Message {
5587 Request(LevelA),
5588 Response(i32),
5589 }
5590 #[derive(Clone)]
5591 struct LevelA {
5592 data: Arc<Mutex<i32>>,
5593 }
5594
5595 struct RootWithEnum {
5596 msg: Arc<Mutex<Message>>,
5597 }
5598
5599 let root = RootWithEnum {
5600 msg: Arc::new(Mutex::new(Message::Request(LevelA {
5601 data: Arc::new(Mutex::new(100)),
5602 }))),
5603 };
5604
5605 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> = Kp::new(
5606 |r: &RootWithEnum| Some(&r.msg),
5607 |r: &mut RootWithEnum| Some(&mut r.msg),
5608 );
5609
5610 let lock_kp_msg = {
5611 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> = Kp::new(
5612 |m: &Arc<Mutex<Message>>| Some(m),
5613 |m: &mut Arc<Mutex<Message>>| Some(m),
5614 );
5615 let next: KpType<Message, Message> =
5616 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
5617 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5618 };
5619
5620 let chained = kp_msg.then_lock(lock_kp_msg);
5621 let msg = chained.get(&root);
5622 assert!(msg.is_some());
5623 match msg.unwrap() {
5624 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
5625 Message::Response(_) => panic!("expected Request"),
5626 }
5627 }
5628
5629 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5630 #[tokio::test]
5631 async fn test_kp_then_async_deep_chain() {
5632 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5633 use std::sync::Arc;
5634
5635 #[derive(Clone)]
5636 struct Root {
5637 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
5638 }
5639 #[derive(Clone)]
5640 struct Level1 {
5641 value: i32,
5642 }
5643
5644 let root = Root {
5645 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
5646 };
5647
5648 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
5649 |r: &Root| Some(&r.tokio_guard),
5650 |r: &mut Root| Some(&mut r.tokio_guard),
5651 );
5652
5653 let async_kp = {
5654 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
5655 Kp::new(
5656 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
5657 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
5658 );
5659 let next: KpType<Level1, Level1> =
5660 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5661 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5662 };
5663
5664 let chained = kp_to_guard.then_async(async_kp);
5665 let level1 = chained.get(&root).await;
5666 assert!(level1.is_some());
5667 assert_eq!(level1.unwrap().value, 7);
5668 }
5669
5670 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5673 #[tokio::test]
5674 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
5675 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5676 use crate::lock::{ArcMutexAccess, LockKp};
5677 use std::sync::{Arc, Mutex};
5678
5679 #[derive(Clone)]
5681 struct Root {
5682 sync_mutex: Arc<Mutex<Level1>>,
5683 }
5684 #[derive(Clone)]
5686 struct Level1 {
5687 inner: Level2,
5688 }
5689 #[derive(Clone)]
5691 struct Level2 {
5692 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
5693 }
5694 #[derive(Clone)]
5696 struct Level3 {
5697 leaf: i32,
5698 }
5699
5700 let mut root = Root {
5701 sync_mutex: Arc::new(Mutex::new(Level1 {
5702 inner: Level2 {
5703 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
5704 },
5705 })),
5706 };
5707
5708 let identity_l1: KpType<Level1, Level1> =
5710 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5711 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
5712 |r: &Root| Some(&r.sync_mutex),
5713 |r: &mut Root| Some(&mut r.sync_mutex),
5714 );
5715 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
5716
5717 let kp_l1_inner: KpType<Level1, Level2> = Kp::new(
5719 |l: &Level1| Some(&l.inner),
5720 |l: &mut Level1| Some(&mut l.inner),
5721 );
5722
5723 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
5725 |l: &Level2| Some(&l.tokio_mutex),
5726 |l: &mut Level2| Some(&mut l.tokio_mutex),
5727 );
5728
5729 let async_l3 = {
5731 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
5732 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
5733 let next: KpType<Level3, Level3> =
5734 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
5735 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5736 };
5737
5738 let kp_l3_leaf: KpType<Level3, i32> = Kp::new(
5740 |l: &Level3| Some(&l.leaf),
5741 |l: &mut Level3| Some(&mut l.leaf),
5742 );
5743
5744 let step1 = lock_root_to_l1.then(kp_l1_inner);
5746 let step2 = step1.then(kp_l2_tokio);
5747 let step3 = step2.then_async(async_l3);
5748 let deep_chain = step3.then(kp_l3_leaf);
5749
5750 let leaf = deep_chain.get(&root).await;
5752 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5753 assert_eq!(leaf, Some(&100));
5754
5755 let mut root_mut = root.clone();
5757 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5758 assert!(leaf_mut.is_some());
5759 *leaf_mut.unwrap() = 99;
5760
5761 let leaf_after = deep_chain.get(&root_mut).await;
5763 assert_eq!(leaf_after, Some(&99));
5764 }
5765}