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 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 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 let first = self;
1255 let second = lock_kp;
1256
1257 crate::lock::KpThenLockKp {
1258 first: first,
1259 second: second,
1260 _p: std::marker::PhantomData,
1261 }
1262 }
1263
1264 #[cfg(feature = "pin_project")]
1265 fn then_pin_future<Struct, Output, L>(
1266 self,
1267 pin_fut: L,
1268 ) -> crate::pin::KpThenPinFuture<R, Struct, Output, Root, MutRoot, Value, MutValue, Self, L>
1269 where
1270 Struct: Unpin + 'static,
1271 Output: 'static,
1272 Value: std::borrow::Borrow<Struct>,
1273 MutValue: std::borrow::BorrowMut<Struct>,
1274 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
1275 {
1276 let first = self;
1277 let second = pin_fut;
1278
1279 crate::pin::KpThenPinFuture {
1280 first: first,
1281 second: second,
1282 _p: std::marker::PhantomData,
1283 }
1284 }
1285
1286 fn then_async<AsyncKp>(
1287 self,
1288 async_kp: AsyncKp,
1289 ) -> crate::async_lock::KpThenAsyncKeyPath<
1290 R,
1291 V,
1292 <AsyncKp::Value as KeyPathValueTarget>::Target,
1293 Root,
1294 Value,
1295 AsyncKp::Value,
1296 MutRoot,
1297 MutValue,
1298 AsyncKp::MutValue,
1299 Self,
1300 AsyncKp,
1301 >
1302 where
1303 Value: std::borrow::Borrow<V>,
1304 MutValue: std::borrow::BorrowMut<V>,
1305 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
1306 AsyncKp::Value: KeyPathValueTarget
1307 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1308 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
1309 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
1310 {
1311 let first = self;
1312 let second = async_kp;
1313
1314 crate::async_lock::KpThenAsyncKeyPath {
1315 first: first,
1316 second: second,
1317 _p: std::marker::PhantomData,
1318 }
1319 }
1320}
1321
1322pub trait AccessorTrait<R, V, Root, Value, MutRoot, MutValue, G, S> {
1323 fn get_optional(&self, root: Option<Root>) -> Option<Value>;
1325 fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue>;
1331 fn get_or_else<F>(&self, root: Root, f: F) -> Value
1337 where
1338 F: FnOnce() -> Value;
1339 #[inline]
1345 fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
1346 where
1347 F: FnOnce() -> MutValue;
1348 }
1352
1353pub trait CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1354where
1355 Root: std::borrow::Borrow<R>,
1356 Value: std::borrow::Borrow<V>,
1357 MutRoot: std::borrow::BorrowMut<R>,
1358 MutValue: std::borrow::BorrowMut<V>,
1359 G: Fn(Root) -> Option<Value>,
1360 S: Fn(MutRoot) -> Option<MutValue>,
1361{
1362 fn for_arc<'b>(
1363 &self,
1364 ) -> Kp<
1365 std::sync::Arc<R>,
1366 V,
1367 std::sync::Arc<R>,
1368 Value,
1369 std::sync::Arc<R>,
1370 MutValue,
1371 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1372 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1373 >
1374 where
1375 R: 'b,
1376 V: 'b,
1377 Root: for<'a> From<&'a R>,
1378 MutRoot: for<'a> From<&'a mut R>;
1379
1380 fn for_box<'a>(
1381 &self,
1382 ) -> Kp<
1383 Box<R>,
1384 V,
1385 Box<R>,
1386 Value,
1387 Box<R>,
1388 MutValue,
1389 impl Fn(Box<R>) -> Option<Value>,
1390 impl Fn(Box<R>) -> Option<MutValue>,
1391 >
1392 where
1393 R: 'a,
1394 V: 'a,
1395 Root: for<'b> From<&'b R>,
1396 MutRoot: for<'b> From<&'b mut R>;
1397
1398 fn into_set(self) -> impl Fn(MutRoot) -> Option<MutValue>;
1400
1401 fn into_get(self) -> impl Fn(Root) -> Option<Value>;
1403}
1404
1405pub trait HofTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
1406 KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1407where
1408 Root: std::borrow::Borrow<R>,
1409 Value: std::borrow::Borrow<V>,
1410 MutRoot: std::borrow::BorrowMut<R>,
1411 MutValue: std::borrow::BorrowMut<V>,
1412 G: Fn(Root) -> Option<Value>,
1413 S: Fn(MutRoot) -> Option<MutValue>,
1414{
1415 fn map<MappedValue, F>(
1465 &self,
1466 mapper: F,
1467 ) -> Kp<
1468 R,
1469 MappedValue,
1470 Root,
1471 MappedValue,
1472 MutRoot,
1473 MappedValue,
1474 impl Fn(Root) -> Option<MappedValue> + '_,
1475 impl Fn(MutRoot) -> Option<MappedValue> + '_,
1476 >
1477 where
1478 F: Fn(&V) -> MappedValue + Copy + 'static,
1479 MappedValue: 'static,
1480 {
1481 Kp::new(
1482 move |root: Root| {
1483 self.get(root).map(|value| {
1484 let v: &V = value.borrow();
1485 mapper(v)
1486 })
1487 },
1488 move |root: MutRoot| {
1489 self.get_mut(root).map(|value| {
1490 let v: &V = value.borrow();
1491 mapper(v)
1492 })
1493 },
1494 )
1495 }
1496
1497 fn filter<F>(
1499 &self,
1500 predicate: F,
1501 ) -> Kp<
1502 R,
1503 V,
1504 Root,
1505 Value,
1506 MutRoot,
1507 MutValue,
1508 impl Fn(Root) -> Option<Value> + '_,
1509 impl Fn(MutRoot) -> Option<MutValue> + '_,
1510 >
1511 where
1512 F: Fn(&V) -> bool + Copy + 'static,
1513 {
1514 Kp::new(
1515 move |root: Root| {
1516 self.get(root).filter(|value| {
1517 let v: &V = value.borrow();
1518 predicate(v)
1519 })
1520 },
1521 move |root: MutRoot| {
1522 self.get_mut(root).filter(|value| {
1523 let v: &V = value.borrow();
1524 predicate(v)
1525 })
1526 },
1527 )
1528 }
1529
1530 fn filter_map<MappedValue, F>(
1532 &self,
1533 mapper: F,
1534 ) -> Kp<
1535 R,
1536 MappedValue,
1537 Root,
1538 MappedValue,
1539 MutRoot,
1540 MappedValue,
1541 impl Fn(Root) -> Option<MappedValue> + '_,
1542 impl Fn(MutRoot) -> Option<MappedValue> + '_,
1543 >
1544 where
1545 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1546 {
1547 Kp::new(
1548 move |root: Root| {
1549 self.get(root).and_then(|value| {
1550 let v: &V = value.borrow();
1551 mapper(v)
1552 })
1553 },
1554 move |root: MutRoot| {
1555 self.get_mut(root).and_then(|value| {
1556 let v: &V = value.borrow();
1557 mapper(v)
1558 })
1559 },
1560 )
1561 }
1562
1563 fn inspect<F>(
1565 &self,
1566 inspector: F,
1567 ) -> Kp<
1568 R,
1569 V,
1570 Root,
1571 Value,
1572 MutRoot,
1573 MutValue,
1574 impl Fn(Root) -> Option<Value> + '_,
1575 impl Fn(MutRoot) -> Option<MutValue> + '_,
1576 >
1577 where
1578 F: Fn(&V) + Copy + 'static,
1579 {
1580 Kp::new(
1581 move |root: Root| {
1582 self.get(root).map(|value| {
1583 let v: &V = value.borrow();
1584 inspector(v);
1585 value
1586 })
1587 },
1588 move |root: MutRoot| {
1589 self.get_mut(root).map(|value| {
1590 let v: &V = value.borrow();
1591 inspector(v);
1592 value
1593 })
1594 },
1595 )
1596 }
1597
1598 fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item> + '_
1600 where
1601 F: Fn(&V) -> I + 'static,
1602 I: IntoIterator<Item = Item>,
1603 {
1604 move |root: Root| {
1605 self.get(root)
1606 .map(|value| {
1607 let v: &V = value.borrow();
1608 mapper(v).into_iter().collect()
1609 })
1610 .unwrap_or_else(Vec::new)
1611 }
1612 }
1613
1614 fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc + '_
1616 where
1617 F: Fn(Acc, &V) -> Acc + 'static,
1618 Acc: Copy + 'static,
1619 {
1620 move |root: Root| {
1621 self.get(root)
1622 .map(|value| {
1623 let v: &V = value.borrow();
1624 folder(init, v)
1625 })
1626 .unwrap_or(init)
1627 }
1628 }
1629
1630 fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
1632 where
1633 F: Fn(&V) -> bool + 'static,
1634 {
1635 move |root: Root| {
1636 self.get(root)
1637 .map(|value| {
1638 let v: &V = value.borrow();
1639 predicate(v)
1640 })
1641 .unwrap_or(false)
1642 }
1643 }
1644
1645 fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
1647 where
1648 F: Fn(&V) -> bool + 'static,
1649 {
1650 move |root: Root| {
1651 self.get(root)
1652 .map(|value| {
1653 let v: &V = value.borrow();
1654 predicate(v)
1655 })
1656 .unwrap_or(true)
1657 }
1658 }
1659
1660 fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize> + '_
1662 where
1663 F: Fn(&V) -> usize + 'static,
1664 {
1665 move |root: Root| {
1666 self.get(root).map(|value| {
1667 let v: &V = value.borrow();
1668 counter(v)
1669 })
1670 }
1671 }
1672
1673 fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item> + '_
1675 where
1676 F: Fn(&V) -> Option<Item> + 'static,
1677 {
1678 move |root: Root| {
1679 self.get(root).and_then(|value| {
1680 let v: &V = value.borrow();
1681 finder(v)
1682 })
1683 }
1684 }
1685
1686 fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output> + '_
1688 where
1689 F: Fn(&V, usize) -> Output + 'static,
1690 {
1691 move |root: Root| {
1692 self.get(root).map(|value| {
1693 let v: &V = value.borrow();
1694 taker(v, n)
1695 })
1696 }
1697 }
1698
1699 fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output> + '_
1701 where
1702 F: Fn(&V, usize) -> Output + 'static,
1703 {
1704 move |root: Root| {
1705 self.get(root).map(|value| {
1706 let v: &V = value.borrow();
1707 skipper(v, n)
1708 })
1709 }
1710 }
1711
1712 fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output> + '_
1714 where
1715 F: Fn(&V) -> Output + 'static,
1716 {
1717 move |root: Root| {
1718 self.get(root).map(|value| {
1719 let v: &V = value.borrow();
1720 partitioner(v)
1721 })
1722 }
1723 }
1724
1725 fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item> + '_
1727 where
1728 F: Fn(&V) -> Option<Item> + 'static,
1729 {
1730 move |root: Root| {
1731 self.get(root).and_then(|value| {
1732 let v: &V = value.borrow();
1733 min_fn(v)
1734 })
1735 }
1736 }
1737
1738 fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item> + '_
1740 where
1741 F: Fn(&V) -> Option<Item> + 'static,
1742 {
1743 move |root: Root| {
1744 self.get(root).and_then(|value| {
1745 let v: &V = value.borrow();
1746 max_fn(v)
1747 })
1748 }
1749 }
1750
1751 fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum> + '_
1753 where
1754 F: Fn(&V) -> Sum + 'static,
1755 {
1756 move |root: Root| {
1757 self.get(root).map(|value| {
1758 let v: &V = value.borrow();
1759 sum_fn(v)
1760 })
1761 }
1762 }
1763
1764 }
1815
1816impl<R, V, Root, Value, MutRoot, MutValue, G, S> KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1817 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1818where
1819 Root: std::borrow::Borrow<R>,
1820 Value: std::borrow::Borrow<V>,
1821 MutRoot: std::borrow::BorrowMut<R>,
1822 MutValue: std::borrow::BorrowMut<V>,
1823 G: Fn(Root) -> Option<Value>,
1824 S: Fn(MutRoot) -> Option<MutValue>,
1825{
1826 fn then<SV, SubValue, MutSubValue, G2, S2>(
1827 self,
1828 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1829 ) -> Kp<
1830 R,
1831 SV,
1832 Root,
1833 SubValue,
1834 MutRoot,
1835 MutSubValue,
1836 impl Fn(Root) -> Option<SubValue>,
1837 impl Fn(MutRoot) -> Option<MutSubValue>,
1838 >
1839 where
1840 SubValue: std::borrow::Borrow<SV>,
1841 MutSubValue: std::borrow::BorrowMut<SV>,
1842 G2: Fn(Value) -> Option<SubValue>,
1843 S2: Fn(MutValue) -> Option<MutSubValue>,
1844 {
1845 let first_get = self.get;
1846 let first_set = self.set;
1847 let second_get = next.get;
1848 let second_set = next.set;
1849
1850 Kp::new(
1851 move |root: Root| first_get(root).and_then(|value| second_get(value)),
1852 move |root: MutRoot| first_set(root).and_then(|value| second_set(value)),
1853 )
1854 }
1855
1856 fn get(&self, root: Root) -> Option<Value> {
1857 (self.get)(root)
1858 }
1859
1860 fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1861 (self.set)(root)
1862 }
1863}
1864
1865impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1866 CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1867 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1868where
1869 Root: std::borrow::Borrow<R>,
1870 Value: std::borrow::Borrow<V>,
1871 MutRoot: std::borrow::BorrowMut<R>,
1872 MutValue: std::borrow::BorrowMut<V>,
1873 G: Fn(Root) -> Option<Value>,
1874 S: Fn(MutRoot) -> Option<MutValue>,
1875{
1876 fn for_arc<'b>(
1877 &self,
1878 ) -> Kp<
1879 std::sync::Arc<R>,
1880 V,
1881 std::sync::Arc<R>,
1882 Value,
1883 std::sync::Arc<R>,
1884 MutValue,
1885 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1886 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1887 >
1888 where
1889 R: 'b,
1890 V: 'b,
1891 Root: for<'a> From<&'a R>,
1892 MutRoot: for<'a> From<&'a mut R>,
1893 {
1894 Kp::new(
1895 move |arc_root: std::sync::Arc<R>| {
1896 let r_ref: &R = &*arc_root;
1897 (self.get)(Root::from(r_ref))
1898 },
1899 move |mut arc_root: std::sync::Arc<R>| {
1900 std::sync::Arc::get_mut(&mut arc_root)
1902 .and_then(|r_mut| (self.set)(MutRoot::from(r_mut)))
1903 },
1904 )
1905 }
1906
1907 fn for_box<'a>(
1908 &self,
1909 ) -> Kp<
1910 Box<R>,
1911 V,
1912 Box<R>,
1913 Value,
1914 Box<R>,
1915 MutValue,
1916 impl Fn(Box<R>) -> Option<Value>,
1917 impl Fn(Box<R>) -> Option<MutValue>,
1918 >
1919 where
1920 R: 'a,
1921 V: 'a,
1922 Root: for<'b> From<&'b R>,
1923 MutRoot: for<'b> From<&'b mut R>,
1924 {
1925 Kp::new(
1926 move |r: Box<R>| {
1927 let r_ref: &R = r.as_ref();
1928 (self.get)(Root::from(r_ref))
1929 },
1930 move |mut r: Box<R>| {
1931 (self.set)(MutRoot::from(r.as_mut()))
1933 },
1934 )
1935 }
1936
1937 #[inline]
1939 fn into_set(self) -> impl Fn(MutRoot) -> Option<MutValue> {
1940 self.set
1941 }
1942
1943 #[inline]
1945 fn into_get(self) -> impl Fn(Root) -> Option<Value> {
1946 self.get
1947 }
1948}
1949
1950impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1951 HofTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1952 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1953where
1954 Root: std::borrow::Borrow<R>,
1955 Value: std::borrow::Borrow<V>,
1956 MutRoot: std::borrow::BorrowMut<R>,
1957 MutValue: std::borrow::BorrowMut<V>,
1958 G: Fn(Root) -> Option<Value>,
1959 S: Fn(MutRoot) -> Option<MutValue>,
1960{
1961}
1962
1963impl<R, V, Root, Value, MutRoot, MutValue, G, S>
1964 AccessorTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
1965 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1966where
1967 Root: std::borrow::Borrow<R>,
1968 Value: std::borrow::Borrow<V>,
1969 MutRoot: std::borrow::BorrowMut<R>,
1970 MutValue: std::borrow::BorrowMut<V>,
1971 G: Fn(Root) -> Option<Value>,
1972 S: Fn(MutRoot) -> Option<MutValue>,
1973{
1974 #[inline]
1976 fn get_optional(&self, root: Option<Root>) -> Option<Value> {
1977 root.and_then(|r| (self.get)(r))
1978 }
1979
1980 #[inline]
1982 fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue> {
1983 root.and_then(|r| (self.set)(r))
1984 }
1985
1986 #[inline]
1988 fn get_or_else<F>(&self, root: Root, f: F) -> Value
1989 where
1990 F: FnOnce() -> Value,
1991 {
1992 (self.get)(root).unwrap_or_else(f)
1993 }
1994
1995 #[inline]
1997 fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
1998 where
1999 F: FnOnce() -> MutValue,
2000 {
2001 (self.set)(root).unwrap_or_else(f)
2002 }
2003}
2004
2005#[derive(Clone)]
2018pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2019where
2020 Root: std::borrow::Borrow<R>,
2021 MutRoot: std::borrow::BorrowMut<R>,
2022 MutValue: std::borrow::BorrowMut<V>,
2023 G: Fn(Root) -> Option<Value>,
2024 S: Fn(MutRoot) -> Option<MutValue>,
2025{
2026 pub get: G,
2028 pub set: S,
2030 pub _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
2031}
2032
2033#[inline]
2035pub fn constrain_get<R, V, F>(f: F) -> F
2036where
2037 F: for<'b> Fn(&'b R) -> Option<&'b V>,
2038{
2039 f
2040}
2041
2042#[inline]
2044pub fn constrain_set<R, V, F>(f: F) -> F
2045where
2046 F: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
2047{
2048 f
2049}
2050
2051impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2052where
2053 Root: std::borrow::Borrow<R>,
2054 Value: std::borrow::Borrow<V>,
2055 MutRoot: std::borrow::BorrowMut<R>,
2056 MutValue: std::borrow::BorrowMut<V>,
2057 G: Fn(Root) -> Option<Value>,
2058 S: Fn(MutRoot) -> Option<MutValue>,
2059{
2060 pub fn new(get: G, set: S) -> Self {
2061 Self {
2062 get,
2063 set,
2064 _p: std::marker::PhantomData,
2065 }
2066 }
2067
2068 #[inline]
2071 pub fn get(&self, root: Root) -> Option<Value> {
2072 (self.get)(root)
2073 }
2074
2075 #[inline]
2077 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
2078 (self.set)(root)
2079 }
2080
2081 #[inline]
2084 pub fn get_ref<'a>(&self, root: &'a R) -> Option<&'a V>
2085 where
2086 G: for<'b> Fn(&'b R) -> Option<&'b V>,
2087 {
2088 (self.get)(root)
2089 }
2090
2091 #[inline]
2093 pub fn get_mut_ref<'a>(&self, root: &'a mut R) -> Option<&'a mut V>
2094 where
2095 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
2096 {
2097 (self.set)(root)
2098 }
2099
2100 #[inline]
2101 pub fn then<SV, G2, S2>(
2102 self,
2103 next: Kp<
2104 V,
2105 SV,
2106 &'static V, &'static SV,
2108 &'static mut V,
2109 &'static mut SV,
2110 G2,
2111 S2,
2112 >,
2113 ) -> Kp<
2114 R,
2115 SV,
2116 &'static R,
2117 &'static SV,
2118 &'static mut R,
2119 &'static mut SV,
2120 impl for<'b> Fn(&'b R) -> Option<&'b SV>,
2121 impl for<'b> Fn(&'b mut R) -> Option<&'b mut SV>,
2122 >
2123 where
2124 G: for<'b> Fn(&'b R) -> Option<&'b V>,
2125 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
2126 G2: for<'b> Fn(&'b V) -> Option<&'b SV>,
2127 S2: for<'b> Fn(&'b mut V) -> Option<&'b mut SV>,
2128 {
2129 let first_get = self.get;
2130 let first_set = self.set;
2131 let second_get = next.get;
2132 let second_set = next.set;
2133
2134 Kp::new(
2135 constrain_get(move |root: &R| first_get(root).and_then(|value| second_get(value))),
2136 constrain_set(move |root: &mut R| first_set(root).and_then(|value| second_set(value))),
2137 )
2138 }
2139
2140}
2141
2142impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Debug
2143 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2144where
2145 Root: std::borrow::Borrow<R>,
2146 Value: std::borrow::Borrow<V>,
2147 MutRoot: std::borrow::BorrowMut<R>,
2148 MutValue: std::borrow::BorrowMut<V>,
2149 G: Fn(Root) -> Option<Value>,
2150 S: Fn(MutRoot) -> Option<MutValue>,
2151{
2152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2153 f.debug_struct("Kp")
2154 .field("root_ty", &std::any::type_name::<R>())
2155 .field("value_ty", &std::any::type_name::<V>())
2156 .finish_non_exhaustive()
2157 }
2158}
2159
2160impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Display
2161 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
2162where
2163 Root: std::borrow::Borrow<R>,
2164 Value: std::borrow::Borrow<V>,
2165 MutRoot: std::borrow::BorrowMut<R>,
2166 MutValue: std::borrow::BorrowMut<V>,
2167 G: Fn(Root) -> Option<Value>,
2168 S: Fn(MutRoot) -> Option<MutValue>,
2169{
2170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2171 write!(
2172 f,
2173 "Kp<{}, {}>",
2174 std::any::type_name::<R>(),
2175 std::any::type_name::<V>()
2176 )
2177 }
2178}
2179
2180pub fn zip_kps<'a, RootType, Value1, Value2>(
2194 kp1: &'a KpType<'a, RootType, Value1>,
2195 kp2: &'a KpType<'a, RootType, Value2>,
2196) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
2197where
2198 RootType: 'a,
2199 Value1: 'a,
2200 Value2: 'a,
2201{
2202 move |root: &'a RootType| {
2203 let val1 = (kp1.get)(root)?;
2204 let val2 = (kp2.get)(root)?;
2205 Some((val1, val2))
2206 }
2207}
2208
2209impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
2210where
2211 Root: std::borrow::Borrow<R>,
2212 MutRoot: std::borrow::BorrowMut<R>,
2213 G: Fn(Root) -> Option<Root>,
2214 S: Fn(MutRoot) -> Option<MutRoot>,
2215{
2216 pub fn identity_typed() -> Kp<
2217 R,
2218 R,
2219 Root,
2220 Root,
2221 MutRoot,
2222 MutRoot,
2223 fn(Root) -> Option<Root>,
2224 fn(MutRoot) -> Option<MutRoot>,
2225 > {
2226 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
2227 }
2228
2229 pub fn identity<'a>() -> KpType<'a, R, R> {
2230 KpType::new(|r| Some(r), |r| Some(r))
2231 }
2232}
2233
2234pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2243where
2244 Root: std::borrow::Borrow<Enum>,
2245 Value: std::borrow::Borrow<Variant>,
2246 MutRoot: std::borrow::BorrowMut<Enum>,
2247 MutValue: std::borrow::BorrowMut<Variant>,
2248 G: Fn(Root) -> Option<Value>,
2249 S: Fn(MutRoot) -> Option<MutValue>,
2250 E: Fn(Variant) -> Enum,
2251{
2252 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
2253 embedder: E,
2254}
2255
2256unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
2258 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2259where
2260 Root: std::borrow::Borrow<Enum>,
2261 Value: std::borrow::Borrow<Variant>,
2262 MutRoot: std::borrow::BorrowMut<Enum>,
2263 MutValue: std::borrow::BorrowMut<Variant>,
2264 G: Fn(Root) -> Option<Value> + Send,
2265 S: Fn(MutRoot) -> Option<MutValue> + Send,
2266 E: Fn(Variant) -> Enum + Send,
2267{
2268}
2269unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
2270 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2271where
2272 Root: std::borrow::Borrow<Enum>,
2273 Value: std::borrow::Borrow<Variant>,
2274 MutRoot: std::borrow::BorrowMut<Enum>,
2275 MutValue: std::borrow::BorrowMut<Variant>,
2276 G: Fn(Root) -> Option<Value> + Sync,
2277 S: Fn(MutRoot) -> Option<MutValue> + Sync,
2278 E: Fn(Variant) -> Enum + Sync,
2279{
2280}
2281
2282impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2283 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2284where
2285 Root: std::borrow::Borrow<Enum>,
2286 Value: std::borrow::Borrow<Variant>,
2287 MutRoot: std::borrow::BorrowMut<Enum>,
2288 MutValue: std::borrow::BorrowMut<Variant>,
2289 G: Fn(Root) -> Option<Value>,
2290 S: Fn(MutRoot) -> Option<MutValue>,
2291 E: Fn(Variant) -> Enum,
2292{
2293 pub fn new(
2295 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
2296 embedder: E,
2297 ) -> Self {
2298 Self {
2299 extractor,
2300 embedder,
2301 }
2302 }
2303
2304 pub fn get(&self, enum_value: Root) -> Option<Value> {
2306 (self.extractor.get)(enum_value)
2307 }
2308
2309 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
2311 (self.extractor.set)(enum_value)
2312 }
2313
2314 pub fn embed(&self, value: Variant) -> Enum {
2316 (self.embedder)(value)
2317 }
2318
2319 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2321 &self.extractor
2322 }
2323
2324 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
2326 self.extractor
2327 }
2328
2329 pub fn map<MappedValue, F>(
2340 &self,
2341 mapper: F,
2342 ) -> EnumKp<
2343 Enum,
2344 MappedValue,
2345 Root,
2346 MappedValue,
2347 MutRoot,
2348 MappedValue,
2349 impl Fn(Root) -> Option<MappedValue>,
2350 impl Fn(MutRoot) -> Option<MappedValue>,
2351 impl Fn(MappedValue) -> Enum,
2352 >
2353 where
2354 F: Fn(&Variant) -> MappedValue + Copy + 'static,
2357 Variant: 'static,
2358 MappedValue: 'static,
2359 E: Fn(Variant) -> Enum + Copy + 'static,
2361 {
2362 let mapped_extractor = self.extractor.map(mapper);
2363
2364 let new_embedder = move |_value: MappedValue| -> Enum {
2368 panic!(
2369 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
2370 )
2371 };
2372
2373 EnumKp::new(mapped_extractor, new_embedder)
2374 }
2375
2376 pub fn filter<F>(
2388 &self,
2389 predicate: F,
2390 ) -> EnumKp<
2391 Enum,
2392 Variant,
2393 Root,
2394 Value,
2395 MutRoot,
2396 MutValue,
2397 impl Fn(Root) -> Option<Value>,
2398 impl Fn(MutRoot) -> Option<MutValue>,
2399 E,
2400 >
2401 where
2402 F: Fn(&Variant) -> bool + Copy + 'static,
2405 Variant: 'static,
2406 E: Copy,
2408 {
2409 let filtered_extractor = self.extractor.filter(predicate);
2410 EnumKp::new(filtered_extractor, self.embedder)
2411 }
2412}
2413
2414impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Debug
2415 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2416where
2417 Root: std::borrow::Borrow<Enum>,
2418 Value: std::borrow::Borrow<Variant>,
2419 MutRoot: std::borrow::BorrowMut<Enum>,
2420 MutValue: std::borrow::BorrowMut<Variant>,
2421 G: Fn(Root) -> Option<Value>,
2422 S: Fn(MutRoot) -> Option<MutValue>,
2423 E: Fn(Variant) -> Enum,
2424{
2425 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2426 f.debug_struct("EnumKp")
2427 .field("enum_ty", &std::any::type_name::<Enum>())
2428 .field("variant_ty", &std::any::type_name::<Variant>())
2429 .finish_non_exhaustive()
2430 }
2431}
2432
2433impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Display
2434 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
2435where
2436 Root: std::borrow::Borrow<Enum>,
2437 Value: std::borrow::Borrow<Variant>,
2438 MutRoot: std::borrow::BorrowMut<Enum>,
2439 MutValue: std::borrow::BorrowMut<Variant>,
2440 G: Fn(Root) -> Option<Value>,
2441 S: Fn(MutRoot) -> Option<MutValue>,
2442 E: Fn(Variant) -> Enum,
2443{
2444 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2445 write!(
2446 f,
2447 "EnumKp<{}, {}>",
2448 std::any::type_name::<Enum>(),
2449 std::any::type_name::<Variant>()
2450 )
2451 }
2452}
2453
2454pub type EnumKpType<'a, Enum, Variant> = EnumKp<
2456 Enum,
2457 Variant,
2458 &'a Enum,
2459 &'a Variant,
2460 &'a mut Enum,
2461 &'a mut Variant,
2462 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2463 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2464 fn(Variant) -> Enum,
2465>;
2466
2467pub fn enum_variant<'a, Enum, Variant>(
2485 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2486 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2487 embedder: fn(Variant) -> Enum,
2488) -> EnumKpType<'a, Enum, Variant> {
2489 EnumKp::new(Kp::new(getter, setter), embedder)
2490}
2491
2492pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
2502 EnumKp::new(
2503 Kp::new(
2504 |r: &Result<T, E>| r.as_ref().ok(),
2505 |r: &mut Result<T, E>| r.as_mut().ok(),
2506 ),
2507 |t: T| Ok(t),
2508 )
2509}
2510
2511pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
2521 EnumKp::new(
2522 Kp::new(
2523 |r: &Result<T, E>| r.as_ref().err(),
2524 |r: &mut Result<T, E>| r.as_mut().err(),
2525 ),
2526 |e: E| Err(e),
2527 )
2528}
2529
2530pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
2540 EnumKp::new(
2541 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
2542 |t: T| Some(t),
2543 )
2544}
2545
2546pub fn variant_of<'a, Enum, Variant>(
2564 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
2565 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
2566 embedder: fn(Variant) -> Enum,
2567) -> EnumKpType<'a, Enum, Variant> {
2568 enum_variant(getter, setter, embedder)
2569}
2570
2571pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
2584 Kp::new(
2585 |b: &Box<T>| Some(b.as_ref()),
2586 |b: &mut Box<T>| Some(b.as_mut()),
2587 )
2588}
2589
2590pub fn kp_arc<'a, T>() -> Kp<
2601 Arc<T>,
2602 T,
2603 &'a Arc<T>,
2604 &'a T,
2605 &'a mut Arc<T>,
2606 &'a mut T,
2607 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
2608 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
2609> {
2610 Kp::new(
2611 |arc: &Arc<T>| Some(arc.as_ref()),
2612 |arc: &mut Arc<T>| Arc::get_mut(arc),
2613 )
2614}
2615
2616pub fn kp_rc<'a, T>() -> Kp<
2627 std::rc::Rc<T>,
2628 T,
2629 &'a std::rc::Rc<T>,
2630 &'a T,
2631 &'a mut std::rc::Rc<T>,
2632 &'a mut T,
2633 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
2634 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
2635> {
2636 Kp::new(
2637 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
2638 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
2639 )
2640}
2641
2642use std::any::{Any, TypeId};
2645use std::rc::Rc;
2646
2647#[cfg(test)]
2662mod tests {
2663 use super::*;
2664 use std::collections::HashMap;
2665
2666 fn kp_adaptable<T, Root, Value, MutRoot, MutValue, G, S>(kp: T)
2667 where
2668 T: KpTrait<TestKP, String, Root, Value, MutRoot, MutValue, G, S>,
2669 {
2670 }
2673 fn test_kp_trait() {}
2674
2675 #[derive(Debug)]
2676 struct TestKP {
2677 a: String,
2678 b: String,
2679 c: std::sync::Arc<String>,
2680 d: std::sync::Mutex<String>,
2681 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
2682 f: Option<TestKP2>,
2683 g: HashMap<i32, TestKP2>,
2684 }
2685
2686 impl TestKP {
2687 fn new() -> Self {
2688 Self {
2689 a: String::from("a"),
2690 b: String::from("b"),
2691 c: std::sync::Arc::new(String::from("c")),
2692 d: std::sync::Mutex::new(String::from("d")),
2693 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2694 f: Some(TestKP2 {
2695 a: String::from("a3"),
2696 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2697 }),
2698 g: HashMap::new(),
2699 }
2700 }
2701
2702 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2703 KpComposed::from_closures(
2704 move |r: &TestKP| r.g.get(&index),
2705 move |r: &mut TestKP| r.g.get_mut(&index),
2706 )
2707 }
2708
2709 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2712 TestKP2,
2713 String,
2714 Root,
2715 Value,
2716 MutRoot,
2717 MutValue,
2718 impl Fn(Root) -> Option<Value>,
2719 impl Fn(MutRoot) -> Option<MutValue>,
2720 >
2721 where
2722 Root: std::borrow::Borrow<TestKP2>,
2723 MutRoot: std::borrow::BorrowMut<TestKP2>,
2724 Value: std::borrow::Borrow<String> + From<String>,
2725 MutValue: std::borrow::BorrowMut<String> + From<String>,
2726 {
2727 Kp::new(
2728 |r: Root| Some(Value::from(r.borrow().a.clone())),
2729 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2730 )
2731 }
2732
2733 fn c<'a>() -> KpType<'a, TestKP, String> {
2736 KpType::new(
2737 |r: &TestKP| Some(r.c.as_ref()),
2738 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2739 Some(arc_str) => Some(arc_str),
2740 None => None,
2741 },
2742 )
2743 }
2744
2745 fn a<'a>() -> KpType<'a, TestKP, String> {
2746 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2747 }
2748
2749 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2750 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2751 }
2752
2753 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2754 KpType::identity()
2755 }
2756 }
2757
2758 #[test]
2759 fn kp_debug_display_uses_type_names() {
2760 let kp = TestKP::a();
2761 let dbg = format!("{kp:?}");
2762 assert!(dbg.starts_with("Kp {"), "{dbg}");
2763 assert!(dbg.contains("root_ty") && dbg.contains("value_ty"), "{dbg}");
2764 let disp = format!("{kp}");
2765 assert!(disp.contains("TestKP"), "{disp}");
2766 assert!(disp.contains("String"), "{disp}");
2767 }
2768
2769 #[test]
2770 fn akp_and_pkp_debug_display() {
2771 let akp = AKp::new(TestKP::a());
2772 assert!(format!("{akp:?}").starts_with("AKp"));
2773 let pkp = PKp::new(TestKP::a());
2774 let pkp_dbg = format!("{pkp:?}");
2775 assert!(pkp_dbg.starts_with("PKp"), "{pkp_dbg}");
2776 assert!(format!("{pkp}").contains("TestKP"));
2777 }
2778
2779 #[test]
2780 fn enum_kp_debug_display() {
2781 let ok_kp = enum_ok::<i32, String>();
2782 assert!(format!("{ok_kp:?}").contains("EnumKp"));
2783 let s = format!("{ok_kp}");
2784 assert!(s.contains("Result") && s.contains("i32"), "{s}");
2785 }
2786
2787 #[test]
2788 fn composed_kp_into_dynamic_stores_as_kp_dynamic() {
2789 let path: KpDynamic<TestKP, String> = TestKP::f().then(TestKP2::a()).into_dynamic();
2790 let mut t = TestKP::new();
2791 assert_eq!(path.get(&t), Some(&"a3".to_string()));
2792 path.get_mut(&mut t).map(|s| *s = "x".into());
2793 assert_eq!(t.f.as_ref().unwrap().a, "x");
2794 }
2795
2796 #[derive(Debug)]
2797 struct TestKP2 {
2798 a: String,
2799 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2800 }
2801
2802 impl TestKP2 {
2803 fn new() -> Self {
2804 TestKP2 {
2805 a: String::from("a2"),
2806 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2807 }
2808 }
2809
2810 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2811 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2818 fn(MutRoot) -> Option<MutRoot>,
2819 >
2820 where
2821 Root: std::borrow::Borrow<TestKP2>,
2822 MutRoot: std::borrow::BorrowMut<TestKP2>,
2823 G: Fn(Root) -> Option<Root>,
2824 S: Fn(MutRoot) -> Option<MutRoot>,
2825 {
2826 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2827 }
2828
2829 fn a<'a>() -> KpType<'a, TestKP2, String> {
2830 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2831 }
2832
2833 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2834 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2835 }
2836
2837 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2842 KpType::identity()
2843 }
2844 }
2845
2846 #[derive(Debug)]
2847 struct TestKP3 {
2848 a: String,
2849 b: std::sync::Arc<std::sync::Mutex<String>>,
2850 }
2851
2852 impl TestKP3 {
2853 fn new() -> Self {
2854 TestKP3 {
2855 a: String::from("a2"),
2856 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2857 }
2858 }
2859
2860 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2861 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2868 fn(MutRoot) -> Option<MutRoot>,
2869 >
2870 where
2871 Root: std::borrow::Borrow<TestKP3>,
2872 MutRoot: std::borrow::BorrowMut<TestKP3>,
2873 G: Fn(Root) -> Option<Root>,
2874 S: Fn(MutRoot) -> Option<MutRoot>,
2875 {
2876 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2877 }
2878
2879 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2880 KpType::identity()
2881 }
2882 }
2883
2884 impl TestKP3 {}
2885
2886 impl TestKP {}
2887 #[test]
2888 fn test_a() {
2889 let instance2 = TestKP2::new();
2890 let mut instance = TestKP::new();
2891 let kp = TestKP::identity();
2892 let kp_a = TestKP::a();
2893 let wres = TestKP::f()
2895 .then(TestKP2::a())
2896 .get_mut(&mut instance)
2897 .unwrap();
2898 *wres = String::from("a3 changed successfully");
2899 let res = (TestKP::f().then(TestKP2::a()).get)(&instance);
2900 println!("{:?}", res);
2901 let res = (TestKP::f().then(TestKP2::identity()).get)(&instance);
2902 println!("{:?}", res);
2903 let res = (kp.get)(&instance);
2904 println!("{:?}", res);
2905
2906 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2907 println!("{:?}", (new_kp_from_hashmap.get)(&instance));
2908 }
2909
2910 #[test]
2989 fn test_enum_kp_result_ok() {
2990 let ok_result: Result<String, i32> = Ok("success".to_string());
2991 let mut err_result: Result<String, i32> = Err(42);
2992
2993 let ok_kp = enum_ok();
2994
2995 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2997 assert_eq!(ok_kp.get(&err_result), None);
2998
2999 let embedded = ok_kp.embed("embedded".to_string());
3001 assert_eq!(embedded, Ok("embedded".to_string()));
3002
3003 if let Some(val) = ok_kp.get_mut(&mut err_result) {
3005 *val = "modified".to_string();
3006 }
3007 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
3010 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
3011 *val = "modified".to_string();
3012 }
3013 assert_eq!(ok_result2, Ok("modified".to_string()));
3014 }
3015
3016 #[test]
3017 fn test_enum_kp_result_err() {
3018 let ok_result: Result<String, i32> = Ok("success".to_string());
3019 let mut err_result: Result<String, i32> = Err(42);
3020
3021 let err_kp = enum_err();
3022
3023 assert_eq!(err_kp.get(&err_result), Some(&42));
3025 assert_eq!(err_kp.get(&ok_result), None);
3026
3027 let embedded = err_kp.embed(99);
3029 assert_eq!(embedded, Err(99));
3030
3031 if let Some(val) = err_kp.get_mut(&mut err_result) {
3033 *val = 100;
3034 }
3035 assert_eq!(err_result, Err(100));
3036 }
3037
3038 #[test]
3039 fn test_enum_kp_option_some() {
3040 let some_opt = Some("value".to_string());
3041 let mut none_opt: Option<String> = None;
3042
3043 let some_kp = enum_some();
3044
3045 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
3047 assert_eq!(some_kp.get(&none_opt), None);
3048
3049 let embedded = some_kp.embed("embedded".to_string());
3051 assert_eq!(embedded, Some("embedded".to_string()));
3052
3053 let mut some_opt2 = Some("original".to_string());
3055 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
3056 *val = "modified".to_string();
3057 }
3058 assert_eq!(some_opt2, Some("modified".to_string()));
3059 }
3060
3061 #[test]
3062 fn test_enum_kp_custom_enum() {
3063 #[derive(Debug, PartialEq)]
3064 enum MyEnum {
3065 A(String),
3066 B(i32),
3067 C,
3068 }
3069
3070 let mut enum_a = MyEnum::A("hello".to_string());
3071 let enum_b = MyEnum::B(42);
3072 let enum_c = MyEnum::C;
3073
3074 let kp_a = enum_variant(
3076 |e: &MyEnum| match e {
3077 MyEnum::A(s) => Some(s),
3078 _ => None,
3079 },
3080 |e: &mut MyEnum| match e {
3081 MyEnum::A(s) => Some(s),
3082 _ => None,
3083 },
3084 |s: String| MyEnum::A(s),
3085 );
3086
3087 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
3089 assert_eq!(kp_a.get(&enum_b), None);
3090 assert_eq!(kp_a.get(&enum_c), None);
3091
3092 let embedded = kp_a.embed("world".to_string());
3094 assert_eq!(embedded, MyEnum::A("world".to_string()));
3095
3096 if let Some(val) = kp_a.get_mut(&mut enum_a) {
3098 *val = "modified".to_string();
3099 }
3100 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
3101 }
3102
3103 #[test]
3104 fn test_container_kp_box() {
3105 let boxed = Box::new("value".to_string());
3106 let mut boxed_mut = Box::new("original".to_string());
3107
3108 let box_kp = kp_box();
3109
3110 assert_eq!((box_kp.get)(&boxed), Some(&"value".to_string()));
3112
3113 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
3115 *val = "modified".to_string();
3116 }
3117 assert_eq!(*boxed_mut, "modified".to_string());
3118 }
3119
3120 #[test]
3121 fn test_container_kp_arc() {
3122 let arc = Arc::new("value".to_string());
3123 let mut arc_mut = Arc::new("original".to_string());
3124
3125 let arc_kp = kp_arc();
3126
3127 assert_eq!((arc_kp.get)(&arc), Some(&"value".to_string()));
3129
3130 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
3132 *val = "modified".to_string();
3133 }
3134 assert_eq!(*arc_mut, "modified".to_string());
3135
3136 let arc_shared = Arc::new("shared".to_string());
3138 let arc_shared2 = Arc::clone(&arc_shared);
3139 let mut arc_shared_mut = arc_shared;
3140 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
3141 }
3142
3143 #[test]
3144 fn test_enum_kp_composition() {
3145 #[derive(Debug, PartialEq)]
3147 struct Inner {
3148 value: String,
3149 }
3150
3151 let result: Result<Inner, i32> = Ok(Inner {
3152 value: "nested".to_string(),
3153 });
3154
3155 let inner_kp = KpType::new(
3157 |i: &Inner| Some(&i.value),
3158 |i: &mut Inner| Some(&mut i.value),
3159 );
3160
3161 let ok_kp = enum_ok::<Inner, i32>();
3163 let ok_kp_base = ok_kp.into_kp();
3164 let composed = ok_kp_base.then(inner_kp);
3165
3166 assert_eq!((composed.get)(&result), Some(&"nested".to_string()));
3167 }
3168
3169 #[test]
3170 fn test_pkp_basic() {
3171 #[derive(Debug)]
3172 struct User {
3173 name: String,
3174 age: i32,
3175 }
3176
3177 let user = User {
3178 name: "Akash".to_string(),
3179 age: 30,
3180 };
3181
3182 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3184 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3185
3186 let name_pkp = PKp::new(name_kp);
3188 let age_pkp = PKp::new(age_kp);
3189
3190 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Akash".to_string()));
3192 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
3193
3194 assert_eq!(name_pkp.get_as::<i32>(&user), None);
3196 assert_eq!(age_pkp.get_as::<String>(&user), None);
3197
3198 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
3200 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
3201 }
3202
3203 #[test]
3204 fn test_pkp_collection() {
3205 #[derive(Debug)]
3206 struct User {
3207 name: String,
3208 age: i32,
3209 }
3210
3211 let user = User {
3212 name: "Bob".to_string(),
3213 age: 25,
3214 };
3215
3216 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3218 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3219
3220 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
3221
3222 let name_value = keypaths[0].get_as::<String>(&user);
3224 let age_value = keypaths[1].get_as::<i32>(&user);
3225
3226 assert_eq!(name_value, Some(&"Bob".to_string()));
3227 assert_eq!(age_value, Some(&25));
3228 }
3229
3230 #[test]
3231 fn test_pkp_for_arc() {
3232 #[derive(Debug)]
3233 struct User {
3234 name: String,
3235 }
3236
3237 let user = Arc::new(User {
3238 name: "Charlie".to_string(),
3239 });
3240
3241 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3242 let name_pkp = PKp::new(name_kp);
3243
3244 let arc_pkp = name_pkp.for_arc();
3246
3247 assert_eq!(
3248 arc_pkp.get_as::<String>(&user),
3249 Some(&"Charlie".to_string())
3250 );
3251 }
3252
3253 #[test]
3254 fn test_pkp_for_option() {
3255 #[derive(Debug)]
3256 struct User {
3257 name: String,
3258 }
3259
3260 let some_user = Some(User {
3261 name: "Diana".to_string(),
3262 });
3263 let none_user: Option<User> = None;
3264
3265 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3266 let name_pkp = PKp::new(name_kp);
3267
3268 let opt_pkp = name_pkp.for_option();
3270
3271 assert_eq!(
3272 opt_pkp.get_as::<String>(&some_user),
3273 Some(&"Diana".to_string())
3274 );
3275 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
3276 }
3277
3278 #[test]
3279 fn test_akp_basic() {
3280 #[derive(Debug)]
3281 struct User {
3282 name: String,
3283 age: i32,
3284 }
3285
3286 #[derive(Debug)]
3287 struct Product {
3288 title: String,
3289 price: f64,
3290 }
3291
3292 let user = User {
3293 name: "Eve".to_string(),
3294 age: 28,
3295 };
3296
3297 let product = Product {
3298 title: "Book".to_string(),
3299 price: 19.99,
3300 };
3301
3302 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3304 let user_name_akp = AKp::new(user_name_kp);
3305
3306 let product_title_kp = KpType::new(
3307 |p: &Product| Some(&p.title),
3308 |p: &mut Product| Some(&mut p.title),
3309 );
3310 let product_title_akp = AKp::new(product_title_kp);
3311
3312 assert_eq!(
3314 user_name_akp.get_as::<User, String>(&user),
3315 Some(Some(&"Eve".to_string()))
3316 );
3317 assert_eq!(
3318 product_title_akp.get_as::<Product, String>(&product),
3319 Some(Some(&"Book".to_string()))
3320 );
3321
3322 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
3324 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
3325
3326 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
3328 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
3329 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
3330 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
3331 }
3332
3333 #[test]
3334 fn test_akp_heterogeneous_collection() {
3335 #[derive(Debug)]
3336 struct User {
3337 name: String,
3338 }
3339
3340 #[derive(Debug)]
3341 struct Product {
3342 title: String,
3343 }
3344
3345 let user = User {
3346 name: "Frank".to_string(),
3347 };
3348 let product = Product {
3349 title: "Laptop".to_string(),
3350 };
3351
3352 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3354 let product_title_kp = KpType::new(
3355 |p: &Product| Some(&p.title),
3356 |p: &mut Product| Some(&mut p.title),
3357 );
3358
3359 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
3360
3361 let user_any: &dyn Any = &user;
3363 let product_any: &dyn Any = &product;
3364
3365 let user_value = keypaths[0].get(user_any);
3366 let product_value = keypaths[1].get(product_any);
3367
3368 assert!(user_value.is_some());
3369 assert!(product_value.is_some());
3370
3371 assert_eq!(
3373 user_value.and_then(|v| v.downcast_ref::<String>()),
3374 Some(&"Frank".to_string())
3375 );
3376 assert_eq!(
3377 product_value.and_then(|v| v.downcast_ref::<String>()),
3378 Some(&"Laptop".to_string())
3379 );
3380 }
3381
3382 #[test]
3383 fn test_akp_for_option() {
3384 #[derive(Debug)]
3385 struct User {
3386 name: String,
3387 }
3388
3389 let some_user = Some(User {
3390 name: "Grace".to_string(),
3391 });
3392 let none_user: Option<User> = None;
3393
3394 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3395 let name_akp = AKp::new(name_kp);
3396
3397 let opt_akp = name_akp.for_option::<User>();
3399
3400 assert_eq!(
3401 opt_akp.get_as::<Option<User>, String>(&some_user),
3402 Some(Some(&"Grace".to_string()))
3403 );
3404 assert_eq!(
3405 opt_akp.get_as::<Option<User>, String>(&none_user),
3406 Some(None)
3407 );
3408 }
3409
3410 #[test]
3411 fn test_akp_for_result() {
3412 #[derive(Debug)]
3413 struct User {
3414 name: String,
3415 }
3416
3417 let ok_user: Result<User, String> = Ok(User {
3418 name: "Henry".to_string(),
3419 });
3420 let err_user: Result<User, String> = Err("Not found".to_string());
3421
3422 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3423 let name_akp = AKp::new(name_kp);
3424
3425 let result_akp = name_akp.for_result::<User, String>();
3427
3428 assert_eq!(
3429 result_akp.get_as::<Result<User, String>, String>(&ok_user),
3430 Some(Some(&"Henry".to_string()))
3431 );
3432 assert_eq!(
3433 result_akp.get_as::<Result<User, String>, String>(&err_user),
3434 Some(None)
3435 );
3436 }
3437
3438 #[test]
3441 fn test_kp_map() {
3442 #[derive(Debug)]
3443 struct User {
3444 name: String,
3445 age: i32,
3446 }
3447
3448 let user = User {
3449 name: "Akash".to_string(),
3450 age: 30,
3451 };
3452
3453 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3455 let len_kp = name_kp.map(|name: &String| name.len());
3456
3457 assert_eq!((len_kp.get)(&user), Some(5));
3458
3459 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3461 let double_age_kp = age_kp.map(|age: &i32| age * 2);
3462
3463 assert_eq!((double_age_kp.get)(&user), Some(60));
3464
3465 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
3467 assert_eq!((is_adult_kp.get)(&user), Some(true));
3468 }
3469
3470 #[test]
3471 fn test_kp_filter() {
3472 #[derive(Debug)]
3473 struct User {
3474 name: String,
3475 age: i32,
3476 }
3477
3478 let adult = User {
3479 name: "Akash".to_string(),
3480 age: 30,
3481 };
3482
3483 let minor = User {
3484 name: "Bob".to_string(),
3485 age: 15,
3486 };
3487
3488 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3489 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
3490
3491 assert_eq!((adult_age_kp.get)(&adult), Some(&30));
3492 assert_eq!((adult_age_kp.get)(&minor), None);
3493
3494 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3496 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
3497
3498 assert_eq!((short_name_kp.get)(&minor), Some(&"Bob".to_string()));
3499 assert_eq!((short_name_kp.get)(&adult), None);
3500 }
3501
3502 #[test]
3503 fn test_kp_map_and_filter() {
3504 #[derive(Debug)]
3505 struct User {
3506 scores: Vec<i32>,
3507 }
3508
3509 let user = User {
3510 scores: vec![85, 92, 78, 95],
3511 };
3512
3513 let scores_kp = KpType::new(
3514 |u: &User| Some(&u.scores),
3515 |u: &mut User| Some(&mut u.scores),
3516 );
3517
3518 let avg_kp =
3520 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3521
3522 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
3524
3525 assert_eq!((high_avg_kp.get)(&user), Some(87)); }
3527
3528 #[test]
3529 fn test_enum_kp_map() {
3530 let ok_result: Result<String, i32> = Ok("hello".to_string());
3531 let err_result: Result<String, i32> = Err(42);
3532
3533 let ok_kp = enum_ok::<String, i32>();
3534 let len_kp = ok_kp.map(|s: &String| s.len());
3535
3536 assert_eq!(len_kp.get(&ok_result), Some(5));
3537 assert_eq!(len_kp.get(&err_result), None);
3538
3539 let some_opt = Some(vec![1, 2, 3, 4, 5]);
3541 let none_opt: Option<Vec<i32>> = None;
3542
3543 let some_kp = enum_some::<Vec<i32>>();
3544 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
3545
3546 assert_eq!(count_kp.get(&some_opt), Some(5));
3547 assert_eq!(count_kp.get(&none_opt), None);
3548 }
3549
3550 #[test]
3551 fn test_enum_kp_filter() {
3552 let ok_result1: Result<i32, String> = Ok(42);
3553 let ok_result2: Result<i32, String> = Ok(-5);
3554 let err_result: Result<i32, String> = Err("error".to_string());
3555
3556 let ok_kp = enum_ok::<i32, String>();
3557 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
3558
3559 assert_eq!((positive_kp.extractor.get)(&ok_result1), Some(&42));
3560 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
3565 let short_str = Some("hi".to_string());
3566
3567 let some_kp = enum_some::<String>();
3568 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
3569
3570 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
3571 assert_eq!(long_kp.get(&short_str), None);
3572 }
3573
3574 #[test]
3575 fn test_pkp_filter() {
3576 #[derive(Debug)]
3577 struct User {
3578 name: String,
3579 age: i32,
3580 }
3581
3582 let adult = User {
3583 name: "Akash".to_string(),
3584 age: 30,
3585 };
3586
3587 let minor = User {
3588 name: "Bob".to_string(),
3589 age: 15,
3590 };
3591
3592 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3593 let age_pkp = PKp::new(age_kp);
3594
3595 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
3597
3598 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
3599 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
3600
3601 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3603 let name_pkp = PKp::new(name_kp);
3604 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
3605
3606 assert_eq!(
3607 short_name_pkp.get_as::<String>(&minor),
3608 Some(&"Bob".to_string())
3609 );
3610 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
3611 }
3612
3613 #[test]
3614 fn test_akp_filter() {
3615 #[derive(Debug)]
3616 struct User {
3617 age: i32,
3618 }
3619
3620 #[derive(Debug)]
3621 struct Product {
3622 price: f64,
3623 }
3624
3625 let adult = User { age: 30 };
3626 let minor = User { age: 15 };
3627 let expensive = Product { price: 99.99 };
3628 let cheap = Product { price: 5.0 };
3629
3630 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3632 let age_akp = AKp::new(age_kp);
3633 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
3634
3635 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
3636 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
3637
3638 let price_kp = KpType::new(
3640 |p: &Product| Some(&p.price),
3641 |p: &mut Product| Some(&mut p.price),
3642 );
3643 let price_akp = AKp::new(price_kp);
3644 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
3645
3646 assert_eq!(
3647 expensive_akp.get_as::<Product, f64>(&expensive),
3648 Some(Some(&99.99))
3649 );
3650 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
3651 }
3652
3653 #[test]
3656 fn test_kp_filter_map() {
3657 #[derive(Debug)]
3658 struct User {
3659 middle_name: Option<String>,
3660 }
3661
3662 let user_with = User {
3663 middle_name: Some("Marie".to_string()),
3664 };
3665 let user_without = User { middle_name: None };
3666
3667 let middle_kp = KpType::new(
3668 |u: &User| Some(&u.middle_name),
3669 |u: &mut User| Some(&mut u.middle_name),
3670 );
3671
3672 let first_char_kp = middle_kp
3673 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
3674
3675 assert_eq!((first_char_kp.get)(&user_with), Some('M'));
3676 assert_eq!((first_char_kp.get)(&user_without), None);
3677 }
3678
3679 #[test]
3680 fn test_kp_inspect() {
3681 #[derive(Debug)]
3682 struct User {
3683 name: String,
3684 }
3685
3686 let user = User {
3687 name: "Akash".to_string(),
3688 };
3689
3690 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3694
3695 let result = (name_kp.get)(&user);
3698 assert_eq!(result, Some(&"Akash".to_string()));
3699
3700 }
3703
3704 #[test]
3705 fn test_kp_fold_value() {
3706 #[derive(Debug)]
3707 struct User {
3708 scores: Vec<i32>,
3709 }
3710
3711 let user = User {
3712 scores: vec![85, 92, 78, 95],
3713 };
3714
3715 let scores_kp = KpType::new(
3716 |u: &User| Some(&u.scores),
3717 |u: &mut User| Some(&mut u.scores),
3718 );
3719
3720 let sum_fn =
3722 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
3723
3724 assert_eq!(sum_fn(&user), 350);
3725 }
3726
3727 #[test]
3728 fn test_kp_any_all() {
3729 #[derive(Debug)]
3730 struct User {
3731 scores: Vec<i32>,
3732 }
3733
3734 let user_high = User {
3735 scores: vec![85, 92, 88],
3736 };
3737 let user_mixed = User {
3738 scores: vec![65, 92, 78],
3739 };
3740
3741 let scores_kp = KpType::new(
3742 |u: &User| Some(&u.scores),
3743 |u: &mut User| Some(&mut u.scores),
3744 );
3745
3746 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
3748 assert!(has_high_fn(&user_high));
3749 assert!(has_high_fn(&user_mixed));
3750
3751 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
3753 assert!(all_passing_fn(&user_high));
3754 assert!(!all_passing_fn(&user_mixed));
3755 }
3756
3757 #[test]
3758 fn test_kp_count_items() {
3759 #[derive(Debug)]
3760 struct User {
3761 tags: Vec<String>,
3762 }
3763
3764 let user = User {
3765 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
3766 };
3767
3768 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3769 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
3770
3771 assert_eq!(count_fn(&user), Some(3));
3772 }
3773
3774 #[test]
3775 fn test_kp_find_in() {
3776 #[derive(Debug)]
3777 struct User {
3778 scores: Vec<i32>,
3779 }
3780
3781 let user = User {
3782 scores: vec![85, 92, 78, 95, 88],
3783 };
3784
3785 let scores_kp = KpType::new(
3786 |u: &User| Some(&u.scores),
3787 |u: &mut User| Some(&mut u.scores),
3788 );
3789
3790 let first_high_fn =
3792 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3793
3794 assert_eq!(first_high_fn(&user), Some(92));
3795
3796 let perfect_fn =
3798 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3799
3800 assert_eq!(perfect_fn(&user), None);
3801 }
3802
3803 #[test]
3804 fn test_kp_take_skip() {
3805 #[derive(Debug)]
3806 struct User {
3807 tags: Vec<String>,
3808 }
3809
3810 let user = User {
3811 tags: vec![
3812 "a".to_string(),
3813 "b".to_string(),
3814 "c".to_string(),
3815 "d".to_string(),
3816 ],
3817 };
3818
3819 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3820
3821 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3823 tags.iter().take(n).cloned().collect::<Vec<_>>()
3824 });
3825
3826 let taken = take_fn(&user).unwrap();
3827 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3828
3829 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3831 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3832 });
3833
3834 let skipped = skip_fn(&user).unwrap();
3835 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3836 }
3837
3838 #[test]
3839 fn test_kp_partition() {
3840 #[derive(Debug)]
3841 struct User {
3842 scores: Vec<i32>,
3843 }
3844
3845 let user = User {
3846 scores: vec![85, 92, 65, 95, 72, 58],
3847 };
3848
3849 let scores_kp = KpType::new(
3850 |u: &User| Some(&u.scores),
3851 |u: &mut User| Some(&mut u.scores),
3852 );
3853
3854 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3855 scores.iter().copied().partition(|&s| s >= 70)
3856 });
3857
3858 let (passing, failing) = partition_fn(&user).unwrap();
3859 assert_eq!(passing, vec![85, 92, 95, 72]);
3860 assert_eq!(failing, vec![65, 58]);
3861 }
3862
3863 #[test]
3864 fn test_kp_min_max() {
3865 #[derive(Debug)]
3866 struct User {
3867 scores: Vec<i32>,
3868 }
3869
3870 let user = User {
3871 scores: vec![85, 92, 78, 95, 88],
3872 };
3873
3874 let scores_kp = KpType::new(
3875 |u: &User| Some(&u.scores),
3876 |u: &mut User| Some(&mut u.scores),
3877 );
3878
3879 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3881 assert_eq!(min_fn(&user), Some(78));
3882
3883 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3885 assert_eq!(max_fn(&user), Some(95));
3886 }
3887
3888 #[test]
3889 fn test_kp_sum() {
3890 #[derive(Debug)]
3891 struct User {
3892 scores: Vec<i32>,
3893 }
3894
3895 let user = User {
3896 scores: vec![85, 92, 78],
3897 };
3898
3899 let scores_kp = KpType::new(
3900 |u: &User| Some(&u.scores),
3901 |u: &mut User| Some(&mut u.scores),
3902 );
3903
3904 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3905 assert_eq!(sum_fn(&user), Some(255));
3906
3907 let avg_fn =
3909 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3910 assert_eq!(avg_fn.get(&user), Some(85));
3911 }
3912
3913 #[test]
3914 fn test_kp_chain() {
3915 #[derive(Debug)]
3916 struct User {
3917 profile: Profile,
3918 }
3919
3920 #[derive(Debug)]
3921 struct Profile {
3922 settings: Settings,
3923 }
3924
3925 #[derive(Debug)]
3926 struct Settings {
3927 theme: String,
3928 }
3929
3930 let user = User {
3931 profile: Profile {
3932 settings: Settings {
3933 theme: "dark".to_string(),
3934 },
3935 },
3936 };
3937
3938 let profile_kp = KpType::new(
3939 |u: &User| Some(&u.profile),
3940 |u: &mut User| Some(&mut u.profile),
3941 );
3942 let settings_kp = KpType::new(
3943 |p: &Profile| Some(&p.settings),
3944 |p: &mut Profile| Some(&mut p.settings),
3945 );
3946 let theme_kp = KpType::new(
3947 |s: &Settings| Some(&s.theme),
3948 |s: &mut Settings| Some(&mut s.theme),
3949 );
3950
3951 let profile_settings = profile_kp.then(settings_kp);
3953 let theme_path = profile_settings.then(theme_kp);
3954 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3955 }
3956
3957 #[test]
3958 fn test_kp_zip() {
3959 #[derive(Debug)]
3960 struct User {
3961 name: String,
3962 age: i32,
3963 }
3964
3965 let user = User {
3966 name: "Akash".to_string(),
3967 age: 30,
3968 };
3969
3970 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3971 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3972
3973 let zipped_fn = zip_kps(&name_kp, &age_kp);
3974 let result = zipped_fn(&user);
3975
3976 assert_eq!(result, Some((&"Akash".to_string(), &30)));
3977 }
3978
3979 #[test]
3980 fn test_kp_complex_pipeline() {
3981 #[derive(Debug)]
3982 struct User {
3983 transactions: Vec<Transaction>,
3984 }
3985
3986 #[derive(Debug)]
3987 struct Transaction {
3988 amount: f64,
3989 category: String,
3990 }
3991
3992 let user = User {
3993 transactions: vec![
3994 Transaction {
3995 amount: 50.0,
3996 category: "food".to_string(),
3997 },
3998 Transaction {
3999 amount: 100.0,
4000 category: "transport".to_string(),
4001 },
4002 Transaction {
4003 amount: 25.0,
4004 category: "food".to_string(),
4005 },
4006 Transaction {
4007 amount: 200.0,
4008 category: "shopping".to_string(),
4009 },
4010 ],
4011 };
4012
4013 let txns_kp = KpType::new(
4014 |u: &User| Some(&u.transactions),
4015 |u: &mut User| Some(&mut u.transactions),
4016 );
4017
4018 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
4020 txns.iter()
4021 .filter(|t| t.category == "food")
4022 .map(|t| t.amount)
4023 .sum::<f64>()
4024 });
4025
4026 assert_eq!(food_total.get(&user), Some(75.0));
4027
4028 let has_large =
4030 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
4031
4032 assert!(has_large(&user));
4033
4034 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
4036 assert_eq!(count(&user), Some(4));
4037 }
4038
4039 #[test]
4043 fn test_no_clone_required_for_root() {
4044 use std::sync::Arc;
4045 use std::sync::atomic::{AtomicUsize, Ordering};
4046
4047 struct NonCloneableRoot {
4050 data: Arc<AtomicUsize>,
4051 cached_value: usize,
4052 }
4053
4054 impl NonCloneableRoot {
4055 fn new() -> Self {
4056 Self {
4057 data: Arc::new(AtomicUsize::new(42)),
4058 cached_value: 42,
4059 }
4060 }
4061
4062 fn increment(&mut self) {
4063 self.data.fetch_add(1, Ordering::SeqCst);
4064 self.cached_value = self.data.load(Ordering::SeqCst);
4065 }
4066
4067 fn get_value(&self) -> &usize {
4068 &self.cached_value
4069 }
4070
4071 fn get_value_mut(&mut self) -> &mut usize {
4072 &mut self.cached_value
4073 }
4074 }
4075
4076 let mut root = NonCloneableRoot::new();
4077
4078 let data_kp = KpType::new(
4080 |r: &NonCloneableRoot| Some(r.get_value()),
4081 |r: &mut NonCloneableRoot| {
4082 r.increment();
4083 Some(r.get_value_mut())
4084 },
4085 );
4086
4087 assert_eq!(data_kp.get(&root), Some(&42));
4089
4090 {
4091 let doubled = data_kp.map(|val: &usize| val * 2);
4093 assert_eq!(doubled.get(&root), Some(84));
4094
4095 let filtered = data_kp.filter(|val: &usize| *val > 0);
4097 assert_eq!(filtered.get(&root), Some(&42));
4098 } let value_ref = data_kp.get_mut(&mut root);
4102 assert!(value_ref.is_some());
4103 }
4104
4105 #[test]
4106 fn test_no_clone_required_for_value() {
4107 use std::sync::Arc;
4108 use std::sync::atomic::{AtomicUsize, Ordering};
4109
4110 struct NonCloneableValue {
4112 counter: Arc<AtomicUsize>,
4113 }
4114
4115 impl NonCloneableValue {
4116 fn new(val: usize) -> Self {
4117 Self {
4118 counter: Arc::new(AtomicUsize::new(val)),
4119 }
4120 }
4121
4122 fn get(&self) -> usize {
4123 self.counter.load(Ordering::SeqCst)
4124 }
4125 }
4126
4127 struct Root {
4128 value: NonCloneableValue,
4129 }
4130
4131 let root = Root {
4132 value: NonCloneableValue::new(100),
4133 };
4134
4135 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4137
4138 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
4140 assert_eq!(counter_kp.get(&root), Some(100));
4141
4142 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
4144 assert!(filtered.get(&root).is_some());
4145 }
4146
4147 #[test]
4148 fn test_static_does_not_leak_memory() {
4149 use std::sync::Arc;
4150 use std::sync::atomic::{AtomicUsize, Ordering};
4151
4152 static CREATED: AtomicUsize = AtomicUsize::new(0);
4154 static DROPPED: AtomicUsize = AtomicUsize::new(0);
4155
4156 struct Tracked {
4157 id: usize,
4158 }
4159
4160 impl Tracked {
4161 fn new() -> Self {
4162 let id = CREATED.fetch_add(1, Ordering::SeqCst);
4163 Self { id }
4164 }
4165 }
4166
4167 impl Drop for Tracked {
4168 fn drop(&mut self) {
4169 DROPPED.fetch_add(1, Ordering::SeqCst);
4170 }
4171 }
4172
4173 struct Root {
4174 data: Tracked,
4175 }
4176
4177 CREATED.store(0, Ordering::SeqCst);
4179 DROPPED.store(0, Ordering::SeqCst);
4180
4181 {
4182 let root = Root {
4183 data: Tracked::new(),
4184 };
4185
4186 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4187
4188 let mapped1 = data_kp.map(|t: &Tracked| t.id);
4190 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
4191 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
4192
4193 assert_eq!(mapped1.get(&root), Some(0));
4194 assert_eq!(mapped2.get(&root), Some(1));
4195 assert_eq!(mapped3.get(&root), Some(2));
4196
4197 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
4199 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
4200 }
4201
4202 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
4204 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
4205
4206 }
4208
4209 #[test]
4210 fn test_references_not_cloned() {
4211 use std::sync::Arc;
4212
4213 struct ExpensiveData {
4215 large_vec: Vec<u8>,
4216 }
4217
4218 impl ExpensiveData {
4219 fn new(size: usize) -> Self {
4220 Self {
4221 large_vec: vec![0u8; size],
4222 }
4223 }
4224
4225 fn size(&self) -> usize {
4226 self.large_vec.len()
4227 }
4228 }
4229
4230 struct Root {
4231 expensive: ExpensiveData,
4232 }
4233
4234 let root = Root {
4235 expensive: ExpensiveData::new(1_000_000), };
4237
4238 let expensive_kp = KpType::new(
4239 |r: &Root| Some(&r.expensive),
4240 |r: &mut Root| Some(&mut r.expensive),
4241 );
4242
4243 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
4245 assert_eq!(size_kp.get(&root), Some(1_000_000));
4246
4247 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
4249 assert!(large_filter.get(&root).is_some());
4250
4251 }
4253
4254 #[test]
4255 fn test_hof_with_arc_no_extra_clones() {
4256 use std::sync::Arc;
4257
4258 #[derive(Debug)]
4259 struct SharedData {
4260 value: String,
4261 }
4262
4263 struct Root {
4264 shared: Arc<SharedData>,
4265 }
4266
4267 let shared = Arc::new(SharedData {
4268 value: "shared".to_string(),
4269 });
4270
4271 assert_eq!(Arc::strong_count(&shared), 1);
4273
4274 {
4275 let root = Root {
4276 shared: Arc::clone(&shared),
4277 };
4278
4279 assert_eq!(Arc::strong_count(&shared), 2);
4281
4282 let shared_kp = KpType::new(
4283 |r: &Root| Some(&r.shared),
4284 |r: &mut Root| Some(&mut r.shared),
4285 );
4286
4287 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
4289
4290 assert_eq!(value_kp.get(&root), Some(6));
4292 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
4296 assert!(filtered.get(&root).is_some());
4297 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
4302
4303 #[test]
4304 fn test_closure_captures_not_root_values() {
4305 use std::sync::Arc;
4306 use std::sync::atomic::{AtomicUsize, Ordering};
4307
4308 let call_count = Arc::new(AtomicUsize::new(0));
4310 let call_count_clone = Arc::clone(&call_count);
4311
4312 struct Root {
4313 value: i32,
4314 }
4315
4316 let root = Root { value: 42 };
4317
4318 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4319
4320 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
4323 call_count_clone.fetch_add(1, Ordering::SeqCst);
4324 v * 2
4325 });
4326
4327 assert_eq!(doubled(&root), 84);
4329 assert_eq!(doubled(&root), 84);
4330 assert_eq!(doubled(&root), 84);
4331
4332 assert_eq!(call_count.load(Ordering::SeqCst), 3);
4334
4335 }
4337
4338 #[test]
4339 fn test_static_with_borrowed_data() {
4340 struct Root {
4344 data: String,
4345 }
4346
4347 {
4348 let root = Root {
4349 data: "temporary".to_string(),
4350 };
4351
4352 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4353
4354 let len_kp = data_kp.map(|s: &String| s.len());
4356 assert_eq!(len_kp.get(&root), Some(9));
4357
4358 } }
4363
4364 #[test]
4365 fn test_multiple_hof_operations_no_accumulation() {
4366 use std::sync::Arc;
4367 use std::sync::atomic::{AtomicUsize, Ordering};
4368
4369 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
4370
4371 struct Tracked {
4372 id: usize,
4373 }
4374
4375 impl Drop for Tracked {
4376 fn drop(&mut self) {
4377 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4378 }
4379 }
4380
4381 struct Root {
4382 values: Vec<Tracked>,
4383 }
4384
4385 DROP_COUNT.store(0, Ordering::SeqCst);
4386
4387 {
4388 let root = Root {
4389 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
4390 };
4391
4392 let values_kp = KpType::new(
4393 |r: &Root| Some(&r.values),
4394 |r: &mut Root| Some(&mut r.values),
4395 );
4396
4397 let count = values_kp.count_items(|v| v.len());
4399 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
4400 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
4401 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
4402
4403 assert_eq!(count(&root), Some(3));
4404 assert_eq!(sum(&root), Some(6));
4405 assert!(has_2(&root));
4406 assert!(all_positive(&root));
4407
4408 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4410 }
4411
4412 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
4414 }
4415
4416 #[test]
4417 fn test_copy_bound_only_for_function_not_data() {
4418 #[derive(Debug)]
4422 struct NonCopyData {
4423 value: String,
4424 }
4425
4426 struct Root {
4427 data: NonCopyData,
4428 }
4429
4430 let root = Root {
4431 data: NonCopyData {
4432 value: "test".to_string(),
4433 },
4434 };
4435
4436 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
4437
4438 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
4441 assert_eq!(len_kp.get(&root), Some(4));
4442
4443 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
4445 assert!(filtered.get(&root).is_some());
4446 }
4447
4448 #[test]
4449 fn test_no_memory_leak_with_cyclic_references() {
4450 use std::sync::atomic::{AtomicUsize, Ordering};
4451 use std::sync::{Arc, Weak};
4452
4453 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
4454
4455 struct Node {
4456 id: usize,
4457 parent: Option<Weak<Node>>,
4458 }
4459
4460 impl Drop for Node {
4461 fn drop(&mut self) {
4462 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
4463 }
4464 }
4465
4466 struct Root {
4467 node: Arc<Node>,
4468 }
4469
4470 DROP_COUNT.store(0, Ordering::SeqCst);
4471
4472 {
4473 let root = Root {
4474 node: Arc::new(Node {
4475 id: 1,
4476 parent: None,
4477 }),
4478 };
4479
4480 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
4481
4482 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
4484 assert_eq!(id_kp.get(&root), Some(1));
4485
4486 assert_eq!(Arc::strong_count(&root.node), 1);
4488
4489 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
4491 }
4492
4493 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
4495 }
4496
4497 #[test]
4498 fn test_hof_operations_are_zero_cost_abstractions() {
4499 struct Root {
4503 value: i32,
4504 }
4505
4506 let root = Root { value: 10 };
4507
4508 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
4509
4510 let direct_result = value_kp.get(&root).map(|v| v * 2);
4512 assert_eq!(direct_result, Some(20));
4513
4514 let mapped_kp = value_kp.map(|v: &i32| v * 2);
4516 let hof_result = mapped_kp.get(&root);
4517 assert_eq!(hof_result, Some(20));
4518
4519 assert_eq!(direct_result, hof_result);
4521 }
4522
4523 #[test]
4524 fn test_complex_closure_captures_allowed() {
4525 use std::sync::Arc;
4526
4527 struct Root {
4529 scores: Vec<i32>,
4530 }
4531
4532 let root = Root {
4533 scores: vec![85, 92, 78, 95, 88],
4534 };
4535
4536 let scores_kp = KpType::new(
4537 |r: &Root| Some(&r.scores),
4538 |r: &mut Root| Some(&mut r.scores),
4539 );
4540
4541 let threshold = 90;
4543 let multiplier = Arc::new(2);
4544
4545 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
4547 let high: i32 = scores
4548 .iter()
4549 .filter(|&&s| s >= threshold)
4550 .map(|&s| s * *multiplier)
4551 .sum();
4552 acc + high
4553 });
4554
4555 assert_eq!(high_scores_doubled(&root), 374);
4557 }
4558
4559 #[test]
4563 fn test_pkp_filter_by_value_type() {
4564 use std::any::TypeId;
4565
4566 #[derive(Debug)]
4567 struct User {
4568 name: String,
4569 age: i32,
4570 score: f64,
4571 active: bool,
4572 }
4573
4574 let user = User {
4575 name: "Akash".to_string(),
4576 age: 30,
4577 score: 95.5,
4578 active: true,
4579 };
4580
4581 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4583 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4584 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
4585 let active_kp = KpType::new(
4586 |u: &User| Some(&u.active),
4587 |u: &mut User| Some(&mut u.active),
4588 );
4589
4590 let all_keypaths: Vec<PKp<User>> = vec![
4592 PKp::new(name_kp),
4593 PKp::new(age_kp),
4594 PKp::new(score_kp),
4595 PKp::new(active_kp),
4596 ];
4597
4598 let string_kps: Vec<_> = all_keypaths
4600 .iter()
4601 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
4602 .collect();
4603
4604 assert_eq!(string_kps.len(), 1);
4605 assert_eq!(
4606 string_kps[0].get_as::<String>(&user),
4607 Some(&"Akash".to_string())
4608 );
4609
4610 let i32_kps: Vec<_> = all_keypaths
4612 .iter()
4613 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
4614 .collect();
4615
4616 assert_eq!(i32_kps.len(), 1);
4617 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
4618
4619 let f64_kps: Vec<_> = all_keypaths
4621 .iter()
4622 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
4623 .collect();
4624
4625 assert_eq!(f64_kps.len(), 1);
4626 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
4627
4628 let bool_kps: Vec<_> = all_keypaths
4630 .iter()
4631 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
4632 .collect();
4633
4634 assert_eq!(bool_kps.len(), 1);
4635 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
4636 }
4637
4638 #[test]
4639 fn test_pkp_filter_by_struct_type() {
4640 use std::any::TypeId;
4641
4642 #[derive(Debug, PartialEq)]
4643 struct Address {
4644 street: String,
4645 city: String,
4646 }
4647
4648 #[derive(Debug)]
4649 struct User {
4650 name: String,
4651 age: i32,
4652 address: Address,
4653 }
4654
4655 let user = User {
4656 name: "Bob".to_string(),
4657 age: 25,
4658 address: Address {
4659 street: "123 Main St".to_string(),
4660 city: "NYC".to_string(),
4661 },
4662 };
4663
4664 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4666 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4667 let address_kp = KpType::new(
4668 |u: &User| Some(&u.address),
4669 |u: &mut User| Some(&mut u.address),
4670 );
4671
4672 let all_keypaths: Vec<PKp<User>> =
4673 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
4674
4675 let struct_kps: Vec<_> = all_keypaths
4677 .iter()
4678 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
4679 .collect();
4680
4681 assert_eq!(struct_kps.len(), 1);
4682 assert_eq!(
4683 struct_kps[0].get_as::<Address>(&user),
4684 Some(&Address {
4685 street: "123 Main St".to_string(),
4686 city: "NYC".to_string(),
4687 })
4688 );
4689
4690 let primitive_kps: Vec<_> = all_keypaths
4692 .iter()
4693 .filter(|pkp| {
4694 pkp.value_type_id() == TypeId::of::<String>()
4695 || pkp.value_type_id() == TypeId::of::<i32>()
4696 })
4697 .collect();
4698
4699 assert_eq!(primitive_kps.len(), 2);
4700 }
4701
4702 #[test]
4703 fn test_pkp_filter_by_arc_type() {
4704 use std::any::TypeId;
4705 use std::sync::Arc;
4706
4707 #[derive(Debug)]
4708 struct User {
4709 name: String,
4710 shared_data: Arc<String>,
4711 shared_number: Arc<i32>,
4712 }
4713
4714 let user = User {
4715 name: "Charlie".to_string(),
4716 shared_data: Arc::new("shared".to_string()),
4717 shared_number: Arc::new(42),
4718 };
4719
4720 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4722 let shared_data_kp = KpType::new(
4723 |u: &User| Some(&u.shared_data),
4724 |u: &mut User| Some(&mut u.shared_data),
4725 );
4726 let shared_number_kp = KpType::new(
4727 |u: &User| Some(&u.shared_number),
4728 |u: &mut User| Some(&mut u.shared_number),
4729 );
4730
4731 let all_keypaths: Vec<PKp<User>> = vec![
4732 PKp::new(name_kp),
4733 PKp::new(shared_data_kp),
4734 PKp::new(shared_number_kp),
4735 ];
4736
4737 let arc_string_kps: Vec<_> = all_keypaths
4739 .iter()
4740 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
4741 .collect();
4742
4743 assert_eq!(arc_string_kps.len(), 1);
4744 assert_eq!(
4745 arc_string_kps[0]
4746 .get_as::<Arc<String>>(&user)
4747 .map(|arc| arc.as_str()),
4748 Some("shared")
4749 );
4750
4751 let arc_i32_kps: Vec<_> = all_keypaths
4753 .iter()
4754 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
4755 .collect();
4756
4757 assert_eq!(arc_i32_kps.len(), 1);
4758 assert_eq!(
4759 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
4760 Some(42)
4761 );
4762
4763 let all_arc_kps: Vec<_> = all_keypaths
4765 .iter()
4766 .filter(|pkp| {
4767 pkp.value_type_id() == TypeId::of::<Arc<String>>()
4768 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
4769 })
4770 .collect();
4771
4772 assert_eq!(all_arc_kps.len(), 2);
4773 }
4774
4775 #[test]
4776 fn test_pkp_filter_by_box_type() {
4777 use std::any::TypeId;
4778
4779 #[derive(Debug)]
4780 struct User {
4781 name: String,
4782 boxed_value: Box<i32>,
4783 boxed_string: Box<String>,
4784 }
4785
4786 let user = User {
4787 name: "Diana".to_string(),
4788 boxed_value: Box::new(100),
4789 boxed_string: Box::new("boxed".to_string()),
4790 };
4791
4792 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4794 let boxed_value_kp = KpType::new(
4795 |u: &User| Some(&u.boxed_value),
4796 |u: &mut User| Some(&mut u.boxed_value),
4797 );
4798 let boxed_string_kp = KpType::new(
4799 |u: &User| Some(&u.boxed_string),
4800 |u: &mut User| Some(&mut u.boxed_string),
4801 );
4802
4803 let all_keypaths: Vec<PKp<User>> = vec![
4804 PKp::new(name_kp),
4805 PKp::new(boxed_value_kp),
4806 PKp::new(boxed_string_kp),
4807 ];
4808
4809 let box_i32_kps: Vec<_> = all_keypaths
4811 .iter()
4812 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4813 .collect();
4814
4815 assert_eq!(box_i32_kps.len(), 1);
4816 assert_eq!(
4817 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4818 Some(100)
4819 );
4820
4821 let box_string_kps: Vec<_> = all_keypaths
4823 .iter()
4824 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4825 .collect();
4826
4827 assert_eq!(box_string_kps.len(), 1);
4828 assert_eq!(
4829 box_string_kps[0]
4830 .get_as::<Box<String>>(&user)
4831 .map(|b| b.as_str()),
4832 Some("boxed")
4833 );
4834 }
4835
4836 #[test]
4837 fn test_akp_filter_by_root_and_value_type() {
4838 use std::any::TypeId;
4839
4840 #[derive(Debug)]
4841 struct User {
4842 name: String,
4843 age: i32,
4844 }
4845
4846 #[derive(Debug)]
4847 struct Product {
4848 title: String,
4849 price: f64,
4850 }
4851
4852 let user = User {
4853 name: "Eve".to_string(),
4854 age: 28,
4855 };
4856
4857 let product = Product {
4858 title: "Book".to_string(),
4859 price: 19.99,
4860 };
4861
4862 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4864 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4865 let product_title_kp = KpType::new(
4866 |p: &Product| Some(&p.title),
4867 |p: &mut Product| Some(&mut p.title),
4868 );
4869 let product_price_kp = KpType::new(
4870 |p: &Product| Some(&p.price),
4871 |p: &mut Product| Some(&mut p.price),
4872 );
4873
4874 let all_keypaths: Vec<AKp> = vec![
4875 AKp::new(user_name_kp),
4876 AKp::new(user_age_kp),
4877 AKp::new(product_title_kp),
4878 AKp::new(product_price_kp),
4879 ];
4880
4881 let user_kps: Vec<_> = all_keypaths
4883 .iter()
4884 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4885 .collect();
4886
4887 assert_eq!(user_kps.len(), 2);
4888
4889 let product_kps: Vec<_> = all_keypaths
4891 .iter()
4892 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4893 .collect();
4894
4895 assert_eq!(product_kps.len(), 2);
4896
4897 let string_value_kps: Vec<_> = all_keypaths
4899 .iter()
4900 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4901 .collect();
4902
4903 assert_eq!(string_value_kps.len(), 2);
4904
4905 let user_string_kps: Vec<_> = all_keypaths
4907 .iter()
4908 .filter(|akp| {
4909 akp.root_type_id() == TypeId::of::<User>()
4910 && akp.value_type_id() == TypeId::of::<String>()
4911 })
4912 .collect();
4913
4914 assert_eq!(user_string_kps.len(), 1);
4915 assert_eq!(
4916 user_string_kps[0].get_as::<User, String>(&user),
4917 Some(Some(&"Eve".to_string()))
4918 );
4919
4920 let product_f64_kps: Vec<_> = all_keypaths
4922 .iter()
4923 .filter(|akp| {
4924 akp.root_type_id() == TypeId::of::<Product>()
4925 && akp.value_type_id() == TypeId::of::<f64>()
4926 })
4927 .collect();
4928
4929 assert_eq!(product_f64_kps.len(), 1);
4930 assert_eq!(
4931 product_f64_kps[0].get_as::<Product, f64>(&product),
4932 Some(Some(&19.99))
4933 );
4934 }
4935
4936 #[test]
4937 fn test_akp_filter_by_arc_root_type() {
4938 use std::any::TypeId;
4939 use std::sync::Arc;
4940
4941 #[derive(Debug)]
4942 struct User {
4943 name: String,
4944 }
4945
4946 #[derive(Debug)]
4947 struct Product {
4948 title: String,
4949 }
4950
4951 let user = User {
4952 name: "Frank".to_string(),
4953 };
4954 let product = Product {
4955 title: "Laptop".to_string(),
4956 };
4957
4958 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4960 let product_title_kp = KpType::new(
4961 |p: &Product| Some(&p.title),
4962 |p: &mut Product| Some(&mut p.title),
4963 );
4964
4965 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4967 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4968
4969 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4970
4971 let arc_user_kps: Vec<_> = all_keypaths
4973 .iter()
4974 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4975 .collect();
4976
4977 assert_eq!(arc_user_kps.len(), 1);
4978
4979 let arc_user = Arc::new(user);
4981 assert_eq!(
4982 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4983 Some(Some(&"Frank".to_string()))
4984 );
4985
4986 let arc_product_kps: Vec<_> = all_keypaths
4988 .iter()
4989 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4990 .collect();
4991
4992 assert_eq!(arc_product_kps.len(), 1);
4993
4994 let arc_product = Arc::new(product);
4996 assert_eq!(
4997 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4998 Some(Some(&"Laptop".to_string()))
4999 );
5000 }
5001
5002 #[test]
5003 fn test_akp_filter_by_box_root_type() {
5004 use std::any::TypeId;
5005
5006 #[derive(Debug)]
5007 struct Config {
5008 setting: String,
5009 }
5010
5011 let config = Config {
5012 setting: "enabled".to_string(),
5013 };
5014
5015 let config_kp1 = KpType::new(
5017 |c: &Config| Some(&c.setting),
5018 |c: &mut Config| Some(&mut c.setting),
5019 );
5020 let config_kp2 = KpType::new(
5021 |c: &Config| Some(&c.setting),
5022 |c: &mut Config| Some(&mut c.setting),
5023 );
5024
5025 let regular_akp = AKp::new(config_kp1);
5027 let box_akp = AKp::new(config_kp2).for_box::<Config>();
5028
5029 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
5030
5031 let config_kps: Vec<_> = all_keypaths
5033 .iter()
5034 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
5035 .collect();
5036
5037 assert_eq!(config_kps.len(), 1);
5038 assert_eq!(
5039 config_kps[0].get_as::<Config, String>(&config),
5040 Some(Some(&"enabled".to_string()))
5041 );
5042
5043 let box_config_kps: Vec<_> = all_keypaths
5045 .iter()
5046 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
5047 .collect();
5048
5049 assert_eq!(box_config_kps.len(), 1);
5050
5051 let box_config = Box::new(Config {
5053 setting: "enabled".to_string(),
5054 });
5055 assert_eq!(
5056 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
5057 Some(Some(&"enabled".to_string()))
5058 );
5059 }
5060
5061 #[test]
5062 fn test_mixed_collection_type_filtering() {
5063 use std::any::TypeId;
5064 use std::sync::Arc;
5065
5066 #[derive(Debug)]
5067 struct User {
5068 name: String,
5069 email: String,
5070 }
5071
5072 #[derive(Debug)]
5073 struct Product {
5074 title: String,
5075 sku: String,
5076 }
5077
5078 let user = User {
5079 name: "Grace".to_string(),
5080 email: "grace@example.com".to_string(),
5081 };
5082
5083 let product = Product {
5084 title: "Widget".to_string(),
5085 sku: "WID-001".to_string(),
5086 };
5087
5088 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
5090 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
5091 let user_email_kp1 =
5092 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
5093 let user_email_kp2 =
5094 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
5095 let product_title_kp = KpType::new(
5096 |p: &Product| Some(&p.title),
5097 |p: &mut Product| Some(&mut p.title),
5098 );
5099 let product_sku_kp = KpType::new(
5100 |p: &Product| Some(&p.sku),
5101 |p: &mut Product| Some(&mut p.sku),
5102 );
5103
5104 let all_keypaths: Vec<AKp> = vec![
5105 AKp::new(user_name_kp1),
5106 AKp::new(user_email_kp1),
5107 AKp::new(product_title_kp),
5108 AKp::new(product_sku_kp),
5109 AKp::new(user_name_kp2).for_arc::<User>(),
5110 AKp::new(user_email_kp2).for_box::<User>(),
5111 ];
5112
5113 let string_value_kps: Vec<_> = all_keypaths
5115 .iter()
5116 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
5117 .collect();
5118
5119 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
5123 .iter()
5124 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
5125 .collect();
5126
5127 assert_eq!(user_root_kps.len(), 2);
5128
5129 let arc_user_kps: Vec<_> = all_keypaths
5131 .iter()
5132 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
5133 .collect();
5134
5135 assert_eq!(arc_user_kps.len(), 1);
5136
5137 let box_user_kps: Vec<_> = all_keypaths
5139 .iter()
5140 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
5141 .collect();
5142
5143 assert_eq!(box_user_kps.len(), 1);
5144
5145 let product_kps: Vec<_> = all_keypaths
5147 .iter()
5148 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
5149 .collect();
5150
5151 assert_eq!(product_kps.len(), 2);
5152
5153 let user_value = user_root_kps[0].get_as::<User, String>(&user);
5155 assert!(user_value.is_some());
5156 assert!(user_value.unwrap().is_some());
5157 }
5158
5159 #[test]
5164 fn test_kp_with_pin() {
5165 use std::pin::Pin;
5166
5167 #[derive(Debug)]
5171 struct SelfReferential {
5172 value: String,
5173 ptr_to_value: *const String, }
5175
5176 impl SelfReferential {
5177 fn new(s: String) -> Self {
5178 let mut sr = Self {
5179 value: s,
5180 ptr_to_value: std::ptr::null(),
5181 };
5182 sr.ptr_to_value = &sr.value as *const String;
5184 sr
5185 }
5186
5187 fn get_value(&self) -> &str {
5188 &self.value
5189 }
5190 }
5191
5192 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
5194 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
5195
5196 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
5198 |p: &Pin<Box<SelfReferential>>| {
5199 Some(&p.as_ref().get_ref().value)
5201 },
5202 |p: &mut Pin<Box<SelfReferential>>| {
5203 unsafe {
5206 let sr = Pin::get_unchecked_mut(p.as_mut());
5207 Some(&mut sr.value)
5208 }
5209 },
5210 );
5211
5212 let result = kp.get(&pinned);
5214 assert_eq!(result, Some(&"pinned_data".to_string()));
5215
5216 assert_eq!(pinned.get_value(), "pinned_data");
5218 }
5219
5220 #[test]
5221 fn test_kp_with_pin_arc() {
5222 use std::pin::Pin;
5223 use std::sync::Arc;
5224
5225 struct AsyncState {
5226 status: String,
5227 data: Vec<i32>,
5228 }
5229
5230 let state = AsyncState {
5232 status: "ready".to_string(),
5233 data: vec![1, 2, 3, 4, 5],
5234 };
5235
5236 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
5237
5238 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
5240 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
5241 |_: &mut Pin<Arc<AsyncState>>| {
5242 None::<&mut String>
5244 },
5245 );
5246
5247 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
5249 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
5250 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
5251 );
5252
5253 let status = status_kp.get(&pinned_arc);
5254 assert_eq!(status, Some(&"ready".to_string()));
5255
5256 let data = data_kp.get(&pinned_arc);
5257 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
5258 }
5259
5260 #[test]
5261 fn test_kp_with_maybe_uninit() {
5262 use std::mem::MaybeUninit;
5263
5264 struct Config {
5268 name: MaybeUninit<String>,
5269 value: MaybeUninit<i32>,
5270 initialized: bool,
5271 }
5272
5273 impl Config {
5274 fn new_uninit() -> Self {
5275 Self {
5276 name: MaybeUninit::uninit(),
5277 value: MaybeUninit::uninit(),
5278 initialized: false,
5279 }
5280 }
5281
5282 fn init(&mut self, name: String, value: i32) {
5283 self.name.write(name);
5284 self.value.write(value);
5285 self.initialized = true;
5286 }
5287
5288 fn get_name(&self) -> Option<&String> {
5289 if self.initialized {
5290 unsafe { Some(self.name.assume_init_ref()) }
5291 } else {
5292 None
5293 }
5294 }
5295
5296 fn get_value(&self) -> Option<&i32> {
5297 if self.initialized {
5298 unsafe { Some(self.value.assume_init_ref()) }
5299 } else {
5300 None
5301 }
5302 }
5303 }
5304
5305 let name_kp: KpType<Config, String> = Kp::new(
5307 |c: &Config| c.get_name(),
5308 |c: &mut Config| {
5309 if c.initialized {
5310 unsafe { Some(c.name.assume_init_mut()) }
5311 } else {
5312 None
5313 }
5314 },
5315 );
5316
5317 let value_kp: KpType<Config, i32> = Kp::new(
5318 |c: &Config| c.get_value(),
5319 |c: &mut Config| {
5320 if c.initialized {
5321 unsafe { Some(c.value.assume_init_mut()) }
5322 } else {
5323 None
5324 }
5325 },
5326 );
5327
5328 let uninit_config = Config::new_uninit();
5330 assert_eq!(name_kp.get(&uninit_config), None);
5331 assert_eq!(value_kp.get(&uninit_config), None);
5332
5333 let mut init_config = Config::new_uninit();
5335 init_config.init("test_config".to_string(), 42);
5336
5337 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
5338 assert_eq!(value_kp.get(&init_config), Some(&42));
5339
5340 if let Some(val) = value_kp.get_mut(&mut init_config) {
5342 *val = 100;
5343 }
5344
5345 assert_eq!(value_kp.get(&init_config), Some(&100));
5346 }
5347
5348 #[test]
5349 fn test_kp_with_weak() {
5350 use std::sync::{Arc, Weak};
5351
5352 #[derive(Debug, Clone)]
5356 struct Node {
5357 value: i32,
5358 }
5359
5360 struct NodeWithParent {
5361 value: i32,
5362 parent: Option<Arc<Node>>, }
5364
5365 let parent = Arc::new(Node { value: 100 });
5366
5367 let child = NodeWithParent {
5368 value: 42,
5369 parent: Some(parent.clone()),
5370 };
5371
5372 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
5374 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
5375 |_: &mut NodeWithParent| None::<&mut i32>,
5376 );
5377
5378 let parent_val = parent_value_kp.get(&child);
5380 assert_eq!(parent_val, Some(&100));
5381 }
5382
5383 #[test]
5384 fn test_kp_with_rc_weak() {
5385 use std::rc::Rc;
5386
5387 struct TreeNode {
5390 value: String,
5391 parent: Option<Rc<TreeNode>>, }
5393
5394 let root = Rc::new(TreeNode {
5395 value: "root".to_string(),
5396 parent: None,
5397 });
5398
5399 let child1 = TreeNode {
5400 value: "child1".to_string(),
5401 parent: Some(root.clone()),
5402 };
5403
5404 let child2 = TreeNode {
5405 value: "child2".to_string(),
5406 parent: Some(root.clone()),
5407 };
5408
5409 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
5411 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
5412 |_: &mut TreeNode| None::<&mut String>,
5413 );
5414
5415 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
5417 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
5418
5419 assert_eq!(parent_name_kp.get(&root), None);
5421 }
5422
5423 #[test]
5424 fn test_kp_with_complex_weak_structure() {
5425 use std::sync::Arc;
5426
5427 struct Cache {
5430 data: String,
5431 backup: Option<Arc<Cache>>, }
5433
5434 let primary = Arc::new(Cache {
5435 data: "primary_data".to_string(),
5436 backup: None,
5437 });
5438
5439 let backup = Arc::new(Cache {
5440 data: "backup_data".to_string(),
5441 backup: Some(primary.clone()),
5442 });
5443
5444 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
5446 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
5447 |_: &mut Arc<Cache>| None::<&mut String>,
5448 );
5449
5450 let data = backup_data_kp.get(&backup);
5452 assert_eq!(data, Some(&"primary_data".to_string()));
5453
5454 let no_backup = backup_data_kp.get(&primary);
5456 assert_eq!(no_backup, None);
5457 }
5458
5459 #[test]
5460 fn test_kp_chain_with_pin_and_arc() {
5461 use std::pin::Pin;
5462 use std::sync::Arc;
5463
5464 struct Outer {
5467 inner: Arc<Inner>,
5468 }
5469
5470 struct Inner {
5471 value: String,
5472 }
5473
5474 let outer = Outer {
5475 inner: Arc::new(Inner {
5476 value: "nested_value".to_string(),
5477 }),
5478 };
5479
5480 let pinned_outer = Box::pin(outer);
5481
5482 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
5484 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
5485 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
5486 );
5487
5488 let to_value: KpType<Arc<Inner>, String> = Kp::new(
5490 |a: &Arc<Inner>| Some(&a.value),
5491 |_: &mut Arc<Inner>| None::<&mut String>,
5492 );
5493
5494 let chained = to_inner.then(to_value);
5496
5497 let result = chained.get(&pinned_outer);
5498 assert_eq!(result, Some(&"nested_value".to_string()));
5499 }
5500
5501 #[test]
5502 fn test_kp_with_maybe_uninit_array() {
5503 use std::mem::MaybeUninit;
5504
5505 struct Buffer {
5509 data: [MaybeUninit<u8>; 10],
5510 len: usize,
5511 }
5512
5513 impl Buffer {
5514 fn new() -> Self {
5515 Self {
5516 data: unsafe { MaybeUninit::uninit().assume_init() },
5517 len: 0,
5518 }
5519 }
5520
5521 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
5522 if self.len >= self.data.len() {
5523 return Err("Buffer full");
5524 }
5525 self.data[self.len].write(byte);
5526 self.len += 1;
5527 Ok(())
5528 }
5529
5530 fn get(&self, idx: usize) -> Option<&u8> {
5531 if idx < self.len {
5532 unsafe { Some(self.data[idx].assume_init_ref()) }
5533 } else {
5534 None
5535 }
5536 }
5537
5538 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
5539 if idx < self.len {
5540 unsafe { Some(self.data[idx].assume_init_mut()) }
5541 } else {
5542 None
5543 }
5544 }
5545 }
5546
5547 let len_kp: KpType<Buffer, usize> =
5549 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
5550
5551 let mut buffer = Buffer::new();
5552
5553 assert_eq!(len_kp.get(&buffer), Some(&0));
5555
5556 buffer.push(1).unwrap();
5558 buffer.push(2).unwrap();
5559 buffer.push(3).unwrap();
5560
5561 assert_eq!(len_kp.get(&buffer), Some(&3));
5563
5564 assert_eq!(buffer.get(0), Some(&1));
5566 assert_eq!(buffer.get(1), Some(&2));
5567 assert_eq!(buffer.get(2), Some(&3));
5568 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
5572 *elem = 20;
5573 }
5574 assert_eq!(buffer.get(1), Some(&20));
5575 }
5576
5577 #[test]
5578 fn test_kp_then_lock_deep_structs() {
5579 use std::sync::{Arc, Mutex};
5580
5581 #[derive(Clone)]
5582 struct Root {
5583 guard: Arc<Mutex<Level1>>,
5584 }
5585 #[derive(Clone)]
5586 struct Level1 {
5587 name: String,
5588 nested: Level2,
5589 }
5590 #[derive(Clone)]
5591 struct Level2 {
5592 count: i32,
5593 }
5594
5595 let root = Root {
5596 guard: Arc::new(Mutex::new(Level1 {
5597 name: "deep".to_string(),
5598 nested: Level2 { count: 42 },
5599 })),
5600 };
5601
5602 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
5603 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
5604
5605 let lock_kp = {
5606 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> = Kp::new(
5607 |g: &Arc<Mutex<Level1>>| Some(g),
5608 |g: &mut Arc<Mutex<Level1>>| Some(g),
5609 );
5610 let next: KpType<Level1, Level1> =
5611 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5612 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5613 };
5614
5615 let chained = kp_to_guard.then_lock(lock_kp);
5616 let level1 = chained.get(&root);
5617 assert!(level1.is_some());
5618 assert_eq!(level1.unwrap().name, "deep");
5619 assert_eq!(level1.unwrap().nested.count, 42);
5620
5621 let mut_root = &mut root.clone();
5622 let mut_level1 = chained.get_mut(mut_root);
5623 assert!(mut_level1.is_some());
5624 mut_level1.unwrap().nested.count = 99;
5625 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
5626 }
5627
5628 #[test]
5629 fn test_kp_then_lock_with_enum() {
5630 use std::sync::{Arc, Mutex};
5631
5632 #[derive(Clone)]
5633 enum Message {
5634 Request(LevelA),
5635 Response(i32),
5636 }
5637 #[derive(Clone)]
5638 struct LevelA {
5639 data: Arc<Mutex<i32>>,
5640 }
5641
5642 struct RootWithEnum {
5643 msg: Arc<Mutex<Message>>,
5644 }
5645
5646 let root = RootWithEnum {
5647 msg: Arc::new(Mutex::new(Message::Request(LevelA {
5648 data: Arc::new(Mutex::new(100)),
5649 }))),
5650 };
5651
5652 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> = Kp::new(
5653 |r: &RootWithEnum| Some(&r.msg),
5654 |r: &mut RootWithEnum| Some(&mut r.msg),
5655 );
5656
5657 let lock_kp_msg = {
5658 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> = Kp::new(
5659 |m: &Arc<Mutex<Message>>| Some(m),
5660 |m: &mut Arc<Mutex<Message>>| Some(m),
5661 );
5662 let next: KpType<Message, Message> =
5663 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
5664 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
5665 };
5666
5667 let chained = kp_msg.then_lock(lock_kp_msg);
5668 let msg = chained.get(&root);
5669 assert!(msg.is_some());
5670 match msg.unwrap() {
5671 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
5672 Message::Response(_) => panic!("expected Request"),
5673 }
5674 }
5675
5676 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5677 #[tokio::test]
5678 async fn test_kp_then_async_deep_chain() {
5679 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5680 use std::sync::Arc;
5681
5682 #[derive(Clone)]
5683 struct Root {
5684 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
5685 }
5686 #[derive(Clone)]
5687 struct Level1 {
5688 value: i32,
5689 }
5690
5691 let root = Root {
5692 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
5693 };
5694
5695 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
5696 |r: &Root| Some(&r.tokio_guard),
5697 |r: &mut Root| Some(&mut r.tokio_guard),
5698 );
5699
5700 let async_kp = {
5701 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
5702 Kp::new(
5703 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
5704 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
5705 );
5706 let next: KpType<Level1, Level1> =
5707 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5708 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5709 };
5710
5711 let chained = kp_to_guard.then_async(async_kp);
5712 let level1 = chained.get(&root).await;
5713 assert!(level1.is_some());
5714 assert_eq!(level1.unwrap().value, 7);
5715 }
5716
5717 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
5720 #[tokio::test]
5721 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
5722 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
5723 use crate::lock::{ArcMutexAccess, LockKp};
5724 use std::sync::{Arc, Mutex};
5725
5726 #[derive(Clone)]
5728 struct Root {
5729 sync_mutex: Arc<Mutex<Level1>>,
5730 }
5731 #[derive(Clone)]
5733 struct Level1 {
5734 inner: Level2,
5735 }
5736 #[derive(Clone)]
5738 struct Level2 {
5739 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
5740 }
5741 #[derive(Clone)]
5743 struct Level3 {
5744 leaf: i32,
5745 }
5746
5747 let mut root = Root {
5748 sync_mutex: Arc::new(Mutex::new(Level1 {
5749 inner: Level2 {
5750 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
5751 },
5752 })),
5753 };
5754
5755 let identity_l1: KpType<Level1, Level1> =
5757 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
5758 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
5759 |r: &Root| Some(&r.sync_mutex),
5760 |r: &mut Root| Some(&mut r.sync_mutex),
5761 );
5762 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
5763
5764 let kp_l1_inner: KpType<Level1, Level2> = Kp::new(
5766 |l: &Level1| Some(&l.inner),
5767 |l: &mut Level1| Some(&mut l.inner),
5768 );
5769
5770 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
5772 |l: &Level2| Some(&l.tokio_mutex),
5773 |l: &mut Level2| Some(&mut l.tokio_mutex),
5774 );
5775
5776 let async_l3 = {
5778 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
5779 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
5780 let next: KpType<Level3, Level3> =
5781 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
5782 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5783 };
5784
5785 let kp_l3_leaf: KpType<Level3, i32> = Kp::new(
5787 |l: &Level3| Some(&l.leaf),
5788 |l: &mut Level3| Some(&mut l.leaf),
5789 );
5790
5791 let step1 = lock_root_to_l1.then(kp_l1_inner);
5793 let step2 = step1.then(kp_l2_tokio);
5794 let step3 = step2.then_async(async_l3);
5795 let deep_chain = step3.then(kp_l3_leaf);
5796
5797 let leaf = deep_chain.get(&root).await;
5799 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5800 assert_eq!(leaf, Some(&100));
5801
5802 let mut root_mut = root.clone();
5804 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5805 assert!(leaf_mut.is_some());
5806 *leaf_mut.unwrap() = 99;
5807
5808 let leaf_after = deep_chain.get(&root_mut).await;
5810 assert_eq!(leaf_after, Some(&99));
5811 }
5812}