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