1use std::fmt;
14use std::sync::Arc;
15
16pub mod sync_kp;
18pub mod prelude;
19
20pub use sync_kp::{
21 ArcMutexAccess, ArcRwLockAccess, LockAccess, SyncKp, SyncKpType, RcRefCellAccess,
22 StdMutexAccess, StdRwLockAccess,
23};
24
25#[cfg(feature = "parking_lot")]
26pub use sync_kp::{
27 DirectParkingLotMutexAccess, DirectParkingLotRwLockAccess, ParkingLotMutexAccess,
28 ParkingLotRwLockAccess,
29};
30
31#[cfg(feature = "arc-swap")]
32pub use sync_kp::{ArcArcSwapAccess, ArcArcSwapOptionAccess};
33
34pub mod async_lock;
36
37pub mod kptrait;
38
39pub use kptrait::{
40 AccessorTrait, ChainExt, CoercionTrait, HofTrait, KeyPathValueTarget, KpReadable, KpTrait,
41 KPWritable,
42};
43
44#[cfg(feature = "pin_project")]
87pub mod pin;
88
89#[macro_export]
91macro_rules! keypath {
92 { $root:ident . $field:ident } => { $root::$field() };
93 { $root:ident . $field:ident . $($ty:ident . $f:ident).+ } => {
94 $root::$field() $(.then($ty::$f()))+
95 };
96 ($root:ident . $field:ident) => { $root::$field() };
97 ($root:ident . $field:ident . $($ty:ident . $f:ident).+) => {
98 $root::$field() $(.then($ty::$f()))+
99 };
100}
101
102#[macro_export]
106macro_rules! get_or {
107 ($kp:expr, $root:expr, $default:expr) => {
108 $kp.get($root).unwrap_or($default)
109 };
110 ($root:expr => $($path:tt)*, $default:expr) => {
111 $crate::get_or!($crate::keypath!($($path)*), $root, $default)
112 };
113}
114
115#[macro_export]
120macro_rules! get_or_else {
121 ($kp:expr, $root:expr, $closure:expr) => {
122 $kp.get($root).map(|r| r.clone()).unwrap_or_else($closure)
123 };
124 ($root:expr => ($($path:tt)*), $closure:expr) => {
125 $crate::get_or_else!($crate::keypath!($($path)*), $root, $closure)
126 };
127}
128
129#[macro_export]
150macro_rules! zip_with_kp {
151 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr) => {
152 match ($kp1.get($root), $kp2.get($root)) {
153 (Some(__a), Some(__b)) => Some($closure((__a, __b))),
154 _ => None,
155 }
156 };
157 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr) => {
158 match ($kp1.get($root), $kp2.get($root), $kp3.get($root)) {
159 (Some(__a), Some(__b), Some(__c)) => Some($closure((__a, __b, __c))),
160 _ => None,
161 }
162 };
163 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr) => {
164 match (
165 $kp1.get($root),
166 $kp2.get($root),
167 $kp3.get($root),
168 $kp4.get($root),
169 ) {
170 (Some(__a), Some(__b), Some(__c), Some(__d)) => Some($closure((__a, __b, __c, __d))),
171 _ => None,
172 }
173 };
174 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr) => {
175 match (
176 $kp1.get($root),
177 $kp2.get($root),
178 $kp3.get($root),
179 $kp4.get($root),
180 $kp5.get($root),
181 ) {
182 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e)) => {
183 Some($closure((__a, __b, __c, __d, __e)))
184 }
185 _ => None,
186 }
187 };
188 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr, $kp6:expr) => {
189 match (
190 $kp1.get($root),
191 $kp2.get($root),
192 $kp3.get($root),
193 $kp4.get($root),
194 $kp5.get($root),
195 $kp6.get($root),
196 ) {
197 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e), Some(__f)) => {
198 Some($closure((__a, __b, __c, __d, __e, __f)))
199 }
200 _ => None,
201 }
202 };
203}
204
205pub type KpValue<'a, R, V> = Kp<
207 R,
208 V,
209 &'a R,
210 V, &'a mut R,
212 V, for<'b> fn(&'b R) -> Option<V>,
214 for<'b> fn(&'b mut R) -> Option<V>,
215>;
216
217pub type KpOwned<R, V> = Kp<
219 R,
220 V,
221 R,
222 V, R,
224 V, fn(R) -> Option<V>,
226 fn(R) -> Option<V>,
227>;
228
229pub type KpRoot<R> = Kp<
231 R,
232 R,
233 R,
234 R, R,
236 R, fn(R) -> Option<R>,
238 fn(R) -> Option<R>,
239>;
240
241pub type KpVoid = Kp<(), (), (), (), (), (), fn() -> Option<()>, fn() -> Option<()>>;
243
244pub type KpDynamic<R, V> = Kp<
245 R,
246 V,
247 &'static R,
248 &'static V,
249 &'static mut R,
250 &'static mut V,
251 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
252 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
253>;
254
255pub type KpBox<'a, R, V> = Kp<
256 R,
257 V,
258 &'a R,
259 &'a V,
260 &'a mut R,
261 &'a mut V,
262 Box<dyn Fn(&'a R) -> Option<&'a V> + 'a>,
263 Box<dyn Fn(&'a mut R) -> Option<&'a mut V> + 'a>,
264>;
265
266pub type KpArc<'a, R, V> = Kp<
267 R,
268 V,
269 &'a R,
270 &'a V,
271 &'a mut R,
272 &'a mut V,
273 Arc<dyn Fn(&'a R) -> Option<&'a V> + Send + Sync + 'a>,
274 Arc<dyn Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync + 'a>,
275>;
276
277pub type KpType<'a, R, V> = Kp<
278 R,
279 V,
280 &'a R,
281 &'a V,
282 &'a mut R,
283 &'a mut V,
284 for<'b> fn(&'b R) -> Option<&'b V>,
285 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
286>;
287
288pub type KpTraitType<'a, R, V> = dyn KpTrait<
289 R,
290 V,
291 &'a R,
292 &'a V,
293 &'a mut R,
294 &'a mut V,
295 for<'b> fn(&'b R) -> Option<&'b V>,
296 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
297 >;
298
299pub type KpOptionRefCellType<'a, R, V> = Kp<
302 R,
303 V,
304 &'a R,
305 std::cell::Ref<'a, V>,
306 &'a mut R,
307 std::cell::RefMut<'a, V>,
308 for<'b> fn(&'b R) -> Option<std::cell::Ref<'b, V>>,
309 for<'b> fn(&'b mut R) -> Option<std::cell::RefMut<'b, V>>,
310>;
311
312impl<'a, R, V> KpType<'a, R, V> {
313 #[inline]
315 pub fn to_dynamic(self) -> KpDynamic<R, V> {
316 self.into()
317 }
318}
319
320impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V> {
321 #[inline]
322 fn from(kp: KpType<'a, R, V>) -> Self {
323 let get_fn = kp.get;
324 let set_fn = kp.set;
325 Kp::new(
326 Box::new(move |t: &R| get_fn(t)),
327 Box::new(move |t: &mut R| set_fn(t)),
328 )
329 }
330}
331
332impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
333where
334 Root: std::borrow::Borrow<R>,
335 Value: std::borrow::Borrow<V>,
336 MutRoot: std::borrow::BorrowMut<R>,
337 MutValue: std::borrow::BorrowMut<V>,
338 G: Fn(Root) -> Option<Value> + Send + Sync + 'static,
339 S: Fn(MutRoot) -> Option<MutValue> + Send + Sync + 'static,
340 R: 'static,
341 V: 'static,
342{
343 #[inline]
357 pub fn into_dynamic(self) -> KpDynamic<R, V> {
358 let g = self.get;
359 let s = self.set;
360 Kp::new(
361 Box::new(move |t: &R| unsafe {
362 let root: Root = std::mem::transmute_copy(&t);
365 match g(root) {
366 None => None,
367 Some(v) => {
368 let r: &V = std::borrow::Borrow::borrow(&v);
369 Some(std::mem::transmute::<&V, &V>(r))
371 }
372 }
373 }),
374 Box::new(move |t: &mut R| unsafe {
375 let root: MutRoot = std::mem::transmute_copy(&t);
377 match s(root) {
378 None => None,
379 Some(mut v) => {
380 let r: &mut V = std::borrow::BorrowMut::borrow_mut(&mut v);
381 Some(std::mem::transmute::<&mut V, &mut V>(r))
382 }
383 }
384 }),
385 )
386 }
387}
388
389pub type KpComposed<R, V> = Kp<
425 R,
426 V,
427 &'static R,
428 &'static V,
429 &'static mut R,
430 &'static mut V,
431 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
432 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
433>;
434
435impl<R, V>
436 Kp<
437 R,
438 V,
439 &'static R,
440 &'static V,
441 &'static mut R,
442 &'static mut V,
443 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
444 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
445 >
446{
447 pub fn from_closures<G, S>(get: G, set: S) -> Self
450 where
451 G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
452 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
453 {
454 Self::new(Box::new(get), Box::new(set))
455 }
456}
457
458pub struct AKp {
459 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
460 root_type_id: TypeId,
461 value_type_id: TypeId,
462}
463
464impl AKp {
465 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
467 where
468 R: Any + 'static,
469 V: Any + 'static,
470 {
471 let root_type_id = TypeId::of::<R>();
472 let value_type_id = TypeId::of::<V>();
473 let getter_fn = keypath.get;
474
475 Self {
476 getter: Rc::new(move |any: &dyn Any| {
477 if let Some(root) = any.downcast_ref::<R>() {
478 getter_fn(root).map(|value: &V| value as &dyn Any)
479 } else {
480 None
481 }
482 }),
483 root_type_id,
484 value_type_id,
485 }
486 }
487
488 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
490 where
491 R: Any + 'static,
492 V: Any + 'static,
493 {
494 Self::new(keypath)
495 }
496
497 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
499 (self.getter)(root)
500 }
501
502 pub fn root_type_id(&self) -> TypeId {
504 self.root_type_id
505 }
506
507 pub fn value_type_id(&self) -> TypeId {
509 self.value_type_id
510 }
511
512 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
514 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
515 {
516 Some(
517 self.get(root as &dyn Any)
518 .and_then(|any| any.downcast_ref::<Value>()),
519 )
520 } else {
521 None
522 }
523 }
524
525 pub fn kind_name(&self) -> String {
527 format!("{:?}", self.value_type_id)
528 }
529
530 pub fn root_kind_name(&self) -> String {
532 format!("{:?}", self.root_type_id)
533 }
534
535 pub fn for_arc<Root>(&self) -> AKp
537 where
538 Root: Any + 'static,
539 {
540 let value_type_id = self.value_type_id;
541 let getter = self.getter.clone();
542
543 AKp {
544 getter: Rc::new(move |any: &dyn Any| {
545 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
546 getter(arc.as_ref() as &dyn Any)
547 } else {
548 None
549 }
550 }),
551 root_type_id: TypeId::of::<Arc<Root>>(),
552 value_type_id,
553 }
554 }
555
556 pub fn for_box<Root>(&self) -> AKp
558 where
559 Root: Any + 'static,
560 {
561 let value_type_id = self.value_type_id;
562 let getter = self.getter.clone();
563
564 AKp {
565 getter: Rc::new(move |any: &dyn Any| {
566 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
567 getter(boxed.as_ref() as &dyn Any)
568 } else {
569 None
570 }
571 }),
572 root_type_id: TypeId::of::<Box<Root>>(),
573 value_type_id,
574 }
575 }
576
577 pub fn for_rc<Root>(&self) -> AKp
579 where
580 Root: Any + 'static,
581 {
582 let value_type_id = self.value_type_id;
583 let getter = self.getter.clone();
584
585 AKp {
586 getter: Rc::new(move |any: &dyn Any| {
587 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
588 getter(rc.as_ref() as &dyn Any)
589 } else {
590 None
591 }
592 }),
593 root_type_id: TypeId::of::<Rc<Root>>(),
594 value_type_id,
595 }
596 }
597
598 pub fn for_option<Root>(&self) -> AKp
600 where
601 Root: Any + 'static,
602 {
603 let value_type_id = self.value_type_id;
604 let getter = self.getter.clone();
605
606 AKp {
607 getter: Rc::new(move |any: &dyn Any| {
608 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
609 opt.as_ref().and_then(|root| getter(root as &dyn Any))
610 } else {
611 None
612 }
613 }),
614 root_type_id: TypeId::of::<Option<Root>>(),
615 value_type_id,
616 }
617 }
618
619 pub fn for_result<Root, E>(&self) -> AKp
621 where
622 Root: Any + 'static,
623 E: Any + 'static,
624 {
625 let value_type_id = self.value_type_id;
626 let getter = self.getter.clone();
627
628 AKp {
629 getter: Rc::new(move |any: &dyn Any| {
630 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
631 result
632 .as_ref()
633 .ok()
634 .and_then(|root| getter(root as &dyn Any))
635 } else {
636 None
637 }
638 }),
639 root_type_id: TypeId::of::<Result<Root, E>>(),
640 value_type_id,
641 }
642 }
643
644 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
657 where
658 Root: Any + 'static,
659 OrigValue: Any + 'static,
660 MappedValue: Any + 'static,
661 F: Fn(&OrigValue) -> MappedValue + 'static,
662 {
663 let orig_root_type_id = self.root_type_id;
664 let orig_value_type_id = self.value_type_id;
665 let getter = self.getter.clone();
666 let mapped_type_id = TypeId::of::<MappedValue>();
667
668 AKp {
669 getter: Rc::new(move |any_root: &dyn Any| {
670 if any_root.type_id() == orig_root_type_id {
672 getter(any_root).and_then(|any_value| {
673 if orig_value_type_id == TypeId::of::<OrigValue>() {
675 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
676 let mapped = mapper(orig_val);
677 Box::leak(Box::new(mapped)) as &dyn Any
679 })
680 } else {
681 None
682 }
683 })
684 } else {
685 None
686 }
687 }),
688 root_type_id: orig_root_type_id,
689 value_type_id: mapped_type_id,
690 }
691 }
692
693 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
706 where
707 Root: Any + 'static,
708 Value: Any + 'static,
709 F: Fn(&Value) -> bool + 'static,
710 {
711 let orig_root_type_id = self.root_type_id;
712 let orig_value_type_id = self.value_type_id;
713 let getter = self.getter.clone();
714
715 AKp {
716 getter: Rc::new(move |any_root: &dyn Any| {
717 if any_root.type_id() == orig_root_type_id {
719 getter(any_root).filter(|any_value| {
720 if orig_value_type_id == TypeId::of::<Value>() {
722 any_value
723 .downcast_ref::<Value>()
724 .map(|val| predicate(val))
725 .unwrap_or(false)
726 } else {
727 false
728 }
729 })
730 } else {
731 None
732 }
733 }),
734 root_type_id: orig_root_type_id,
735 value_type_id: orig_value_type_id,
736 }
737 }
738}
739
740impl fmt::Debug for AKp {
741 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
742 f.debug_struct("AKp")
743 .field("root_type_id", &self.root_type_id)
744 .field("value_type_id", &self.value_type_id)
745 .finish_non_exhaustive()
746 }
747}
748
749impl fmt::Display for AKp {
750 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
751 write!(
752 f,
753 "AKp(root_type_id={:?}, value_type_id={:?})",
754 self.root_type_id, self.value_type_id
755 )
756 }
757}
758
759pub struct PKp<Root> {
760 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
761 value_type_id: TypeId,
762 _phantom: std::marker::PhantomData<Root>,
763}
764
765impl<Root> PKp<Root>
766where
767 Root: 'static,
768{
769 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
771 where
772 V: Any + 'static,
773 {
774 let value_type_id = TypeId::of::<V>();
775 let getter_fn = keypath.get;
776
777 Self {
778 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
779 value_type_id,
780 _phantom: std::marker::PhantomData,
781 }
782 }
783
784 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
786 where
787 V: Any + 'static,
788 {
789 Self::new(keypath)
790 }
791
792 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
794 (self.getter)(root)
795 }
796
797 pub fn value_type_id(&self) -> TypeId {
799 self.value_type_id
800 }
801
802 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
804 if self.value_type_id == TypeId::of::<Value>() {
805 self.get(root).and_then(|any| any.downcast_ref::<Value>())
806 } else {
807 None
808 }
809 }
810
811 pub fn kind_name(&self) -> String {
813 format!("{:?}", self.value_type_id)
814 }
815
816 pub fn for_arc(&self) -> PKp<Arc<Root>> {
818 let getter = self.getter.clone();
819 let value_type_id = self.value_type_id;
820
821 PKp {
822 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
823 value_type_id,
824 _phantom: std::marker::PhantomData,
825 }
826 }
827
828 pub fn for_box(&self) -> PKp<Box<Root>> {
830 let getter = self.getter.clone();
831 let value_type_id = self.value_type_id;
832
833 PKp {
834 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
835 value_type_id,
836 _phantom: std::marker::PhantomData,
837 }
838 }
839
840 pub fn for_rc(&self) -> PKp<Rc<Root>> {
842 let getter = self.getter.clone();
843 let value_type_id = self.value_type_id;
844
845 PKp {
846 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
847 value_type_id,
848 _phantom: std::marker::PhantomData,
849 }
850 }
851
852 pub fn for_option(&self) -> PKp<Option<Root>> {
854 let getter = self.getter.clone();
855 let value_type_id = self.value_type_id;
856
857 PKp {
858 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
859 value_type_id,
860 _phantom: std::marker::PhantomData,
861 }
862 }
863
864 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
866 where
867 E: 'static,
868 {
869 let getter = self.getter.clone();
870 let value_type_id = self.value_type_id;
871
872 PKp {
873 getter: Rc::new(move |result: &Result<Root, E>| {
874 result.as_ref().ok().and_then(|root| getter(root))
875 }),
876 value_type_id,
877 _phantom: std::marker::PhantomData,
878 }
879 }
880
881 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
895 where
896 OrigValue: Any + 'static,
897 MappedValue: Any + 'static,
898 F: Fn(&OrigValue) -> MappedValue + 'static,
899 {
900 let orig_type_id = self.value_type_id;
901 let getter = self.getter.clone();
902 let mapped_type_id = TypeId::of::<MappedValue>();
903
904 PKp {
905 getter: Rc::new(move |root: &Root| {
906 getter(root).and_then(|any_value| {
907 if orig_type_id == TypeId::of::<OrigValue>() {
909 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
910 let mapped = mapper(orig_val);
911 Box::leak(Box::new(mapped)) as &dyn Any
914 })
915 } else {
916 None
917 }
918 })
919 }),
920 value_type_id: mapped_type_id,
921 _phantom: std::marker::PhantomData,
922 }
923 }
924
925 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
939 where
940 Value: Any + 'static,
941 F: Fn(&Value) -> bool + 'static,
942 {
943 let orig_type_id = self.value_type_id;
944 let getter = self.getter.clone();
945
946 PKp {
947 getter: Rc::new(move |root: &Root| {
948 getter(root).filter(|any_value| {
949 if orig_type_id == TypeId::of::<Value>() {
951 any_value
952 .downcast_ref::<Value>()
953 .map(|val| predicate(val))
954 .unwrap_or(false)
955 } else {
956 false
957 }
958 })
959 }),
960 value_type_id: orig_type_id,
961 _phantom: std::marker::PhantomData,
962 }
963 }
964}
965
966impl<Root> fmt::Debug for PKp<Root> {
967 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
968 f.debug_struct("PKp")
969 .field("root_ty", &std::any::type_name::<Root>())
970 .field("value_type_id", &self.value_type_id)
971 .finish_non_exhaustive()
972 }
973}
974
975impl<Root> fmt::Display for PKp<Root> {
976 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
977 write!(
978 f,
979 "PKp<{}, value_type_id={:?}>",
980 std::any::type_name::<Root>(),
981 self.value_type_id
982 )
983 }
984}
985
986#[derive(Clone)]
1004pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1005where
1006 Root: std::borrow::Borrow<R>,
1007 MutRoot: std::borrow::BorrowMut<R>,
1008 MutValue: std::borrow::BorrowMut<V>,
1009 G: Fn(Root) -> Option<Value>,
1010 S: Fn(MutRoot) -> Option<MutValue>,
1011{
1012 get: G,
1014 set: S,
1016 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
1017}
1018
1019#[inline]
1021pub fn constrain_get<R, V, F>(f: F) -> F
1022where
1023 F: for<'b> Fn(&'b R) -> Option<&'b V>,
1024{
1025 f
1026}
1027
1028#[inline]
1030pub fn constrain_set<R, V, F>(f: F) -> F
1031where
1032 F: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1033{
1034 f
1035}
1036
1037impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1038where
1039 Root: std::borrow::Borrow<R>,
1040 Value: std::borrow::Borrow<V>,
1041 MutRoot: std::borrow::BorrowMut<R>,
1042 MutValue: std::borrow::BorrowMut<V>,
1043 G: Fn(Root) -> Option<Value>,
1044 S: Fn(MutRoot) -> Option<MutValue>,
1045{
1046 pub fn new(get: G, set: S) -> Self {
1047 Self {
1048 get,
1049 set,
1050 _p: std::marker::PhantomData,
1051 }
1052 }
1053
1054 #[inline]
1057 pub fn get(&self, root: Root) -> Option<Value> {
1058 (self.get)(root)
1059 }
1060
1061 #[inline]
1063 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1064 (self.set)(root)
1065 }
1066
1067 #[inline]
1070 pub fn get_ref<'a>(&self, root: &'a R) -> Option<&'a V>
1071 where
1072 G: for<'b> Fn(&'b R) -> Option<&'b V>,
1073 {
1074 (self.get)(root)
1075 }
1076
1077 #[inline]
1079 pub fn get_mut_ref<'a>(&self, root: &'a mut R) -> Option<&'a mut V>
1080 where
1081 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1082 {
1083 (self.set)(root)
1084 }
1085
1086 #[inline]
1087 pub fn then<SV, G2, S2>(
1088 self,
1089 next: Kp<
1090 V,
1091 SV,
1092 &'static V, &'static SV,
1094 &'static mut V,
1095 &'static mut SV,
1096 G2,
1097 S2,
1098 >,
1099 ) -> Kp<
1100 R,
1101 SV,
1102 &'static R,
1103 &'static SV,
1104 &'static mut R,
1105 &'static mut SV,
1106 impl for<'b> Fn(&'b R) -> Option<&'b SV>,
1107 impl for<'b> Fn(&'b mut R) -> Option<&'b mut SV>,
1108 >
1109 where
1110 G: for<'b> Fn(&'b R) -> Option<&'b V>,
1111 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1112 G2: for<'b> Fn(&'b V) -> Option<&'b SV>,
1113 S2: for<'b> Fn(&'b mut V) -> Option<&'b mut SV>,
1114 {
1115 let first_get = self.get;
1116 let first_set = self.set;
1117 let second_get = next.get;
1118 let second_set = next.set;
1119
1120 Kp::new(
1121 constrain_get(move |root: &R| first_get(root).and_then(|value| second_get(value))),
1122 constrain_set(move |root: &mut R| first_set(root).and_then(|value| second_set(value))),
1123 )
1124 }
1125
1126}
1127
1128impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Debug
1129 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1130where
1131 Root: std::borrow::Borrow<R>,
1132 Value: std::borrow::Borrow<V>,
1133 MutRoot: std::borrow::BorrowMut<R>,
1134 MutValue: std::borrow::BorrowMut<V>,
1135 G: Fn(Root) -> Option<Value>,
1136 S: Fn(MutRoot) -> Option<MutValue>,
1137{
1138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1139 f.debug_struct("Kp")
1140 .field("root_ty", &std::any::type_name::<R>())
1141 .field("value_ty", &std::any::type_name::<V>())
1142 .finish_non_exhaustive()
1143 }
1144}
1145
1146impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Display
1147 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1148where
1149 Root: std::borrow::Borrow<R>,
1150 Value: std::borrow::Borrow<V>,
1151 MutRoot: std::borrow::BorrowMut<R>,
1152 MutValue: std::borrow::BorrowMut<V>,
1153 G: Fn(Root) -> Option<Value>,
1154 S: Fn(MutRoot) -> Option<MutValue>,
1155{
1156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1157 write!(
1158 f,
1159 "Kp<{}, {}>",
1160 std::any::type_name::<R>(),
1161 std::any::type_name::<V>()
1162 )
1163 }
1164}
1165
1166pub fn zip_kps<'a, RootType, Value1, Value2>(
1180 kp1: &'a KpType<'a, RootType, Value1>,
1181 kp2: &'a KpType<'a, RootType, Value2>,
1182) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1183where
1184 RootType: 'a,
1185 Value1: 'a,
1186 Value2: 'a,
1187{
1188 move |root: &'a RootType| {
1189 let val1 = (kp1.get)(root)?;
1190 let val2 = (kp2.get)(root)?;
1191 Some((val1, val2))
1192 }
1193}
1194
1195impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1196where
1197 Root: std::borrow::Borrow<R>,
1198 MutRoot: std::borrow::BorrowMut<R>,
1199 G: Fn(Root) -> Option<Root>,
1200 S: Fn(MutRoot) -> Option<MutRoot>,
1201{
1202 pub fn identity_typed() -> Kp<
1203 R,
1204 R,
1205 Root,
1206 Root,
1207 MutRoot,
1208 MutRoot,
1209 fn(Root) -> Option<Root>,
1210 fn(MutRoot) -> Option<MutRoot>,
1211 > {
1212 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1213 }
1214
1215 pub fn identity<'a>() -> KpType<'a, R, R> {
1216 KpType::new(|r| Some(r), |r| Some(r))
1217 }
1218}
1219
1220pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1229where
1230 Root: std::borrow::Borrow<Enum>,
1231 Value: std::borrow::Borrow<Variant>,
1232 MutRoot: std::borrow::BorrowMut<Enum>,
1233 MutValue: std::borrow::BorrowMut<Variant>,
1234 G: Fn(Root) -> Option<Value>,
1235 S: Fn(MutRoot) -> Option<MutValue>,
1236 E: Fn(Variant) -> Enum,
1237{
1238 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1239 embedder: E,
1240}
1241
1242unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1244 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1245where
1246 Root: std::borrow::Borrow<Enum>,
1247 Value: std::borrow::Borrow<Variant>,
1248 MutRoot: std::borrow::BorrowMut<Enum>,
1249 MutValue: std::borrow::BorrowMut<Variant>,
1250 G: Fn(Root) -> Option<Value> + Send,
1251 S: Fn(MutRoot) -> Option<MutValue> + Send,
1252 E: Fn(Variant) -> Enum + Send,
1253{
1254}
1255unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1256 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1257where
1258 Root: std::borrow::Borrow<Enum>,
1259 Value: std::borrow::Borrow<Variant>,
1260 MutRoot: std::borrow::BorrowMut<Enum>,
1261 MutValue: std::borrow::BorrowMut<Variant>,
1262 G: Fn(Root) -> Option<Value> + Sync,
1263 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1264 E: Fn(Variant) -> Enum + Sync,
1265{
1266}
1267
1268impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1269 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1270where
1271 Root: std::borrow::Borrow<Enum>,
1272 Value: std::borrow::Borrow<Variant>,
1273 MutRoot: std::borrow::BorrowMut<Enum>,
1274 MutValue: std::borrow::BorrowMut<Variant>,
1275 G: Fn(Root) -> Option<Value>,
1276 S: Fn(MutRoot) -> Option<MutValue>,
1277 E: Fn(Variant) -> Enum,
1278{
1279 pub fn new(
1281 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1282 embedder: E,
1283 ) -> Self {
1284 Self {
1285 extractor,
1286 embedder,
1287 }
1288 }
1289
1290 pub fn get(&self, enum_value: Root) -> Option<Value> {
1292 (self.extractor.get)(enum_value)
1293 }
1294
1295 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1297 (self.extractor.set)(enum_value)
1298 }
1299
1300 pub fn embed(&self, value: Variant) -> Enum {
1302 (self.embedder)(value)
1303 }
1304
1305 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1307 &self.extractor
1308 }
1309
1310 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1312 self.extractor
1313 }
1314
1315 pub fn map<MappedValue, F>(
1326 &self,
1327 mapper: F,
1328 ) -> EnumKp<
1329 Enum,
1330 MappedValue,
1331 Root,
1332 MappedValue,
1333 MutRoot,
1334 MappedValue,
1335 impl Fn(Root) -> Option<MappedValue>,
1336 impl Fn(MutRoot) -> Option<MappedValue>,
1337 impl Fn(MappedValue) -> Enum,
1338 >
1339 where
1340 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1343 Variant: 'static,
1344 MappedValue: 'static,
1345 E: Fn(Variant) -> Enum + Copy + 'static,
1347 {
1348 let mapped_extractor = self.extractor.map(mapper);
1349
1350 let new_embedder = move |_value: MappedValue| -> Enum {
1354 panic!(
1355 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1356 )
1357 };
1358
1359 EnumKp::new(mapped_extractor, new_embedder)
1360 }
1361
1362 pub fn filter<F>(
1374 &self,
1375 predicate: F,
1376 ) -> EnumKp<
1377 Enum,
1378 Variant,
1379 Root,
1380 Value,
1381 MutRoot,
1382 MutValue,
1383 impl Fn(Root) -> Option<Value>,
1384 impl Fn(MutRoot) -> Option<MutValue>,
1385 E,
1386 >
1387 where
1388 F: Fn(&Variant) -> bool + Copy + 'static,
1391 Variant: 'static,
1392 E: Copy,
1394 {
1395 let filtered_extractor = self.extractor.filter(predicate);
1396 EnumKp::new(filtered_extractor, self.embedder)
1397 }
1398}
1399
1400impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Debug
1401 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1402where
1403 Root: std::borrow::Borrow<Enum>,
1404 Value: std::borrow::Borrow<Variant>,
1405 MutRoot: std::borrow::BorrowMut<Enum>,
1406 MutValue: std::borrow::BorrowMut<Variant>,
1407 G: Fn(Root) -> Option<Value>,
1408 S: Fn(MutRoot) -> Option<MutValue>,
1409 E: Fn(Variant) -> Enum,
1410{
1411 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1412 f.debug_struct("EnumKp")
1413 .field("enum_ty", &std::any::type_name::<Enum>())
1414 .field("variant_ty", &std::any::type_name::<Variant>())
1415 .finish_non_exhaustive()
1416 }
1417}
1418
1419impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Display
1420 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1421where
1422 Root: std::borrow::Borrow<Enum>,
1423 Value: std::borrow::Borrow<Variant>,
1424 MutRoot: std::borrow::BorrowMut<Enum>,
1425 MutValue: std::borrow::BorrowMut<Variant>,
1426 G: Fn(Root) -> Option<Value>,
1427 S: Fn(MutRoot) -> Option<MutValue>,
1428 E: Fn(Variant) -> Enum,
1429{
1430 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1431 write!(
1432 f,
1433 "EnumKp<{}, {}>",
1434 std::any::type_name::<Enum>(),
1435 std::any::type_name::<Variant>()
1436 )
1437 }
1438}
1439
1440pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1442 Enum,
1443 Variant,
1444 &'a Enum,
1445 &'a Variant,
1446 &'a mut Enum,
1447 &'a mut Variant,
1448 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1449 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1450 fn(Variant) -> Enum,
1451>;
1452
1453pub fn enum_variant<'a, Enum, Variant>(
1471 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1472 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1473 embedder: fn(Variant) -> Enum,
1474) -> EnumKpType<'a, Enum, Variant> {
1475 EnumKp::new(Kp::new(getter, setter), embedder)
1476}
1477
1478pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1488 EnumKp::new(
1489 Kp::new(
1490 |r: &Result<T, E>| r.as_ref().ok(),
1491 |r: &mut Result<T, E>| r.as_mut().ok(),
1492 ),
1493 |t: T| Ok(t),
1494 )
1495}
1496
1497pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1507 EnumKp::new(
1508 Kp::new(
1509 |r: &Result<T, E>| r.as_ref().err(),
1510 |r: &mut Result<T, E>| r.as_mut().err(),
1511 ),
1512 |e: E| Err(e),
1513 )
1514}
1515
1516pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1526 EnumKp::new(
1527 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1528 |t: T| Some(t),
1529 )
1530}
1531
1532pub fn variant_of<'a, Enum, Variant>(
1550 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1551 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1552 embedder: fn(Variant) -> Enum,
1553) -> EnumKpType<'a, Enum, Variant> {
1554 enum_variant(getter, setter, embedder)
1555}
1556
1557pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1570 Kp::new(
1571 |b: &Box<T>| Some(b.as_ref()),
1572 |b: &mut Box<T>| Some(b.as_mut()),
1573 )
1574}
1575
1576pub fn kp_arc<'a, T>() -> Kp<
1587 Arc<T>,
1588 T,
1589 &'a Arc<T>,
1590 &'a T,
1591 &'a mut Arc<T>,
1592 &'a mut T,
1593 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
1594 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
1595> {
1596 Kp::new(
1597 |arc: &Arc<T>| Some(arc.as_ref()),
1598 |arc: &mut Arc<T>| Arc::get_mut(arc),
1599 )
1600}
1601
1602pub fn kp_rc<'a, T>() -> Kp<
1613 std::rc::Rc<T>,
1614 T,
1615 &'a std::rc::Rc<T>,
1616 &'a T,
1617 &'a mut std::rc::Rc<T>,
1618 &'a mut T,
1619 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
1620 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
1621> {
1622 Kp::new(
1623 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
1624 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
1625 )
1626}
1627
1628use std::any::{Any, TypeId};
1631use std::rc::Rc;
1632
1633#[cfg(test)]
1648mod tests {
1649 use super::*;
1650 use std::collections::HashMap;
1651
1652 fn kp_adaptable<T, Root, Value, MutRoot, MutValue, G, S>(kp: T)
1653 where
1654 T: KpTrait<TestKP, String, Root, Value, MutRoot, MutValue, G, S>,
1655 {
1656 }
1659 fn test_kp_trait() {}
1660
1661 #[derive(Debug)]
1662 struct TestKP {
1663 a: String,
1664 b: String,
1665 c: std::sync::Arc<String>,
1666 d: std::sync::Mutex<String>,
1667 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
1668 f: Option<TestKP2>,
1669 g: HashMap<i32, TestKP2>,
1670 }
1671
1672 impl TestKP {
1673 fn new() -> Self {
1674 Self {
1675 a: String::from("a"),
1676 b: String::from("b"),
1677 c: std::sync::Arc::new(String::from("c")),
1678 d: std::sync::Mutex::new(String::from("d")),
1679 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
1680 f: Some(TestKP2 {
1681 a: String::from("a3"),
1682 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1683 }),
1684 g: HashMap::new(),
1685 }
1686 }
1687
1688 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
1689 KpComposed::from_closures(
1690 move |r: &TestKP| r.g.get(&index),
1691 move |r: &mut TestKP| r.g.get_mut(&index),
1692 )
1693 }
1694
1695 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
1698 TestKP2,
1699 String,
1700 Root,
1701 Value,
1702 MutRoot,
1703 MutValue,
1704 impl Fn(Root) -> Option<Value>,
1705 impl Fn(MutRoot) -> Option<MutValue>,
1706 >
1707 where
1708 Root: std::borrow::Borrow<TestKP2>,
1709 MutRoot: std::borrow::BorrowMut<TestKP2>,
1710 Value: std::borrow::Borrow<String> + From<String>,
1711 MutValue: std::borrow::BorrowMut<String> + From<String>,
1712 {
1713 Kp::new(
1714 |r: Root| Some(Value::from(r.borrow().a.clone())),
1715 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
1716 )
1717 }
1718
1719 fn c<'a>() -> KpType<'a, TestKP, String> {
1722 KpType::new(
1723 |r: &TestKP| Some(r.c.as_ref()),
1724 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
1725 Some(arc_str) => Some(arc_str),
1726 None => None,
1727 },
1728 )
1729 }
1730
1731 fn a<'a>() -> KpType<'a, TestKP, String> {
1732 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
1733 }
1734
1735 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
1736 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
1737 }
1738
1739 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
1740 KpType::identity()
1741 }
1742 }
1743
1744 #[test]
1745 fn kp_debug_display_uses_type_names() {
1746 let kp = TestKP::a();
1747 let dbg = format!("{kp:?}");
1748 assert!(dbg.starts_with("Kp {"), "{dbg}");
1749 assert!(dbg.contains("root_ty") && dbg.contains("value_ty"), "{dbg}");
1750 let disp = format!("{kp}");
1751 assert!(disp.contains("TestKP"), "{disp}");
1752 assert!(disp.contains("String"), "{disp}");
1753 }
1754
1755 #[test]
1756 fn akp_and_pkp_debug_display() {
1757 let akp = AKp::new(TestKP::a());
1758 assert!(format!("{akp:?}").starts_with("AKp"));
1759 let pkp = PKp::new(TestKP::a());
1760 let pkp_dbg = format!("{pkp:?}");
1761 assert!(pkp_dbg.starts_with("PKp"), "{pkp_dbg}");
1762 assert!(format!("{pkp}").contains("TestKP"));
1763 }
1764
1765 #[test]
1766 fn enum_kp_debug_display() {
1767 let ok_kp = enum_ok::<i32, String>();
1768 assert!(format!("{ok_kp:?}").contains("EnumKp"));
1769 let s = format!("{ok_kp}");
1770 assert!(s.contains("Result") && s.contains("i32"), "{s}");
1771 }
1772
1773 #[test]
1774 fn composed_kp_into_dynamic_stores_as_kp_dynamic() {
1775 let path: KpDynamic<TestKP, String> = TestKP::f().then(TestKP2::a()).into_dynamic();
1776 let mut t = TestKP::new();
1777 assert_eq!(path.get(&t), Some(&"a3".to_string()));
1778 path.get_mut(&mut t).map(|s| *s = "x".into());
1779 assert_eq!(t.f.as_ref().unwrap().a, "x");
1780 }
1781
1782 #[derive(Debug)]
1783 struct TestKP2 {
1784 a: String,
1785 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
1786 }
1787
1788 impl TestKP2 {
1789 fn new() -> Self {
1790 TestKP2 {
1791 a: String::from("a2"),
1792 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1793 }
1794 }
1795
1796 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1797 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
1804 fn(MutRoot) -> Option<MutRoot>,
1805 >
1806 where
1807 Root: std::borrow::Borrow<TestKP2>,
1808 MutRoot: std::borrow::BorrowMut<TestKP2>,
1809 G: Fn(Root) -> Option<Root>,
1810 S: Fn(MutRoot) -> Option<MutRoot>,
1811 {
1812 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1813 }
1814
1815 fn a<'a>() -> KpType<'a, TestKP2, String> {
1816 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
1817 }
1818
1819 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
1820 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
1821 }
1822
1823 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
1828 KpType::identity()
1829 }
1830 }
1831
1832 #[derive(Debug)]
1833 struct TestKP3 {
1834 a: String,
1835 b: std::sync::Arc<std::sync::Mutex<String>>,
1836 }
1837
1838 impl TestKP3 {
1839 fn new() -> Self {
1840 TestKP3 {
1841 a: String::from("a2"),
1842 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
1843 }
1844 }
1845
1846 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1847 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
1854 fn(MutRoot) -> Option<MutRoot>,
1855 >
1856 where
1857 Root: std::borrow::Borrow<TestKP3>,
1858 MutRoot: std::borrow::BorrowMut<TestKP3>,
1859 G: Fn(Root) -> Option<Root>,
1860 S: Fn(MutRoot) -> Option<MutRoot>,
1861 {
1862 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1863 }
1864
1865 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
1866 KpType::identity()
1867 }
1868 }
1869
1870 impl TestKP3 {}
1871
1872 impl TestKP {}
1873 #[test]
1874 fn test_a() {
1875 let instance2 = TestKP2::new();
1876 let mut instance = TestKP::new();
1877 let kp = TestKP::identity();
1878 let kp_a = TestKP::a();
1879 let wres = TestKP::f()
1881 .then(TestKP2::a())
1882 .get_mut(&mut instance)
1883 .unwrap();
1884 *wres = String::from("a3 changed successfully");
1885 let res = (TestKP::f().then(TestKP2::a()).get)(&instance);
1886 println!("{:?}", res);
1887 let res = (TestKP::f().then(TestKP2::identity()).get)(&instance);
1888 println!("{:?}", res);
1889 let res = (kp.get)(&instance);
1890 println!("{:?}", res);
1891
1892 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
1893 println!("{:?}", (new_kp_from_hashmap.get)(&instance));
1894 }
1895
1896 #[test]
1975 fn test_enum_kp_result_ok() {
1976 let ok_result: Result<String, i32> = Ok("success".to_string());
1977 let mut err_result: Result<String, i32> = Err(42);
1978
1979 let ok_kp = enum_ok();
1980
1981 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
1983 assert_eq!(ok_kp.get(&err_result), None);
1984
1985 let embedded = ok_kp.embed("embedded".to_string());
1987 assert_eq!(embedded, Ok("embedded".to_string()));
1988
1989 if let Some(val) = ok_kp.get_mut(&mut err_result) {
1991 *val = "modified".to_string();
1992 }
1993 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
1996 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
1997 *val = "modified".to_string();
1998 }
1999 assert_eq!(ok_result2, Ok("modified".to_string()));
2000 }
2001
2002 #[test]
2003 fn test_enum_kp_result_err() {
2004 let ok_result: Result<String, i32> = Ok("success".to_string());
2005 let mut err_result: Result<String, i32> = Err(42);
2006
2007 let err_kp = enum_err();
2008
2009 assert_eq!(err_kp.get(&err_result), Some(&42));
2011 assert_eq!(err_kp.get(&ok_result), None);
2012
2013 let embedded = err_kp.embed(99);
2015 assert_eq!(embedded, Err(99));
2016
2017 if let Some(val) = err_kp.get_mut(&mut err_result) {
2019 *val = 100;
2020 }
2021 assert_eq!(err_result, Err(100));
2022 }
2023
2024 #[test]
2025 fn test_enum_kp_option_some() {
2026 let some_opt = Some("value".to_string());
2027 let mut none_opt: Option<String> = None;
2028
2029 let some_kp = enum_some();
2030
2031 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2033 assert_eq!(some_kp.get(&none_opt), None);
2034
2035 let embedded = some_kp.embed("embedded".to_string());
2037 assert_eq!(embedded, Some("embedded".to_string()));
2038
2039 let mut some_opt2 = Some("original".to_string());
2041 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2042 *val = "modified".to_string();
2043 }
2044 assert_eq!(some_opt2, Some("modified".to_string()));
2045 }
2046
2047 #[test]
2048 fn test_enum_kp_custom_enum() {
2049 #[derive(Debug, PartialEq)]
2050 enum MyEnum {
2051 A(String),
2052 B(i32),
2053 C,
2054 }
2055
2056 let mut enum_a = MyEnum::A("hello".to_string());
2057 let enum_b = MyEnum::B(42);
2058 let enum_c = MyEnum::C;
2059
2060 let kp_a = enum_variant(
2062 |e: &MyEnum| match e {
2063 MyEnum::A(s) => Some(s),
2064 _ => None,
2065 },
2066 |e: &mut MyEnum| match e {
2067 MyEnum::A(s) => Some(s),
2068 _ => None,
2069 },
2070 |s: String| MyEnum::A(s),
2071 );
2072
2073 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2075 assert_eq!(kp_a.get(&enum_b), None);
2076 assert_eq!(kp_a.get(&enum_c), None);
2077
2078 let embedded = kp_a.embed("world".to_string());
2080 assert_eq!(embedded, MyEnum::A("world".to_string()));
2081
2082 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2084 *val = "modified".to_string();
2085 }
2086 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2087 }
2088
2089 #[test]
2090 fn test_container_kp_box() {
2091 let boxed = Box::new("value".to_string());
2092 let mut boxed_mut = Box::new("original".to_string());
2093
2094 let box_kp = kp_box();
2095
2096 assert_eq!((box_kp.get)(&boxed), Some(&"value".to_string()));
2098
2099 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2101 *val = "modified".to_string();
2102 }
2103 assert_eq!(*boxed_mut, "modified".to_string());
2104 }
2105
2106 #[test]
2107 fn test_container_kp_arc() {
2108 let arc = Arc::new("value".to_string());
2109 let mut arc_mut = Arc::new("original".to_string());
2110
2111 let arc_kp = kp_arc();
2112
2113 assert_eq!((arc_kp.get)(&arc), Some(&"value".to_string()));
2115
2116 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2118 *val = "modified".to_string();
2119 }
2120 assert_eq!(*arc_mut, "modified".to_string());
2121
2122 let arc_shared = Arc::new("shared".to_string());
2124 let arc_shared2 = Arc::clone(&arc_shared);
2125 let mut arc_shared_mut = arc_shared;
2126 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2127 }
2128
2129 #[test]
2130 fn test_enum_kp_composition() {
2131 #[derive(Debug, PartialEq)]
2133 struct Inner {
2134 value: String,
2135 }
2136
2137 let result: Result<Inner, i32> = Ok(Inner {
2138 value: "nested".to_string(),
2139 });
2140
2141 let inner_kp = KpType::new(
2143 |i: &Inner| Some(&i.value),
2144 |i: &mut Inner| Some(&mut i.value),
2145 );
2146
2147 let ok_kp = enum_ok::<Inner, i32>();
2149 let ok_kp_base = ok_kp.into_kp();
2150 let composed = ok_kp_base.then(inner_kp);
2151
2152 assert_eq!((composed.get)(&result), Some(&"nested".to_string()));
2153 }
2154
2155 #[test]
2156 fn test_pkp_basic() {
2157 #[derive(Debug)]
2158 struct User {
2159 name: String,
2160 age: i32,
2161 }
2162
2163 let user = User {
2164 name: "Akash".to_string(),
2165 age: 30,
2166 };
2167
2168 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2170 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2171
2172 let name_pkp = PKp::new(name_kp);
2174 let age_pkp = PKp::new(age_kp);
2175
2176 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Akash".to_string()));
2178 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2179
2180 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2182 assert_eq!(age_pkp.get_as::<String>(&user), None);
2183
2184 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2186 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2187 }
2188
2189 #[test]
2190 fn test_pkp_collection() {
2191 #[derive(Debug)]
2192 struct User {
2193 name: String,
2194 age: i32,
2195 }
2196
2197 let user = User {
2198 name: "Bob".to_string(),
2199 age: 25,
2200 };
2201
2202 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2204 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2205
2206 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2207
2208 let name_value = keypaths[0].get_as::<String>(&user);
2210 let age_value = keypaths[1].get_as::<i32>(&user);
2211
2212 assert_eq!(name_value, Some(&"Bob".to_string()));
2213 assert_eq!(age_value, Some(&25));
2214 }
2215
2216 #[test]
2217 fn test_pkp_for_arc() {
2218 #[derive(Debug)]
2219 struct User {
2220 name: String,
2221 }
2222
2223 let user = Arc::new(User {
2224 name: "Charlie".to_string(),
2225 });
2226
2227 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2228 let name_pkp = PKp::new(name_kp);
2229
2230 let arc_pkp = name_pkp.for_arc();
2232
2233 assert_eq!(
2234 arc_pkp.get_as::<String>(&user),
2235 Some(&"Charlie".to_string())
2236 );
2237 }
2238
2239 #[test]
2240 fn test_pkp_for_option() {
2241 #[derive(Debug)]
2242 struct User {
2243 name: String,
2244 }
2245
2246 let some_user = Some(User {
2247 name: "Diana".to_string(),
2248 });
2249 let none_user: Option<User> = None;
2250
2251 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2252 let name_pkp = PKp::new(name_kp);
2253
2254 let opt_pkp = name_pkp.for_option();
2256
2257 assert_eq!(
2258 opt_pkp.get_as::<String>(&some_user),
2259 Some(&"Diana".to_string())
2260 );
2261 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2262 }
2263
2264 #[test]
2265 fn test_akp_basic() {
2266 #[derive(Debug)]
2267 struct User {
2268 name: String,
2269 age: i32,
2270 }
2271
2272 #[derive(Debug)]
2273 struct Product {
2274 title: String,
2275 price: f64,
2276 }
2277
2278 let user = User {
2279 name: "Eve".to_string(),
2280 age: 28,
2281 };
2282
2283 let product = Product {
2284 title: "Book".to_string(),
2285 price: 19.99,
2286 };
2287
2288 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2290 let user_name_akp = AKp::new(user_name_kp);
2291
2292 let product_title_kp = KpType::new(
2293 |p: &Product| Some(&p.title),
2294 |p: &mut Product| Some(&mut p.title),
2295 );
2296 let product_title_akp = AKp::new(product_title_kp);
2297
2298 assert_eq!(
2300 user_name_akp.get_as::<User, String>(&user),
2301 Some(Some(&"Eve".to_string()))
2302 );
2303 assert_eq!(
2304 product_title_akp.get_as::<Product, String>(&product),
2305 Some(Some(&"Book".to_string()))
2306 );
2307
2308 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2310 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2311
2312 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2314 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2315 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2316 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2317 }
2318
2319 #[test]
2320 fn test_akp_heterogeneous_collection() {
2321 #[derive(Debug)]
2322 struct User {
2323 name: String,
2324 }
2325
2326 #[derive(Debug)]
2327 struct Product {
2328 title: String,
2329 }
2330
2331 let user = User {
2332 name: "Frank".to_string(),
2333 };
2334 let product = Product {
2335 title: "Laptop".to_string(),
2336 };
2337
2338 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2340 let product_title_kp = KpType::new(
2341 |p: &Product| Some(&p.title),
2342 |p: &mut Product| Some(&mut p.title),
2343 );
2344
2345 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2346
2347 let user_any: &dyn Any = &user;
2349 let product_any: &dyn Any = &product;
2350
2351 let user_value = keypaths[0].get(user_any);
2352 let product_value = keypaths[1].get(product_any);
2353
2354 assert!(user_value.is_some());
2355 assert!(product_value.is_some());
2356
2357 assert_eq!(
2359 user_value.and_then(|v| v.downcast_ref::<String>()),
2360 Some(&"Frank".to_string())
2361 );
2362 assert_eq!(
2363 product_value.and_then(|v| v.downcast_ref::<String>()),
2364 Some(&"Laptop".to_string())
2365 );
2366 }
2367
2368 #[test]
2369 fn test_akp_for_option() {
2370 #[derive(Debug)]
2371 struct User {
2372 name: String,
2373 }
2374
2375 let some_user = Some(User {
2376 name: "Grace".to_string(),
2377 });
2378 let none_user: Option<User> = None;
2379
2380 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2381 let name_akp = AKp::new(name_kp);
2382
2383 let opt_akp = name_akp.for_option::<User>();
2385
2386 assert_eq!(
2387 opt_akp.get_as::<Option<User>, String>(&some_user),
2388 Some(Some(&"Grace".to_string()))
2389 );
2390 assert_eq!(
2391 opt_akp.get_as::<Option<User>, String>(&none_user),
2392 Some(None)
2393 );
2394 }
2395
2396 #[test]
2397 fn test_akp_for_result() {
2398 #[derive(Debug)]
2399 struct User {
2400 name: String,
2401 }
2402
2403 let ok_user: Result<User, String> = Ok(User {
2404 name: "Henry".to_string(),
2405 });
2406 let err_user: Result<User, String> = Err("Not found".to_string());
2407
2408 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2409 let name_akp = AKp::new(name_kp);
2410
2411 let result_akp = name_akp.for_result::<User, String>();
2413
2414 assert_eq!(
2415 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2416 Some(Some(&"Henry".to_string()))
2417 );
2418 assert_eq!(
2419 result_akp.get_as::<Result<User, String>, String>(&err_user),
2420 Some(None)
2421 );
2422 }
2423
2424 #[test]
2427 fn test_kp_map() {
2428 #[derive(Debug)]
2429 struct User {
2430 name: String,
2431 age: i32,
2432 }
2433
2434 let user = User {
2435 name: "Akash".to_string(),
2436 age: 30,
2437 };
2438
2439 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2441 let len_kp = name_kp.map(|name: &String| name.len());
2442
2443 assert_eq!((len_kp.get)(&user), Some(5));
2444
2445 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2447 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2448
2449 assert_eq!((double_age_kp.get)(&user), Some(60));
2450
2451 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2453 assert_eq!((is_adult_kp.get)(&user), Some(true));
2454 }
2455
2456 #[test]
2457 fn test_kp_filter() {
2458 #[derive(Debug)]
2459 struct User {
2460 name: String,
2461 age: i32,
2462 }
2463
2464 let adult = User {
2465 name: "Akash".to_string(),
2466 age: 30,
2467 };
2468
2469 let minor = User {
2470 name: "Bob".to_string(),
2471 age: 15,
2472 };
2473
2474 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2475 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2476
2477 assert_eq!((adult_age_kp.get)(&adult), Some(&30));
2478 assert_eq!((adult_age_kp.get)(&minor), None);
2479
2480 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2482 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2483
2484 assert_eq!((short_name_kp.get)(&minor), Some(&"Bob".to_string()));
2485 assert_eq!((short_name_kp.get)(&adult), None);
2486 }
2487
2488 #[test]
2489 fn test_kp_map_and_filter() {
2490 #[derive(Debug)]
2491 struct User {
2492 scores: Vec<i32>,
2493 }
2494
2495 let user = User {
2496 scores: vec![85, 92, 78, 95],
2497 };
2498
2499 let scores_kp = KpType::new(
2500 |u: &User| Some(&u.scores),
2501 |u: &mut User| Some(&mut u.scores),
2502 );
2503
2504 let avg_kp =
2506 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2507
2508 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2510
2511 assert_eq!((high_avg_kp.get)(&user), Some(87)); }
2513
2514 #[test]
2515 fn test_enum_kp_map() {
2516 let ok_result: Result<String, i32> = Ok("hello".to_string());
2517 let err_result: Result<String, i32> = Err(42);
2518
2519 let ok_kp = enum_ok::<String, i32>();
2520 let len_kp = ok_kp.map(|s: &String| s.len());
2521
2522 assert_eq!(len_kp.get(&ok_result), Some(5));
2523 assert_eq!(len_kp.get(&err_result), None);
2524
2525 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2527 let none_opt: Option<Vec<i32>> = None;
2528
2529 let some_kp = enum_some::<Vec<i32>>();
2530 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2531
2532 assert_eq!(count_kp.get(&some_opt), Some(5));
2533 assert_eq!(count_kp.get(&none_opt), None);
2534 }
2535
2536 #[test]
2537 fn test_enum_kp_filter() {
2538 let ok_result1: Result<i32, String> = Ok(42);
2539 let ok_result2: Result<i32, String> = Ok(-5);
2540 let err_result: Result<i32, String> = Err("error".to_string());
2541
2542 let ok_kp = enum_ok::<i32, String>();
2543 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2544
2545 assert_eq!((positive_kp.extractor.get)(&ok_result1), Some(&42));
2546 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2551 let short_str = Some("hi".to_string());
2552
2553 let some_kp = enum_some::<String>();
2554 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2555
2556 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2557 assert_eq!(long_kp.get(&short_str), None);
2558 }
2559
2560 #[test]
2561 fn test_pkp_filter() {
2562 #[derive(Debug)]
2563 struct User {
2564 name: String,
2565 age: i32,
2566 }
2567
2568 let adult = User {
2569 name: "Akash".to_string(),
2570 age: 30,
2571 };
2572
2573 let minor = User {
2574 name: "Bob".to_string(),
2575 age: 15,
2576 };
2577
2578 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2579 let age_pkp = PKp::new(age_kp);
2580
2581 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2583
2584 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2585 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2586
2587 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2589 let name_pkp = PKp::new(name_kp);
2590 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2591
2592 assert_eq!(
2593 short_name_pkp.get_as::<String>(&minor),
2594 Some(&"Bob".to_string())
2595 );
2596 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2597 }
2598
2599 #[test]
2600 fn test_akp_filter() {
2601 #[derive(Debug)]
2602 struct User {
2603 age: i32,
2604 }
2605
2606 #[derive(Debug)]
2607 struct Product {
2608 price: f64,
2609 }
2610
2611 let adult = User { age: 30 };
2612 let minor = User { age: 15 };
2613 let expensive = Product { price: 99.99 };
2614 let cheap = Product { price: 5.0 };
2615
2616 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2618 let age_akp = AKp::new(age_kp);
2619 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2620
2621 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2622 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2623
2624 let price_kp = KpType::new(
2626 |p: &Product| Some(&p.price),
2627 |p: &mut Product| Some(&mut p.price),
2628 );
2629 let price_akp = AKp::new(price_kp);
2630 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2631
2632 assert_eq!(
2633 expensive_akp.get_as::<Product, f64>(&expensive),
2634 Some(Some(&99.99))
2635 );
2636 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2637 }
2638
2639 #[test]
2642 fn test_kp_filter_map() {
2643 #[derive(Debug)]
2644 struct User {
2645 middle_name: Option<String>,
2646 }
2647
2648 let user_with = User {
2649 middle_name: Some("Marie".to_string()),
2650 };
2651 let user_without = User { middle_name: None };
2652
2653 let middle_kp = KpType::new(
2654 |u: &User| Some(&u.middle_name),
2655 |u: &mut User| Some(&mut u.middle_name),
2656 );
2657
2658 let first_char_kp = middle_kp
2659 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
2660
2661 assert_eq!((first_char_kp.get)(&user_with), Some('M'));
2662 assert_eq!((first_char_kp.get)(&user_without), None);
2663 }
2664
2665 #[test]
2666 fn test_kp_inspect() {
2667 #[derive(Debug)]
2668 struct User {
2669 name: String,
2670 }
2671
2672 let user = User {
2673 name: "Akash".to_string(),
2674 };
2675
2676 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2680
2681 let result = (name_kp.get)(&user);
2684 assert_eq!(result, Some(&"Akash".to_string()));
2685
2686 }
2689
2690 #[test]
2691 fn test_kp_fold_value() {
2692 #[derive(Debug)]
2693 struct User {
2694 scores: Vec<i32>,
2695 }
2696
2697 let user = User {
2698 scores: vec![85, 92, 78, 95],
2699 };
2700
2701 let scores_kp = KpType::new(
2702 |u: &User| Some(&u.scores),
2703 |u: &mut User| Some(&mut u.scores),
2704 );
2705
2706 let sum_fn =
2708 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
2709
2710 assert_eq!(sum_fn(&user), 350);
2711 }
2712
2713 #[test]
2714 fn test_kp_any_all() {
2715 #[derive(Debug)]
2716 struct User {
2717 scores: Vec<i32>,
2718 }
2719
2720 let user_high = User {
2721 scores: vec![85, 92, 88],
2722 };
2723 let user_mixed = User {
2724 scores: vec![65, 92, 78],
2725 };
2726
2727 let scores_kp = KpType::new(
2728 |u: &User| Some(&u.scores),
2729 |u: &mut User| Some(&mut u.scores),
2730 );
2731
2732 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
2734 assert!(has_high_fn(&user_high));
2735 assert!(has_high_fn(&user_mixed));
2736
2737 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
2739 assert!(all_passing_fn(&user_high));
2740 assert!(!all_passing_fn(&user_mixed));
2741 }
2742
2743 #[test]
2744 fn test_kp_count_items() {
2745 #[derive(Debug)]
2746 struct User {
2747 tags: Vec<String>,
2748 }
2749
2750 let user = User {
2751 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
2752 };
2753
2754 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2755 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
2756
2757 assert_eq!(count_fn(&user), Some(3));
2758 }
2759
2760 #[test]
2761 fn test_kp_find_in() {
2762 #[derive(Debug)]
2763 struct User {
2764 scores: Vec<i32>,
2765 }
2766
2767 let user = User {
2768 scores: vec![85, 92, 78, 95, 88],
2769 };
2770
2771 let scores_kp = KpType::new(
2772 |u: &User| Some(&u.scores),
2773 |u: &mut User| Some(&mut u.scores),
2774 );
2775
2776 let first_high_fn =
2778 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
2779
2780 assert_eq!(first_high_fn(&user), Some(92));
2781
2782 let perfect_fn =
2784 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
2785
2786 assert_eq!(perfect_fn(&user), None);
2787 }
2788
2789 #[test]
2790 fn test_kp_take_skip() {
2791 #[derive(Debug)]
2792 struct User {
2793 tags: Vec<String>,
2794 }
2795
2796 let user = User {
2797 tags: vec![
2798 "a".to_string(),
2799 "b".to_string(),
2800 "c".to_string(),
2801 "d".to_string(),
2802 ],
2803 };
2804
2805 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2806
2807 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
2809 tags.iter().take(n).cloned().collect::<Vec<_>>()
2810 });
2811
2812 let taken = take_fn(&user).unwrap();
2813 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
2814
2815 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
2817 tags.iter().skip(n).cloned().collect::<Vec<_>>()
2818 });
2819
2820 let skipped = skip_fn(&user).unwrap();
2821 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
2822 }
2823
2824 #[test]
2825 fn test_kp_partition() {
2826 #[derive(Debug)]
2827 struct User {
2828 scores: Vec<i32>,
2829 }
2830
2831 let user = User {
2832 scores: vec![85, 92, 65, 95, 72, 58],
2833 };
2834
2835 let scores_kp = KpType::new(
2836 |u: &User| Some(&u.scores),
2837 |u: &mut User| Some(&mut u.scores),
2838 );
2839
2840 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
2841 scores.iter().copied().partition(|&s| s >= 70)
2842 });
2843
2844 let (passing, failing) = partition_fn(&user).unwrap();
2845 assert_eq!(passing, vec![85, 92, 95, 72]);
2846 assert_eq!(failing, vec![65, 58]);
2847 }
2848
2849 #[test]
2850 fn test_kp_min_max() {
2851 #[derive(Debug)]
2852 struct User {
2853 scores: Vec<i32>,
2854 }
2855
2856 let user = User {
2857 scores: vec![85, 92, 78, 95, 88],
2858 };
2859
2860 let scores_kp = KpType::new(
2861 |u: &User| Some(&u.scores),
2862 |u: &mut User| Some(&mut u.scores),
2863 );
2864
2865 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
2867 assert_eq!(min_fn(&user), Some(78));
2868
2869 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
2871 assert_eq!(max_fn(&user), Some(95));
2872 }
2873
2874 #[test]
2875 fn test_kp_sum() {
2876 #[derive(Debug)]
2877 struct User {
2878 scores: Vec<i32>,
2879 }
2880
2881 let user = User {
2882 scores: vec![85, 92, 78],
2883 };
2884
2885 let scores_kp = KpType::new(
2886 |u: &User| Some(&u.scores),
2887 |u: &mut User| Some(&mut u.scores),
2888 );
2889
2890 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
2891 assert_eq!(sum_fn(&user), Some(255));
2892
2893 let avg_fn =
2895 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2896 assert_eq!(avg_fn.get(&user), Some(85));
2897 }
2898
2899 #[test]
2900 fn test_kp_chain() {
2901 #[derive(Debug)]
2902 struct User {
2903 profile: Profile,
2904 }
2905
2906 #[derive(Debug)]
2907 struct Profile {
2908 settings: Settings,
2909 }
2910
2911 #[derive(Debug)]
2912 struct Settings {
2913 theme: String,
2914 }
2915
2916 let user = User {
2917 profile: Profile {
2918 settings: Settings {
2919 theme: "dark".to_string(),
2920 },
2921 },
2922 };
2923
2924 let profile_kp = KpType::new(
2925 |u: &User| Some(&u.profile),
2926 |u: &mut User| Some(&mut u.profile),
2927 );
2928 let settings_kp = KpType::new(
2929 |p: &Profile| Some(&p.settings),
2930 |p: &mut Profile| Some(&mut p.settings),
2931 );
2932 let theme_kp = KpType::new(
2933 |s: &Settings| Some(&s.theme),
2934 |s: &mut Settings| Some(&mut s.theme),
2935 );
2936
2937 let profile_settings = profile_kp.then(settings_kp);
2939 let theme_path = profile_settings.then(theme_kp);
2940 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
2941 }
2942
2943 #[test]
2944 fn test_kp_zip() {
2945 #[derive(Debug)]
2946 struct User {
2947 name: String,
2948 age: i32,
2949 }
2950
2951 let user = User {
2952 name: "Akash".to_string(),
2953 age: 30,
2954 };
2955
2956 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2957 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2958
2959 let zipped_fn = zip_kps(&name_kp, &age_kp);
2960 let result = zipped_fn(&user);
2961
2962 assert_eq!(result, Some((&"Akash".to_string(), &30)));
2963 }
2964
2965 #[test]
2966 fn test_kp_complex_pipeline() {
2967 #[derive(Debug)]
2968 struct User {
2969 transactions: Vec<Transaction>,
2970 }
2971
2972 #[derive(Debug)]
2973 struct Transaction {
2974 amount: f64,
2975 category: String,
2976 }
2977
2978 let user = User {
2979 transactions: vec![
2980 Transaction {
2981 amount: 50.0,
2982 category: "food".to_string(),
2983 },
2984 Transaction {
2985 amount: 100.0,
2986 category: "transport".to_string(),
2987 },
2988 Transaction {
2989 amount: 25.0,
2990 category: "food".to_string(),
2991 },
2992 Transaction {
2993 amount: 200.0,
2994 category: "shopping".to_string(),
2995 },
2996 ],
2997 };
2998
2999 let txns_kp = KpType::new(
3000 |u: &User| Some(&u.transactions),
3001 |u: &mut User| Some(&mut u.transactions),
3002 );
3003
3004 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3006 txns.iter()
3007 .filter(|t| t.category == "food")
3008 .map(|t| t.amount)
3009 .sum::<f64>()
3010 });
3011
3012 assert_eq!(food_total.get(&user), Some(75.0));
3013
3014 let has_large =
3016 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3017
3018 assert!(has_large(&user));
3019
3020 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3022 assert_eq!(count(&user), Some(4));
3023 }
3024
3025 #[test]
3029 fn test_no_clone_required_for_root() {
3030 use std::sync::Arc;
3031 use std::sync::atomic::{AtomicUsize, Ordering};
3032
3033 struct NonCloneableRoot {
3036 data: Arc<AtomicUsize>,
3037 cached_value: usize,
3038 }
3039
3040 impl NonCloneableRoot {
3041 fn new() -> Self {
3042 Self {
3043 data: Arc::new(AtomicUsize::new(42)),
3044 cached_value: 42,
3045 }
3046 }
3047
3048 fn increment(&mut self) {
3049 self.data.fetch_add(1, Ordering::SeqCst);
3050 self.cached_value = self.data.load(Ordering::SeqCst);
3051 }
3052
3053 fn get_value(&self) -> &usize {
3054 &self.cached_value
3055 }
3056
3057 fn get_value_mut(&mut self) -> &mut usize {
3058 &mut self.cached_value
3059 }
3060 }
3061
3062 let mut root = NonCloneableRoot::new();
3063
3064 let data_kp = KpType::new(
3066 |r: &NonCloneableRoot| Some(r.get_value()),
3067 |r: &mut NonCloneableRoot| {
3068 r.increment();
3069 Some(r.get_value_mut())
3070 },
3071 );
3072
3073 assert_eq!(data_kp.get(&root), Some(&42));
3075
3076 {
3077 let doubled = data_kp.map(|val: &usize| val * 2);
3079 assert_eq!(doubled.get(&root), Some(84));
3080
3081 let filtered = data_kp.filter(|val: &usize| *val > 0);
3083 assert_eq!(filtered.get(&root), Some(&42));
3084 } let value_ref = data_kp.get_mut(&mut root);
3088 assert!(value_ref.is_some());
3089 }
3090
3091 #[test]
3092 fn test_no_clone_required_for_value() {
3093 use std::sync::Arc;
3094 use std::sync::atomic::{AtomicUsize, Ordering};
3095
3096 struct NonCloneableValue {
3098 counter: Arc<AtomicUsize>,
3099 }
3100
3101 impl NonCloneableValue {
3102 fn new(val: usize) -> Self {
3103 Self {
3104 counter: Arc::new(AtomicUsize::new(val)),
3105 }
3106 }
3107
3108 fn get(&self) -> usize {
3109 self.counter.load(Ordering::SeqCst)
3110 }
3111 }
3112
3113 struct Root {
3114 value: NonCloneableValue,
3115 }
3116
3117 let root = Root {
3118 value: NonCloneableValue::new(100),
3119 };
3120
3121 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3123
3124 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3126 assert_eq!(counter_kp.get(&root), Some(100));
3127
3128 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3130 assert!(filtered.get(&root).is_some());
3131 }
3132
3133 #[test]
3134 fn test_static_does_not_leak_memory() {
3135 use std::sync::Arc;
3136 use std::sync::atomic::{AtomicUsize, Ordering};
3137
3138 static CREATED: AtomicUsize = AtomicUsize::new(0);
3140 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3141
3142 struct Tracked {
3143 id: usize,
3144 }
3145
3146 impl Tracked {
3147 fn new() -> Self {
3148 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3149 Self { id }
3150 }
3151 }
3152
3153 impl Drop for Tracked {
3154 fn drop(&mut self) {
3155 DROPPED.fetch_add(1, Ordering::SeqCst);
3156 }
3157 }
3158
3159 struct Root {
3160 data: Tracked,
3161 }
3162
3163 CREATED.store(0, Ordering::SeqCst);
3165 DROPPED.store(0, Ordering::SeqCst);
3166
3167 {
3168 let root = Root {
3169 data: Tracked::new(),
3170 };
3171
3172 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3173
3174 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3176 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3177 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3178
3179 assert_eq!(mapped1.get(&root), Some(0));
3180 assert_eq!(mapped2.get(&root), Some(1));
3181 assert_eq!(mapped3.get(&root), Some(2));
3182
3183 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3185 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3186 }
3187
3188 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3190 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3191
3192 }
3194
3195 #[test]
3196 fn test_references_not_cloned() {
3197 use std::sync::Arc;
3198
3199 struct ExpensiveData {
3201 large_vec: Vec<u8>,
3202 }
3203
3204 impl ExpensiveData {
3205 fn new(size: usize) -> Self {
3206 Self {
3207 large_vec: vec![0u8; size],
3208 }
3209 }
3210
3211 fn size(&self) -> usize {
3212 self.large_vec.len()
3213 }
3214 }
3215
3216 struct Root {
3217 expensive: ExpensiveData,
3218 }
3219
3220 let root = Root {
3221 expensive: ExpensiveData::new(1_000_000), };
3223
3224 let expensive_kp = KpType::new(
3225 |r: &Root| Some(&r.expensive),
3226 |r: &mut Root| Some(&mut r.expensive),
3227 );
3228
3229 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3231 assert_eq!(size_kp.get(&root), Some(1_000_000));
3232
3233 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3235 assert!(large_filter.get(&root).is_some());
3236
3237 }
3239
3240 #[test]
3241 fn test_hof_with_arc_no_extra_clones() {
3242 use std::sync::Arc;
3243
3244 #[derive(Debug)]
3245 struct SharedData {
3246 value: String,
3247 }
3248
3249 struct Root {
3250 shared: Arc<SharedData>,
3251 }
3252
3253 let shared = Arc::new(SharedData {
3254 value: "shared".to_string(),
3255 });
3256
3257 assert_eq!(Arc::strong_count(&shared), 1);
3259
3260 {
3261 let root = Root {
3262 shared: Arc::clone(&shared),
3263 };
3264
3265 assert_eq!(Arc::strong_count(&shared), 2);
3267
3268 let shared_kp = KpType::new(
3269 |r: &Root| Some(&r.shared),
3270 |r: &mut Root| Some(&mut r.shared),
3271 );
3272
3273 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3275
3276 assert_eq!(value_kp.get(&root), Some(6));
3278 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3282 assert!(filtered.get(&root).is_some());
3283 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3288
3289 #[test]
3290 fn test_closure_captures_not_root_values() {
3291 use std::sync::Arc;
3292 use std::sync::atomic::{AtomicUsize, Ordering};
3293
3294 let call_count = Arc::new(AtomicUsize::new(0));
3296 let call_count_clone = Arc::clone(&call_count);
3297
3298 struct Root {
3299 value: i32,
3300 }
3301
3302 let root = Root { value: 42 };
3303
3304 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3305
3306 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3309 call_count_clone.fetch_add(1, Ordering::SeqCst);
3310 v * 2
3311 });
3312
3313 assert_eq!(doubled(&root), 84);
3315 assert_eq!(doubled(&root), 84);
3316 assert_eq!(doubled(&root), 84);
3317
3318 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3320
3321 }
3323
3324 #[test]
3325 fn test_static_with_borrowed_data() {
3326 struct Root {
3330 data: String,
3331 }
3332
3333 {
3334 let root = Root {
3335 data: "temporary".to_string(),
3336 };
3337
3338 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3339
3340 let len_kp = data_kp.map(|s: &String| s.len());
3342 assert_eq!(len_kp.get(&root), Some(9));
3343
3344 } }
3349
3350 #[test]
3351 fn test_multiple_hof_operations_no_accumulation() {
3352 use std::sync::Arc;
3353 use std::sync::atomic::{AtomicUsize, Ordering};
3354
3355 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3356
3357 struct Tracked {
3358 id: usize,
3359 }
3360
3361 impl Drop for Tracked {
3362 fn drop(&mut self) {
3363 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3364 }
3365 }
3366
3367 struct Root {
3368 values: Vec<Tracked>,
3369 }
3370
3371 DROP_COUNT.store(0, Ordering::SeqCst);
3372
3373 {
3374 let root = Root {
3375 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3376 };
3377
3378 let values_kp = KpType::new(
3379 |r: &Root| Some(&r.values),
3380 |r: &mut Root| Some(&mut r.values),
3381 );
3382
3383 let count = values_kp.count_items(|v| v.len());
3385 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3386 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3387 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3388
3389 assert_eq!(count(&root), Some(3));
3390 assert_eq!(sum(&root), Some(6));
3391 assert!(has_2(&root));
3392 assert!(all_positive(&root));
3393
3394 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3396 }
3397
3398 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3400 }
3401
3402 #[test]
3403 fn test_copy_bound_only_for_function_not_data() {
3404 #[derive(Debug)]
3408 struct NonCopyData {
3409 value: String,
3410 }
3411
3412 struct Root {
3413 data: NonCopyData,
3414 }
3415
3416 let root = Root {
3417 data: NonCopyData {
3418 value: "test".to_string(),
3419 },
3420 };
3421
3422 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3423
3424 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3427 assert_eq!(len_kp.get(&root), Some(4));
3428
3429 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3431 assert!(filtered.get(&root).is_some());
3432 }
3433
3434 #[test]
3435 fn test_no_memory_leak_with_cyclic_references() {
3436 use std::sync::atomic::{AtomicUsize, Ordering};
3437 use std::sync::{Arc, Weak};
3438
3439 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3440
3441 struct Node {
3442 id: usize,
3443 parent: Option<Weak<Node>>,
3444 }
3445
3446 impl Drop for Node {
3447 fn drop(&mut self) {
3448 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3449 }
3450 }
3451
3452 struct Root {
3453 node: Arc<Node>,
3454 }
3455
3456 DROP_COUNT.store(0, Ordering::SeqCst);
3457
3458 {
3459 let root = Root {
3460 node: Arc::new(Node {
3461 id: 1,
3462 parent: None,
3463 }),
3464 };
3465
3466 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3467
3468 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3470 assert_eq!(id_kp.get(&root), Some(1));
3471
3472 assert_eq!(Arc::strong_count(&root.node), 1);
3474
3475 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3477 }
3478
3479 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3481 }
3482
3483 #[test]
3484 fn test_hof_operations_are_zero_cost_abstractions() {
3485 struct Root {
3489 value: i32,
3490 }
3491
3492 let root = Root { value: 10 };
3493
3494 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3495
3496 let direct_result = value_kp.get(&root).map(|v| v * 2);
3498 assert_eq!(direct_result, Some(20));
3499
3500 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3502 let hof_result = mapped_kp.get(&root);
3503 assert_eq!(hof_result, Some(20));
3504
3505 assert_eq!(direct_result, hof_result);
3507 }
3508
3509 #[test]
3510 fn test_complex_closure_captures_allowed() {
3511 use std::sync::Arc;
3512
3513 struct Root {
3515 scores: Vec<i32>,
3516 }
3517
3518 let root = Root {
3519 scores: vec![85, 92, 78, 95, 88],
3520 };
3521
3522 let scores_kp = KpType::new(
3523 |r: &Root| Some(&r.scores),
3524 |r: &mut Root| Some(&mut r.scores),
3525 );
3526
3527 let threshold = 90;
3529 let multiplier = Arc::new(2);
3530
3531 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3533 let high: i32 = scores
3534 .iter()
3535 .filter(|&&s| s >= threshold)
3536 .map(|&s| s * *multiplier)
3537 .sum();
3538 acc + high
3539 });
3540
3541 assert_eq!(high_scores_doubled(&root), 374);
3543 }
3544
3545 #[test]
3549 fn test_pkp_filter_by_value_type() {
3550 use std::any::TypeId;
3551
3552 #[derive(Debug)]
3553 struct User {
3554 name: String,
3555 age: i32,
3556 score: f64,
3557 active: bool,
3558 }
3559
3560 let user = User {
3561 name: "Akash".to_string(),
3562 age: 30,
3563 score: 95.5,
3564 active: true,
3565 };
3566
3567 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3569 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3570 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3571 let active_kp = KpType::new(
3572 |u: &User| Some(&u.active),
3573 |u: &mut User| Some(&mut u.active),
3574 );
3575
3576 let all_keypaths: Vec<PKp<User>> = vec![
3578 PKp::new(name_kp),
3579 PKp::new(age_kp),
3580 PKp::new(score_kp),
3581 PKp::new(active_kp),
3582 ];
3583
3584 let string_kps: Vec<_> = all_keypaths
3586 .iter()
3587 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3588 .collect();
3589
3590 assert_eq!(string_kps.len(), 1);
3591 assert_eq!(
3592 string_kps[0].get_as::<String>(&user),
3593 Some(&"Akash".to_string())
3594 );
3595
3596 let i32_kps: Vec<_> = all_keypaths
3598 .iter()
3599 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3600 .collect();
3601
3602 assert_eq!(i32_kps.len(), 1);
3603 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3604
3605 let f64_kps: Vec<_> = all_keypaths
3607 .iter()
3608 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3609 .collect();
3610
3611 assert_eq!(f64_kps.len(), 1);
3612 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3613
3614 let bool_kps: Vec<_> = all_keypaths
3616 .iter()
3617 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3618 .collect();
3619
3620 assert_eq!(bool_kps.len(), 1);
3621 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3622 }
3623
3624 #[test]
3625 fn test_pkp_filter_by_struct_type() {
3626 use std::any::TypeId;
3627
3628 #[derive(Debug, PartialEq)]
3629 struct Address {
3630 street: String,
3631 city: String,
3632 }
3633
3634 #[derive(Debug)]
3635 struct User {
3636 name: String,
3637 age: i32,
3638 address: Address,
3639 }
3640
3641 let user = User {
3642 name: "Bob".to_string(),
3643 age: 25,
3644 address: Address {
3645 street: "123 Main St".to_string(),
3646 city: "NYC".to_string(),
3647 },
3648 };
3649
3650 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3652 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3653 let address_kp = KpType::new(
3654 |u: &User| Some(&u.address),
3655 |u: &mut User| Some(&mut u.address),
3656 );
3657
3658 let all_keypaths: Vec<PKp<User>> =
3659 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
3660
3661 let struct_kps: Vec<_> = all_keypaths
3663 .iter()
3664 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
3665 .collect();
3666
3667 assert_eq!(struct_kps.len(), 1);
3668 assert_eq!(
3669 struct_kps[0].get_as::<Address>(&user),
3670 Some(&Address {
3671 street: "123 Main St".to_string(),
3672 city: "NYC".to_string(),
3673 })
3674 );
3675
3676 let primitive_kps: Vec<_> = all_keypaths
3678 .iter()
3679 .filter(|pkp| {
3680 pkp.value_type_id() == TypeId::of::<String>()
3681 || pkp.value_type_id() == TypeId::of::<i32>()
3682 })
3683 .collect();
3684
3685 assert_eq!(primitive_kps.len(), 2);
3686 }
3687
3688 #[test]
3689 fn test_pkp_filter_by_arc_type() {
3690 use std::any::TypeId;
3691 use std::sync::Arc;
3692
3693 #[derive(Debug)]
3694 struct User {
3695 name: String,
3696 shared_data: Arc<String>,
3697 shared_number: Arc<i32>,
3698 }
3699
3700 let user = User {
3701 name: "Charlie".to_string(),
3702 shared_data: Arc::new("shared".to_string()),
3703 shared_number: Arc::new(42),
3704 };
3705
3706 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3708 let shared_data_kp = KpType::new(
3709 |u: &User| Some(&u.shared_data),
3710 |u: &mut User| Some(&mut u.shared_data),
3711 );
3712 let shared_number_kp = KpType::new(
3713 |u: &User| Some(&u.shared_number),
3714 |u: &mut User| Some(&mut u.shared_number),
3715 );
3716
3717 let all_keypaths: Vec<PKp<User>> = vec![
3718 PKp::new(name_kp),
3719 PKp::new(shared_data_kp),
3720 PKp::new(shared_number_kp),
3721 ];
3722
3723 let arc_string_kps: Vec<_> = all_keypaths
3725 .iter()
3726 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
3727 .collect();
3728
3729 assert_eq!(arc_string_kps.len(), 1);
3730 assert_eq!(
3731 arc_string_kps[0]
3732 .get_as::<Arc<String>>(&user)
3733 .map(|arc| arc.as_str()),
3734 Some("shared")
3735 );
3736
3737 let arc_i32_kps: Vec<_> = all_keypaths
3739 .iter()
3740 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
3741 .collect();
3742
3743 assert_eq!(arc_i32_kps.len(), 1);
3744 assert_eq!(
3745 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
3746 Some(42)
3747 );
3748
3749 let all_arc_kps: Vec<_> = all_keypaths
3751 .iter()
3752 .filter(|pkp| {
3753 pkp.value_type_id() == TypeId::of::<Arc<String>>()
3754 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
3755 })
3756 .collect();
3757
3758 assert_eq!(all_arc_kps.len(), 2);
3759 }
3760
3761 #[test]
3762 fn test_pkp_filter_by_box_type() {
3763 use std::any::TypeId;
3764
3765 #[derive(Debug)]
3766 struct User {
3767 name: String,
3768 boxed_value: Box<i32>,
3769 boxed_string: Box<String>,
3770 }
3771
3772 let user = User {
3773 name: "Diana".to_string(),
3774 boxed_value: Box::new(100),
3775 boxed_string: Box::new("boxed".to_string()),
3776 };
3777
3778 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3780 let boxed_value_kp = KpType::new(
3781 |u: &User| Some(&u.boxed_value),
3782 |u: &mut User| Some(&mut u.boxed_value),
3783 );
3784 let boxed_string_kp = KpType::new(
3785 |u: &User| Some(&u.boxed_string),
3786 |u: &mut User| Some(&mut u.boxed_string),
3787 );
3788
3789 let all_keypaths: Vec<PKp<User>> = vec![
3790 PKp::new(name_kp),
3791 PKp::new(boxed_value_kp),
3792 PKp::new(boxed_string_kp),
3793 ];
3794
3795 let box_i32_kps: Vec<_> = all_keypaths
3797 .iter()
3798 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
3799 .collect();
3800
3801 assert_eq!(box_i32_kps.len(), 1);
3802 assert_eq!(
3803 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
3804 Some(100)
3805 );
3806
3807 let box_string_kps: Vec<_> = all_keypaths
3809 .iter()
3810 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
3811 .collect();
3812
3813 assert_eq!(box_string_kps.len(), 1);
3814 assert_eq!(
3815 box_string_kps[0]
3816 .get_as::<Box<String>>(&user)
3817 .map(|b| b.as_str()),
3818 Some("boxed")
3819 );
3820 }
3821
3822 #[test]
3823 fn test_akp_filter_by_root_and_value_type() {
3824 use std::any::TypeId;
3825
3826 #[derive(Debug)]
3827 struct User {
3828 name: String,
3829 age: i32,
3830 }
3831
3832 #[derive(Debug)]
3833 struct Product {
3834 title: String,
3835 price: f64,
3836 }
3837
3838 let user = User {
3839 name: "Eve".to_string(),
3840 age: 28,
3841 };
3842
3843 let product = Product {
3844 title: "Book".to_string(),
3845 price: 19.99,
3846 };
3847
3848 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3850 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3851 let product_title_kp = KpType::new(
3852 |p: &Product| Some(&p.title),
3853 |p: &mut Product| Some(&mut p.title),
3854 );
3855 let product_price_kp = KpType::new(
3856 |p: &Product| Some(&p.price),
3857 |p: &mut Product| Some(&mut p.price),
3858 );
3859
3860 let all_keypaths: Vec<AKp> = vec![
3861 AKp::new(user_name_kp),
3862 AKp::new(user_age_kp),
3863 AKp::new(product_title_kp),
3864 AKp::new(product_price_kp),
3865 ];
3866
3867 let user_kps: Vec<_> = all_keypaths
3869 .iter()
3870 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
3871 .collect();
3872
3873 assert_eq!(user_kps.len(), 2);
3874
3875 let product_kps: Vec<_> = all_keypaths
3877 .iter()
3878 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
3879 .collect();
3880
3881 assert_eq!(product_kps.len(), 2);
3882
3883 let string_value_kps: Vec<_> = all_keypaths
3885 .iter()
3886 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
3887 .collect();
3888
3889 assert_eq!(string_value_kps.len(), 2);
3890
3891 let user_string_kps: Vec<_> = all_keypaths
3893 .iter()
3894 .filter(|akp| {
3895 akp.root_type_id() == TypeId::of::<User>()
3896 && akp.value_type_id() == TypeId::of::<String>()
3897 })
3898 .collect();
3899
3900 assert_eq!(user_string_kps.len(), 1);
3901 assert_eq!(
3902 user_string_kps[0].get_as::<User, String>(&user),
3903 Some(Some(&"Eve".to_string()))
3904 );
3905
3906 let product_f64_kps: Vec<_> = all_keypaths
3908 .iter()
3909 .filter(|akp| {
3910 akp.root_type_id() == TypeId::of::<Product>()
3911 && akp.value_type_id() == TypeId::of::<f64>()
3912 })
3913 .collect();
3914
3915 assert_eq!(product_f64_kps.len(), 1);
3916 assert_eq!(
3917 product_f64_kps[0].get_as::<Product, f64>(&product),
3918 Some(Some(&19.99))
3919 );
3920 }
3921
3922 #[test]
3923 fn test_akp_filter_by_arc_root_type() {
3924 use std::any::TypeId;
3925 use std::sync::Arc;
3926
3927 #[derive(Debug)]
3928 struct User {
3929 name: String,
3930 }
3931
3932 #[derive(Debug)]
3933 struct Product {
3934 title: String,
3935 }
3936
3937 let user = User {
3938 name: "Frank".to_string(),
3939 };
3940 let product = Product {
3941 title: "Laptop".to_string(),
3942 };
3943
3944 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3946 let product_title_kp = KpType::new(
3947 |p: &Product| Some(&p.title),
3948 |p: &mut Product| Some(&mut p.title),
3949 );
3950
3951 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
3953 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
3954
3955 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
3956
3957 let arc_user_kps: Vec<_> = all_keypaths
3959 .iter()
3960 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
3961 .collect();
3962
3963 assert_eq!(arc_user_kps.len(), 1);
3964
3965 let arc_user = Arc::new(user);
3967 assert_eq!(
3968 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
3969 Some(Some(&"Frank".to_string()))
3970 );
3971
3972 let arc_product_kps: Vec<_> = all_keypaths
3974 .iter()
3975 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
3976 .collect();
3977
3978 assert_eq!(arc_product_kps.len(), 1);
3979
3980 let arc_product = Arc::new(product);
3982 assert_eq!(
3983 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
3984 Some(Some(&"Laptop".to_string()))
3985 );
3986 }
3987
3988 #[test]
3989 fn test_akp_filter_by_box_root_type() {
3990 use std::any::TypeId;
3991
3992 #[derive(Debug)]
3993 struct Config {
3994 setting: String,
3995 }
3996
3997 let config = Config {
3998 setting: "enabled".to_string(),
3999 };
4000
4001 let config_kp1 = KpType::new(
4003 |c: &Config| Some(&c.setting),
4004 |c: &mut Config| Some(&mut c.setting),
4005 );
4006 let config_kp2 = KpType::new(
4007 |c: &Config| Some(&c.setting),
4008 |c: &mut Config| Some(&mut c.setting),
4009 );
4010
4011 let regular_akp = AKp::new(config_kp1);
4013 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4014
4015 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4016
4017 let config_kps: Vec<_> = all_keypaths
4019 .iter()
4020 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4021 .collect();
4022
4023 assert_eq!(config_kps.len(), 1);
4024 assert_eq!(
4025 config_kps[0].get_as::<Config, String>(&config),
4026 Some(Some(&"enabled".to_string()))
4027 );
4028
4029 let box_config_kps: Vec<_> = all_keypaths
4031 .iter()
4032 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4033 .collect();
4034
4035 assert_eq!(box_config_kps.len(), 1);
4036
4037 let box_config = Box::new(Config {
4039 setting: "enabled".to_string(),
4040 });
4041 assert_eq!(
4042 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4043 Some(Some(&"enabled".to_string()))
4044 );
4045 }
4046
4047 #[test]
4048 fn test_mixed_collection_type_filtering() {
4049 use std::any::TypeId;
4050 use std::sync::Arc;
4051
4052 #[derive(Debug)]
4053 struct User {
4054 name: String,
4055 email: String,
4056 }
4057
4058 #[derive(Debug)]
4059 struct Product {
4060 title: String,
4061 sku: String,
4062 }
4063
4064 let user = User {
4065 name: "Grace".to_string(),
4066 email: "grace@example.com".to_string(),
4067 };
4068
4069 let product = Product {
4070 title: "Widget".to_string(),
4071 sku: "WID-001".to_string(),
4072 };
4073
4074 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4076 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4077 let user_email_kp1 =
4078 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4079 let user_email_kp2 =
4080 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4081 let product_title_kp = KpType::new(
4082 |p: &Product| Some(&p.title),
4083 |p: &mut Product| Some(&mut p.title),
4084 );
4085 let product_sku_kp = KpType::new(
4086 |p: &Product| Some(&p.sku),
4087 |p: &mut Product| Some(&mut p.sku),
4088 );
4089
4090 let all_keypaths: Vec<AKp> = vec![
4091 AKp::new(user_name_kp1),
4092 AKp::new(user_email_kp1),
4093 AKp::new(product_title_kp),
4094 AKp::new(product_sku_kp),
4095 AKp::new(user_name_kp2).for_arc::<User>(),
4096 AKp::new(user_email_kp2).for_box::<User>(),
4097 ];
4098
4099 let string_value_kps: Vec<_> = all_keypaths
4101 .iter()
4102 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4103 .collect();
4104
4105 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4109 .iter()
4110 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4111 .collect();
4112
4113 assert_eq!(user_root_kps.len(), 2);
4114
4115 let arc_user_kps: Vec<_> = all_keypaths
4117 .iter()
4118 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4119 .collect();
4120
4121 assert_eq!(arc_user_kps.len(), 1);
4122
4123 let box_user_kps: Vec<_> = all_keypaths
4125 .iter()
4126 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4127 .collect();
4128
4129 assert_eq!(box_user_kps.len(), 1);
4130
4131 let product_kps: Vec<_> = all_keypaths
4133 .iter()
4134 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4135 .collect();
4136
4137 assert_eq!(product_kps.len(), 2);
4138
4139 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4141 assert!(user_value.is_some());
4142 assert!(user_value.unwrap().is_some());
4143 }
4144
4145 #[test]
4150 fn test_kp_with_pin() {
4151 use std::pin::Pin;
4152
4153 #[derive(Debug)]
4157 struct SelfReferential {
4158 value: String,
4159 ptr_to_value: *const String, }
4161
4162 impl SelfReferential {
4163 fn new(s: String) -> Self {
4164 let mut sr = Self {
4165 value: s,
4166 ptr_to_value: std::ptr::null(),
4167 };
4168 sr.ptr_to_value = &sr.value as *const String;
4170 sr
4171 }
4172
4173 fn get_value(&self) -> &str {
4174 &self.value
4175 }
4176 }
4177
4178 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4180 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4181
4182 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4184 |p: &Pin<Box<SelfReferential>>| {
4185 Some(&p.as_ref().get_ref().value)
4187 },
4188 |p: &mut Pin<Box<SelfReferential>>| {
4189 unsafe {
4192 let sr = Pin::get_unchecked_mut(p.as_mut());
4193 Some(&mut sr.value)
4194 }
4195 },
4196 );
4197
4198 let result = kp.get(&pinned);
4200 assert_eq!(result, Some(&"pinned_data".to_string()));
4201
4202 assert_eq!(pinned.get_value(), "pinned_data");
4204 }
4205
4206 #[test]
4207 fn test_kp_with_pin_arc() {
4208 use std::pin::Pin;
4209 use std::sync::Arc;
4210
4211 struct AsyncState {
4212 status: String,
4213 data: Vec<i32>,
4214 }
4215
4216 let state = AsyncState {
4218 status: "ready".to_string(),
4219 data: vec![1, 2, 3, 4, 5],
4220 };
4221
4222 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4223
4224 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4226 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4227 |_: &mut Pin<Arc<AsyncState>>| {
4228 None::<&mut String>
4230 },
4231 );
4232
4233 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4235 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4236 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4237 );
4238
4239 let status = status_kp.get(&pinned_arc);
4240 assert_eq!(status, Some(&"ready".to_string()));
4241
4242 let data = data_kp.get(&pinned_arc);
4243 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4244 }
4245
4246 #[test]
4247 fn test_kp_with_maybe_uninit() {
4248 use std::mem::MaybeUninit;
4249
4250 struct Config {
4254 name: MaybeUninit<String>,
4255 value: MaybeUninit<i32>,
4256 initialized: bool,
4257 }
4258
4259 impl Config {
4260 fn new_uninit() -> Self {
4261 Self {
4262 name: MaybeUninit::uninit(),
4263 value: MaybeUninit::uninit(),
4264 initialized: false,
4265 }
4266 }
4267
4268 fn init(&mut self, name: String, value: i32) {
4269 self.name.write(name);
4270 self.value.write(value);
4271 self.initialized = true;
4272 }
4273
4274 fn get_name(&self) -> Option<&String> {
4275 if self.initialized {
4276 unsafe { Some(self.name.assume_init_ref()) }
4277 } else {
4278 None
4279 }
4280 }
4281
4282 fn get_value(&self) -> Option<&i32> {
4283 if self.initialized {
4284 unsafe { Some(self.value.assume_init_ref()) }
4285 } else {
4286 None
4287 }
4288 }
4289 }
4290
4291 let name_kp: KpType<Config, String> = Kp::new(
4293 |c: &Config| c.get_name(),
4294 |c: &mut Config| {
4295 if c.initialized {
4296 unsafe { Some(c.name.assume_init_mut()) }
4297 } else {
4298 None
4299 }
4300 },
4301 );
4302
4303 let value_kp: KpType<Config, i32> = Kp::new(
4304 |c: &Config| c.get_value(),
4305 |c: &mut Config| {
4306 if c.initialized {
4307 unsafe { Some(c.value.assume_init_mut()) }
4308 } else {
4309 None
4310 }
4311 },
4312 );
4313
4314 let uninit_config = Config::new_uninit();
4316 assert_eq!(name_kp.get(&uninit_config), None);
4317 assert_eq!(value_kp.get(&uninit_config), None);
4318
4319 let mut init_config = Config::new_uninit();
4321 init_config.init("test_config".to_string(), 42);
4322
4323 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4324 assert_eq!(value_kp.get(&init_config), Some(&42));
4325
4326 if let Some(val) = value_kp.get_mut(&mut init_config) {
4328 *val = 100;
4329 }
4330
4331 assert_eq!(value_kp.get(&init_config), Some(&100));
4332 }
4333
4334 #[test]
4335 fn test_kp_with_weak() {
4336 use std::sync::{Arc, Weak};
4337
4338 #[derive(Debug, Clone)]
4342 struct Node {
4343 value: i32,
4344 }
4345
4346 struct NodeWithParent {
4347 value: i32,
4348 parent: Option<Arc<Node>>, }
4350
4351 let parent = Arc::new(Node { value: 100 });
4352
4353 let child = NodeWithParent {
4354 value: 42,
4355 parent: Some(parent.clone()),
4356 };
4357
4358 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4360 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4361 |_: &mut NodeWithParent| None::<&mut i32>,
4362 );
4363
4364 let parent_val = parent_value_kp.get(&child);
4366 assert_eq!(parent_val, Some(&100));
4367 }
4368
4369 #[test]
4370 fn test_kp_with_rc_weak() {
4371 use std::rc::Rc;
4372
4373 struct TreeNode {
4376 value: String,
4377 parent: Option<Rc<TreeNode>>, }
4379
4380 let root = Rc::new(TreeNode {
4381 value: "root".to_string(),
4382 parent: None,
4383 });
4384
4385 let child1 = TreeNode {
4386 value: "child1".to_string(),
4387 parent: Some(root.clone()),
4388 };
4389
4390 let child2 = TreeNode {
4391 value: "child2".to_string(),
4392 parent: Some(root.clone()),
4393 };
4394
4395 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4397 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4398 |_: &mut TreeNode| None::<&mut String>,
4399 );
4400
4401 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4403 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4404
4405 assert_eq!(parent_name_kp.get(&root), None);
4407 }
4408
4409 #[test]
4410 fn test_kp_with_complex_weak_structure() {
4411 use std::sync::Arc;
4412
4413 struct Cache {
4416 data: String,
4417 backup: Option<Arc<Cache>>, }
4419
4420 let primary = Arc::new(Cache {
4421 data: "primary_data".to_string(),
4422 backup: None,
4423 });
4424
4425 let backup = Arc::new(Cache {
4426 data: "backup_data".to_string(),
4427 backup: Some(primary.clone()),
4428 });
4429
4430 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4432 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4433 |_: &mut Arc<Cache>| None::<&mut String>,
4434 );
4435
4436 let data = backup_data_kp.get(&backup);
4438 assert_eq!(data, Some(&"primary_data".to_string()));
4439
4440 let no_backup = backup_data_kp.get(&primary);
4442 assert_eq!(no_backup, None);
4443 }
4444
4445 #[test]
4446 fn test_kp_chain_with_pin_and_arc() {
4447 use std::pin::Pin;
4448 use std::sync::Arc;
4449
4450 struct Outer {
4453 inner: Arc<Inner>,
4454 }
4455
4456 struct Inner {
4457 value: String,
4458 }
4459
4460 let outer = Outer {
4461 inner: Arc::new(Inner {
4462 value: "nested_value".to_string(),
4463 }),
4464 };
4465
4466 let pinned_outer = Box::pin(outer);
4467
4468 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4470 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4471 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4472 );
4473
4474 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4476 |a: &Arc<Inner>| Some(&a.value),
4477 |_: &mut Arc<Inner>| None::<&mut String>,
4478 );
4479
4480 let chained = to_inner.then(to_value);
4482
4483 let result = chained.get(&pinned_outer);
4484 assert_eq!(result, Some(&"nested_value".to_string()));
4485 }
4486
4487 #[test]
4488 fn test_kp_with_maybe_uninit_array() {
4489 use std::mem::MaybeUninit;
4490
4491 struct Buffer {
4495 data: [MaybeUninit<u8>; 10],
4496 len: usize,
4497 }
4498
4499 impl Buffer {
4500 fn new() -> Self {
4501 Self {
4502 data: unsafe { MaybeUninit::uninit().assume_init() },
4503 len: 0,
4504 }
4505 }
4506
4507 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4508 if self.len >= self.data.len() {
4509 return Err("Buffer full");
4510 }
4511 self.data[self.len].write(byte);
4512 self.len += 1;
4513 Ok(())
4514 }
4515
4516 fn get(&self, idx: usize) -> Option<&u8> {
4517 if idx < self.len {
4518 unsafe { Some(self.data[idx].assume_init_ref()) }
4519 } else {
4520 None
4521 }
4522 }
4523
4524 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4525 if idx < self.len {
4526 unsafe { Some(self.data[idx].assume_init_mut()) }
4527 } else {
4528 None
4529 }
4530 }
4531 }
4532
4533 let len_kp: KpType<Buffer, usize> =
4535 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4536
4537 let mut buffer = Buffer::new();
4538
4539 assert_eq!(len_kp.get(&buffer), Some(&0));
4541
4542 buffer.push(1).unwrap();
4544 buffer.push(2).unwrap();
4545 buffer.push(3).unwrap();
4546
4547 assert_eq!(len_kp.get(&buffer), Some(&3));
4549
4550 assert_eq!(buffer.get(0), Some(&1));
4552 assert_eq!(buffer.get(1), Some(&2));
4553 assert_eq!(buffer.get(2), Some(&3));
4554 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4558 *elem = 20;
4559 }
4560 assert_eq!(buffer.get(1), Some(&20));
4561 }
4562
4563 #[test]
4564 fn test_kp_then_sync_deep_structs() {
4565 use std::sync::{Arc, Mutex};
4566
4567 #[derive(Clone)]
4568 struct Root {
4569 guard: Arc<Mutex<Level1>>,
4570 }
4571 #[derive(Clone)]
4572 struct Level1 {
4573 name: String,
4574 nested: Level2,
4575 }
4576 #[derive(Clone)]
4577 struct Level2 {
4578 count: i32,
4579 }
4580
4581 let root = Root {
4582 guard: Arc::new(Mutex::new(Level1 {
4583 name: "deep".to_string(),
4584 nested: Level2 { count: 42 },
4585 })),
4586 };
4587
4588 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4589 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4590
4591 let lock_kp = {
4592 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> = Kp::new(
4593 |g: &Arc<Mutex<Level1>>| Some(g),
4594 |g: &mut Arc<Mutex<Level1>>| Some(g),
4595 );
4596 let next: KpType<Level1, Level1> =
4597 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4598 crate::sync_kp::SyncKp::new(prev, crate::sync_kp::ArcMutexAccess::new(), next)
4599 };
4600
4601 let chained = kp_to_guard.then_sync(lock_kp);
4602 let level1 = chained.get(&root);
4603 assert!(level1.is_some());
4604 assert_eq!(level1.unwrap().name, "deep");
4605 assert_eq!(level1.unwrap().nested.count, 42);
4606
4607 let mut_root = &mut root.clone();
4608 let mut_level1 = chained.get_mut(mut_root);
4609 assert!(mut_level1.is_some());
4610 mut_level1.unwrap().nested.count = 99;
4611 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4612 }
4613
4614 #[test]
4615 fn test_kp_then_sync_with_enum() {
4616 use std::sync::{Arc, Mutex};
4617
4618 #[derive(Clone)]
4619 enum Message {
4620 Request(LevelA),
4621 Response(i32),
4622 }
4623 #[derive(Clone)]
4624 struct LevelA {
4625 data: Arc<Mutex<i32>>,
4626 }
4627
4628 struct RootWithEnum {
4629 msg: Arc<Mutex<Message>>,
4630 }
4631
4632 let root = RootWithEnum {
4633 msg: Arc::new(Mutex::new(Message::Request(LevelA {
4634 data: Arc::new(Mutex::new(100)),
4635 }))),
4636 };
4637
4638 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> = Kp::new(
4639 |r: &RootWithEnum| Some(&r.msg),
4640 |r: &mut RootWithEnum| Some(&mut r.msg),
4641 );
4642
4643 let lock_kp_msg = {
4644 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> = Kp::new(
4645 |m: &Arc<Mutex<Message>>| Some(m),
4646 |m: &mut Arc<Mutex<Message>>| Some(m),
4647 );
4648 let next: KpType<Message, Message> =
4649 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4650 crate::sync_kp::SyncKp::new(prev, crate::sync_kp::ArcMutexAccess::new(), next)
4651 };
4652
4653 let chained = kp_msg.then_sync(lock_kp_msg);
4654 let msg = chained.get(&root);
4655 assert!(msg.is_some());
4656 match msg.unwrap() {
4657 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
4658 Message::Response(_) => panic!("expected Request"),
4659 }
4660 }
4661
4662 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4663 #[tokio::test]
4664 async fn test_kp_then_async_deep_chain() {
4665 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4666 use std::sync::Arc;
4667
4668 #[derive(Clone)]
4669 struct Root {
4670 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
4671 }
4672 #[derive(Clone)]
4673 struct Level1 {
4674 value: i32,
4675 }
4676
4677 let root = Root {
4678 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
4679 };
4680
4681 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
4682 |r: &Root| Some(&r.tokio_guard),
4683 |r: &mut Root| Some(&mut r.tokio_guard),
4684 );
4685
4686 let async_kp = {
4687 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
4688 Kp::new(
4689 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
4690 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
4691 );
4692 let next: KpType<Level1, Level1> =
4693 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4694 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4695 };
4696
4697 let chained = kp_to_guard.then_async(async_kp);
4698 let level1 = chained.get(&root).await;
4699 assert!(level1.is_some());
4700 assert_eq!(level1.unwrap().value, 7);
4701 }
4702
4703 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4706 #[tokio::test]
4707 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
4708 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4709 use crate::sync_kp::{ArcMutexAccess, SyncKp};
4710 use std::sync::{Arc, Mutex};
4711
4712 #[derive(Clone)]
4714 struct Root {
4715 sync_mutex: Arc<Mutex<Level1>>,
4716 }
4717 #[derive(Clone)]
4719 struct Level1 {
4720 inner: Level2,
4721 }
4722 #[derive(Clone)]
4724 struct Level2 {
4725 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
4726 }
4727 #[derive(Clone)]
4729 struct Level3 {
4730 leaf: i32,
4731 }
4732
4733 let mut root = Root {
4734 sync_mutex: Arc::new(Mutex::new(Level1 {
4735 inner: Level2 {
4736 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
4737 },
4738 })),
4739 };
4740
4741 let identity_l1: KpType<Level1, Level1> =
4743 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4744 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
4745 |r: &Root| Some(&r.sync_mutex),
4746 |r: &mut Root| Some(&mut r.sync_mutex),
4747 );
4748 let lock_root_to_l1 = SyncKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
4749
4750 let kp_l1_inner: KpType<Level1, Level2> = Kp::new(
4752 |l: &Level1| Some(&l.inner),
4753 |l: &mut Level1| Some(&mut l.inner),
4754 );
4755
4756 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
4758 |l: &Level2| Some(&l.tokio_mutex),
4759 |l: &mut Level2| Some(&mut l.tokio_mutex),
4760 );
4761
4762 let async_l3 = {
4764 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
4765 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
4766 let next: KpType<Level3, Level3> =
4767 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
4768 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4769 };
4770
4771 let kp_l3_leaf: KpType<Level3, i32> = Kp::new(
4773 |l: &Level3| Some(&l.leaf),
4774 |l: &mut Level3| Some(&mut l.leaf),
4775 );
4776
4777 let step1 = lock_root_to_l1.then(kp_l1_inner);
4779 let step2 = step1.then(kp_l2_tokio);
4780 let step3 = step2.then_async(async_l3);
4781 let deep_chain = step3.then(kp_l3_leaf);
4782
4783 let leaf = deep_chain.get(&root).await;
4785 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
4786 assert_eq!(leaf, Some(&100));
4787
4788 let mut root_mut = root.clone();
4790 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
4791 assert!(leaf_mut.is_some());
4792 *leaf_mut.unwrap() = 99;
4793
4794 let leaf_after = deep_chain.get(&root_mut).await;
4796 assert_eq!(leaf_after, Some(&99));
4797 }
4798}