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
978pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
996where
997 Root: std::borrow::Borrow<R>,
998 MutRoot: std::borrow::BorrowMut<R>,
999 MutValue: std::borrow::BorrowMut<V>,
1000 G: Fn(Root) -> Option<Value>,
1001 S: Fn(MutRoot) -> Option<MutValue>,
1002{
1003 get: G,
1005 set: S,
1007 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
1008}
1009
1010impl<R, V, Root, Value, MutRoot, MutValue, G, S> Clone
1011 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1012where
1013 Root: std::borrow::Borrow<R>,
1014 MutRoot: std::borrow::BorrowMut<R>,
1015 MutValue: std::borrow::BorrowMut<V>,
1016 G: Fn(Root) -> Option<Value> + Clone,
1017 S: Fn(MutRoot) -> Option<MutValue> + Clone,
1018{
1019 fn clone(&self) -> Self {
1020 Self {
1021 get: self.get.clone(),
1022 set: self.set.clone(),
1023 _p: std::marker::PhantomData,
1024 }
1025 }
1026}
1027
1028impl<'a, R, V> Copy for KpType<'a, R, V> where R: 'static, V: 'static {}
1029
1030#[inline]
1032pub fn constrain_get<R, V, F>(f: F) -> F
1033where
1034 F: for<'b> Fn(&'b R) -> Option<&'b V>,
1035{
1036 f
1037}
1038
1039#[inline]
1041pub fn constrain_set<R, V, F>(f: F) -> F
1042where
1043 F: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1044{
1045 f
1046}
1047
1048impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1049where
1050 Root: std::borrow::Borrow<R>,
1051 Value: std::borrow::Borrow<V>,
1052 MutRoot: std::borrow::BorrowMut<R>,
1053 MutValue: std::borrow::BorrowMut<V>,
1054 G: Fn(Root) -> Option<Value>,
1055 S: Fn(MutRoot) -> Option<MutValue>,
1056{
1057 pub fn new(get: G, set: S) -> Self {
1058 Self {
1059 get,
1060 set,
1061 _p: std::marker::PhantomData,
1062 }
1063 }
1064
1065 #[inline]
1076 pub fn with_embed<E>(self, embedder: E) -> EnumKp<R, V, Root, Value, MutRoot, MutValue, G, S, E>
1077 where
1078 R: 'static,
1079 V: 'static,
1080 E: Fn(V) -> R,
1081 {
1082 EnumKp::new(self, embedder)
1083 }
1084
1085 #[inline]
1088 pub fn get(&self, root: Root) -> Option<Value> {
1089 (self.get)(root)
1090 }
1091
1092 #[inline]
1094 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1095 (self.set)(root)
1096 }
1097
1098 #[inline]
1101 pub fn get_ref<'a>(&self, root: &'a R) -> Option<&'a V>
1102 where
1103 G: for<'b> Fn(&'b R) -> Option<&'b V>,
1104 {
1105 (self.get)(root)
1106 }
1107
1108 #[inline]
1110 pub fn get_mut_ref<'a>(&self, root: &'a mut R) -> Option<&'a mut V>
1111 where
1112 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1113 {
1114 (self.set)(root)
1115 }
1116
1117 #[inline]
1118 pub fn then<SV, G2, S2>(
1119 self,
1120 next: Kp<
1121 V,
1122 SV,
1123 &'static V, &'static SV,
1125 &'static mut V,
1126 &'static mut SV,
1127 G2,
1128 S2,
1129 >,
1130 ) -> Kp<
1131 R,
1132 SV,
1133 &'static R,
1134 &'static SV,
1135 &'static mut R,
1136 &'static mut SV,
1137 impl for<'b> Fn(&'b R) -> Option<&'b SV>,
1138 impl for<'b> Fn(&'b mut R) -> Option<&'b mut SV>,
1139 >
1140 where
1141 G: for<'b> Fn(&'b R) -> Option<&'b V>,
1142 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1143 G2: for<'b> Fn(&'b V) -> Option<&'b SV>,
1144 S2: for<'b> Fn(&'b mut V) -> Option<&'b mut SV>,
1145 {
1146 let first_get = self.get;
1147 let first_set = self.set;
1148 let second_get = next.get;
1149 let second_set = next.set;
1150
1151 Kp::new(
1152 constrain_get(move |root: &R| first_get(root).and_then(|value| second_get(value))),
1153 constrain_set(move |root: &mut R| first_set(root).and_then(|value| second_set(value))),
1154 )
1155 }
1156
1157}
1158
1159impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Debug
1160 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1161where
1162 Root: std::borrow::Borrow<R>,
1163 Value: std::borrow::Borrow<V>,
1164 MutRoot: std::borrow::BorrowMut<R>,
1165 MutValue: std::borrow::BorrowMut<V>,
1166 G: Fn(Root) -> Option<Value>,
1167 S: Fn(MutRoot) -> Option<MutValue>,
1168{
1169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1170 f.debug_struct("Kp")
1171 .field("root_ty", &std::any::type_name::<R>())
1172 .field("value_ty", &std::any::type_name::<V>())
1173 .finish_non_exhaustive()
1174 }
1175}
1176
1177impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Display
1178 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1179where
1180 Root: std::borrow::Borrow<R>,
1181 Value: std::borrow::Borrow<V>,
1182 MutRoot: std::borrow::BorrowMut<R>,
1183 MutValue: std::borrow::BorrowMut<V>,
1184 G: Fn(Root) -> Option<Value>,
1185 S: Fn(MutRoot) -> Option<MutValue>,
1186{
1187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1188 write!(
1189 f,
1190 "Kp<{}, {}>",
1191 std::any::type_name::<R>(),
1192 std::any::type_name::<V>()
1193 )
1194 }
1195}
1196
1197pub fn zip_kps<'a, RootType, Value1, Value2>(
1211 kp1: &'a KpType<'a, RootType, Value1>,
1212 kp2: &'a KpType<'a, RootType, Value2>,
1213) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1214where
1215 RootType: 'a,
1216 Value1: 'a,
1217 Value2: 'a,
1218{
1219 move |root: &'a RootType| {
1220 let val1 = (kp1.get)(root)?;
1221 let val2 = (kp2.get)(root)?;
1222 Some((val1, val2))
1223 }
1224}
1225
1226impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1227where
1228 Root: std::borrow::Borrow<R>,
1229 MutRoot: std::borrow::BorrowMut<R>,
1230 G: Fn(Root) -> Option<Root>,
1231 S: Fn(MutRoot) -> Option<MutRoot>,
1232{
1233 pub fn identity_typed() -> Kp<
1234 R,
1235 R,
1236 Root,
1237 Root,
1238 MutRoot,
1239 MutRoot,
1240 fn(Root) -> Option<Root>,
1241 fn(MutRoot) -> Option<MutRoot>,
1242 > {
1243 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1244 }
1245
1246 pub fn identity<'a>() -> KpType<'a, R, R> {
1247 KpType::new(|r| Some(r), |r| Some(r))
1248 }
1249}
1250
1251pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1260where
1261 Root: std::borrow::Borrow<Enum>,
1262 Value: std::borrow::Borrow<Variant>,
1263 MutRoot: std::borrow::BorrowMut<Enum>,
1264 MutValue: std::borrow::BorrowMut<Variant>,
1265 G: Fn(Root) -> Option<Value>,
1266 S: Fn(MutRoot) -> Option<MutValue>,
1267 E: Fn(Variant) -> Enum,
1268{
1269 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1270 embedder: E,
1271}
1272
1273impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Clone
1274 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1275where
1276 Root: std::borrow::Borrow<Enum>,
1277 Value: std::borrow::Borrow<Variant>,
1278 MutRoot: std::borrow::BorrowMut<Enum>,
1279 MutValue: std::borrow::BorrowMut<Variant>,
1280 G: Fn(Root) -> Option<Value> + Clone,
1281 S: Fn(MutRoot) -> Option<MutValue> + Clone,
1282 E: Fn(Variant) -> Enum + Clone,
1283{
1284 fn clone(&self) -> Self {
1285 Self {
1286 extractor: self.extractor.clone(),
1287 embedder: self.embedder.clone(),
1288 }
1289 }
1290}
1291
1292unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1294 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1295where
1296 Root: std::borrow::Borrow<Enum>,
1297 Value: std::borrow::Borrow<Variant>,
1298 MutRoot: std::borrow::BorrowMut<Enum>,
1299 MutValue: std::borrow::BorrowMut<Variant>,
1300 G: Fn(Root) -> Option<Value> + Send,
1301 S: Fn(MutRoot) -> Option<MutValue> + Send,
1302 E: Fn(Variant) -> Enum + Send,
1303{
1304}
1305unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1306 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1307where
1308 Root: std::borrow::Borrow<Enum>,
1309 Value: std::borrow::Borrow<Variant>,
1310 MutRoot: std::borrow::BorrowMut<Enum>,
1311 MutValue: std::borrow::BorrowMut<Variant>,
1312 G: Fn(Root) -> Option<Value> + Sync,
1313 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1314 E: Fn(Variant) -> Enum + Sync,
1315{
1316}
1317
1318impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1319 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1320where
1321 Root: std::borrow::Borrow<Enum>,
1322 Value: std::borrow::Borrow<Variant>,
1323 MutRoot: std::borrow::BorrowMut<Enum>,
1324 MutValue: std::borrow::BorrowMut<Variant>,
1325 G: Fn(Root) -> Option<Value>,
1326 S: Fn(MutRoot) -> Option<MutValue>,
1327 E: Fn(Variant) -> Enum,
1328{
1329 pub fn new(
1331 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1332 embedder: E,
1333 ) -> Self {
1334 Self {
1335 extractor,
1336 embedder,
1337 }
1338 }
1339
1340 pub fn get(&self, enum_value: Root) -> Option<Value> {
1342 (self.extractor.get)(enum_value)
1343 }
1344
1345 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1347 (self.extractor.set)(enum_value)
1348 }
1349
1350 pub fn embed(&self, value: Variant) -> Enum {
1352 (self.embedder)(value)
1353 }
1354
1355 #[inline]
1357 pub fn get_ref<'a>(&self, enum_value: &'a Enum) -> Option<&'a Variant>
1358 where
1359 G: for<'b> Fn(&'b Enum) -> Option<&'b Variant>,
1360 {
1361 self.extractor.get_ref(enum_value)
1362 }
1363
1364 #[inline]
1366 pub fn embed_fn(&self) -> E
1367 where
1368 E: Copy,
1369 {
1370 self.embedder
1371 }
1372
1373 #[inline]
1386 pub fn then<Leaf, G2, S2, E2>(
1387 self,
1388 inner: EnumKp<
1389 Variant,
1390 Leaf,
1391 &'static Variant,
1392 &'static Leaf,
1393 &'static mut Variant,
1394 &'static mut Leaf,
1395 G2,
1396 S2,
1397 E2,
1398 >,
1399 ) -> EnumKp<
1400 Enum,
1401 Leaf,
1402 &'static Enum,
1403 &'static Leaf,
1404 &'static mut Enum,
1405 &'static mut Leaf,
1406 impl for<'b> Fn(&'b Enum) -> Option<&'b Leaf>,
1407 impl for<'b> Fn(&'b mut Enum) -> Option<&'b mut Leaf>,
1408 impl Fn(Leaf) -> Enum + Copy,
1409 >
1410 where
1411 Enum: 'static,
1412 Variant: 'static,
1413 Leaf: 'static,
1414 G: for<'b> Fn(&'b Enum) -> Option<&'b Variant>,
1415 S: for<'b> Fn(&'b mut Enum) -> Option<&'b mut Variant>,
1416 E: Fn(Variant) -> Enum + Copy,
1417 G2: for<'b> Fn(&'b Variant) -> Option<&'b Leaf>,
1418 S2: for<'b> Fn(&'b mut Variant) -> Option<&'b mut Leaf>,
1419 E2: Fn(Leaf) -> Variant + Copy,
1420 {
1421 let outer_embed = self.embedder;
1422 let inner_embed = inner.embedder;
1423 EnumKp::new(
1424 self.extractor.then(inner.extractor),
1425 move |leaf: Leaf| outer_embed(inner_embed(leaf)),
1426 )
1427 }
1428
1429 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1471 &self.extractor
1472 }
1473
1474 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1476 self.extractor
1477 }
1478
1479 pub fn map<MappedValue, F>(
1490 &self,
1491 mapper: F,
1492 ) -> EnumKp<
1493 Enum,
1494 MappedValue,
1495 Root,
1496 MappedValue,
1497 MutRoot,
1498 MappedValue,
1499 impl Fn(Root) -> Option<MappedValue>,
1500 impl Fn(MutRoot) -> Option<MappedValue>,
1501 impl Fn(MappedValue) -> Enum,
1502 >
1503 where
1504 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1507 Variant: 'static,
1508 MappedValue: 'static,
1509 E: Fn(Variant) -> Enum + Copy + 'static,
1511 {
1512 let mapped_extractor = self.extractor.map(mapper);
1513
1514 let new_embedder = move |_value: MappedValue| -> Enum {
1518 panic!(
1519 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1520 )
1521 };
1522
1523 EnumKp::new(mapped_extractor, new_embedder)
1524 }
1525
1526 pub fn filter<F>(
1538 &self,
1539 predicate: F,
1540 ) -> EnumKp<
1541 Enum,
1542 Variant,
1543 Root,
1544 Value,
1545 MutRoot,
1546 MutValue,
1547 impl Fn(Root) -> Option<Value>,
1548 impl Fn(MutRoot) -> Option<MutValue>,
1549 E,
1550 >
1551 where
1552 F: Fn(&Variant) -> bool + Copy + 'static,
1555 Variant: 'static,
1556 E: Copy,
1558 {
1559 let filtered_extractor = self.extractor.filter(predicate);
1560 EnumKp::new(filtered_extractor, self.embedder)
1561 }
1562}
1563
1564impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Debug
1565 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1566where
1567 Root: std::borrow::Borrow<Enum>,
1568 Value: std::borrow::Borrow<Variant>,
1569 MutRoot: std::borrow::BorrowMut<Enum>,
1570 MutValue: std::borrow::BorrowMut<Variant>,
1571 G: Fn(Root) -> Option<Value>,
1572 S: Fn(MutRoot) -> Option<MutValue>,
1573 E: Fn(Variant) -> Enum,
1574{
1575 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1576 f.debug_struct("EnumKp")
1577 .field("enum_ty", &std::any::type_name::<Enum>())
1578 .field("variant_ty", &std::any::type_name::<Variant>())
1579 .finish_non_exhaustive()
1580 }
1581}
1582
1583impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Display
1584 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1585where
1586 Root: std::borrow::Borrow<Enum>,
1587 Value: std::borrow::Borrow<Variant>,
1588 MutRoot: std::borrow::BorrowMut<Enum>,
1589 MutValue: std::borrow::BorrowMut<Variant>,
1590 G: Fn(Root) -> Option<Value>,
1591 S: Fn(MutRoot) -> Option<MutValue>,
1592 E: Fn(Variant) -> Enum,
1593{
1594 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1595 write!(
1596 f,
1597 "EnumKp<{}, {}>",
1598 std::any::type_name::<Enum>(),
1599 std::any::type_name::<Variant>()
1600 )
1601 }
1602}
1603
1604pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1606 Enum,
1607 Variant,
1608 &'a Enum,
1609 &'a Variant,
1610 &'a mut Enum,
1611 &'a mut Variant,
1612 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1613 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1614 fn(Variant) -> Enum,
1615>;
1616
1617impl<'a, R: 'static, V: 'static> Copy for EnumKpType<'a, R, V> {}
1618
1619pub type EnumValueKpType<'a, Enum, Payload> = EnumKp<
1629 Enum,
1630 Payload,
1631 &'a Enum,
1632 Payload,
1633 &'a mut Enum,
1634 Payload,
1635 for<'b> fn(&'b Enum) -> Option<Payload>,
1636 for<'b> fn(&'b mut Enum) -> Option<Payload>,
1637 fn(Payload) -> Enum,
1638>;
1639
1640pub fn enum_variant<'a, Enum, Variant>(
1658 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1659 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1660 embedder: fn(Variant) -> Enum,
1661) -> EnumKpType<'a, Enum, Variant> {
1662 EnumKp::new(Kp::new(getter, setter), embedder)
1663}
1664
1665pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1675 EnumKp::new(
1676 Kp::new(
1677 |r: &Result<T, E>| r.as_ref().ok(),
1678 |r: &mut Result<T, E>| r.as_mut().ok(),
1679 ),
1680 |t: T| Ok(t),
1681 )
1682}
1683
1684pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1694 EnumKp::new(
1695 Kp::new(
1696 |r: &Result<T, E>| r.as_ref().err(),
1697 |r: &mut Result<T, E>| r.as_mut().err(),
1698 ),
1699 |e: E| Err(e),
1700 )
1701}
1702
1703pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1713 EnumKp::new(
1714 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1715 |t: T| Some(t),
1716 )
1717}
1718
1719pub fn variant_of<'a, Enum, Variant>(
1737 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1738 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1739 embedder: fn(Variant) -> Enum,
1740) -> EnumKpType<'a, Enum, Variant> {
1741 enum_variant(getter, setter, embedder)
1742}
1743
1744pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1757 Kp::new(
1758 |b: &Box<T>| Some(b.as_ref()),
1759 |b: &mut Box<T>| Some(b.as_mut()),
1760 )
1761}
1762
1763pub fn kp_arc<'a, T>() -> Kp<
1774 Arc<T>,
1775 T,
1776 &'a Arc<T>,
1777 &'a T,
1778 &'a mut Arc<T>,
1779 &'a mut T,
1780 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
1781 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
1782> {
1783 Kp::new(
1784 |arc: &Arc<T>| Some(arc.as_ref()),
1785 |arc: &mut Arc<T>| Arc::get_mut(arc),
1786 )
1787}
1788
1789pub fn kp_rc<'a, T>() -> Kp<
1800 std::rc::Rc<T>,
1801 T,
1802 &'a std::rc::Rc<T>,
1803 &'a T,
1804 &'a mut std::rc::Rc<T>,
1805 &'a mut T,
1806 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
1807 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
1808> {
1809 Kp::new(
1810 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
1811 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
1812 )
1813}
1814
1815use std::any::{Any, TypeId};
1818use std::rc::Rc;
1819
1820#[cfg(test)]
1835mod tests {
1836 use super::*;
1837 use std::collections::HashMap;
1838
1839 fn kp_adaptable<T, Root, Value, MutRoot, MutValue, G, S>(kp: T)
1840 where
1841 T: KpTrait<TestKP, String, Root, Value, MutRoot, MutValue>,
1842 {
1843 }
1846 fn test_kp_trait() {}
1847
1848 #[derive(Debug)]
1849 struct TestKP {
1850 a: String,
1851 b: String,
1852 c: std::sync::Arc<String>,
1853 d: std::sync::Mutex<String>,
1854 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
1855 f: Option<TestKP2>,
1856 g: HashMap<i32, TestKP2>,
1857 }
1858
1859 impl TestKP {
1860 fn new() -> Self {
1861 Self {
1862 a: String::from("a"),
1863 b: String::from("b"),
1864 c: std::sync::Arc::new(String::from("c")),
1865 d: std::sync::Mutex::new(String::from("d")),
1866 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
1867 f: Some(TestKP2 {
1868 a: String::from("a3"),
1869 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1870 }),
1871 g: HashMap::new(),
1872 }
1873 }
1874
1875 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
1876 KpComposed::from_closures(
1877 move |r: &TestKP| r.g.get(&index),
1878 move |r: &mut TestKP| r.g.get_mut(&index),
1879 )
1880 }
1881
1882 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
1885 TestKP2,
1886 String,
1887 Root,
1888 Value,
1889 MutRoot,
1890 MutValue,
1891 impl Fn(Root) -> Option<Value>,
1892 impl Fn(MutRoot) -> Option<MutValue>,
1893 >
1894 where
1895 Root: std::borrow::Borrow<TestKP2>,
1896 MutRoot: std::borrow::BorrowMut<TestKP2>,
1897 Value: std::borrow::Borrow<String> + From<String>,
1898 MutValue: std::borrow::BorrowMut<String> + From<String>,
1899 {
1900 Kp::new(
1901 |r: Root| Some(Value::from(r.borrow().a.clone())),
1902 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
1903 )
1904 }
1905
1906 fn c<'a>() -> KpType<'a, TestKP, String> {
1909 KpType::new(
1910 |r: &TestKP| Some(r.c.as_ref()),
1911 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
1912 Some(arc_str) => Some(arc_str),
1913 None => None,
1914 },
1915 )
1916 }
1917
1918 fn a<'a>() -> KpType<'a, TestKP, String> {
1919 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
1920 }
1921
1922 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
1923 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
1924 }
1925
1926 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
1927 KpType::identity()
1928 }
1929 }
1930
1931 #[test]
1932 fn kp_debug_display_uses_type_names() {
1933 let kp = TestKP::a();
1934 let dbg = format!("{kp:?}");
1935 assert!(dbg.starts_with("Kp {"), "{dbg}");
1936 assert!(dbg.contains("root_ty") && dbg.contains("value_ty"), "{dbg}");
1937 let disp = format!("{kp}");
1938 assert!(disp.contains("TestKP"), "{disp}");
1939 assert!(disp.contains("String"), "{disp}");
1940 }
1941
1942 #[test]
1943 fn akp_and_pkp_debug_display() {
1944 let akp = AKp::new(TestKP::a());
1945 assert!(format!("{akp:?}").starts_with("AKp"));
1946 let pkp = PKp::new(TestKP::a());
1947 let pkp_dbg = format!("{pkp:?}");
1948 assert!(pkp_dbg.starts_with("PKp"), "{pkp_dbg}");
1949 assert!(format!("{pkp}").contains("TestKP"));
1950 }
1951
1952 #[test]
1953 fn enum_kp_debug_display() {
1954 let ok_kp = enum_ok::<i32, String>();
1955 assert!(format!("{ok_kp:?}").contains("EnumKp"));
1956 let s = format!("{ok_kp}");
1957 assert!(s.contains("Result") && s.contains("i32"), "{s}");
1958 }
1959
1960 #[test]
1961 fn composed_kp_into_dynamic_stores_as_kp_dynamic() {
1962 let path: KpDynamic<TestKP, String> = TestKP::f().then(TestKP2::a()).into_dynamic();
1963 let mut t = TestKP::new();
1964 assert_eq!(path.get(&t), Some(&"a3".to_string()));
1965 path.get_mut(&mut t).map(|s| *s = "x".into());
1966 assert_eq!(t.f.as_ref().unwrap().a, "x");
1967 }
1968
1969 #[derive(Debug)]
1970 struct TestKP2 {
1971 a: String,
1972 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
1973 }
1974
1975 impl TestKP2 {
1976 fn new() -> Self {
1977 TestKP2 {
1978 a: String::from("a2"),
1979 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1980 }
1981 }
1982
1983 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1984 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
1991 fn(MutRoot) -> Option<MutRoot>,
1992 >
1993 where
1994 Root: std::borrow::Borrow<TestKP2>,
1995 MutRoot: std::borrow::BorrowMut<TestKP2>,
1996 G: Fn(Root) -> Option<Root>,
1997 S: Fn(MutRoot) -> Option<MutRoot>,
1998 {
1999 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2000 }
2001
2002 fn a<'a>() -> KpType<'a, TestKP2, String> {
2003 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2004 }
2005
2006 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2007 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2008 }
2009
2010 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2015 KpType::identity()
2016 }
2017 }
2018
2019 #[derive(Debug)]
2020 struct TestKP3 {
2021 a: String,
2022 b: std::sync::Arc<std::sync::Mutex<String>>,
2023 }
2024
2025 impl TestKP3 {
2026 fn new() -> Self {
2027 TestKP3 {
2028 a: String::from("a2"),
2029 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2030 }
2031 }
2032
2033 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2034 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2041 fn(MutRoot) -> Option<MutRoot>,
2042 >
2043 where
2044 Root: std::borrow::Borrow<TestKP3>,
2045 MutRoot: std::borrow::BorrowMut<TestKP3>,
2046 G: Fn(Root) -> Option<Root>,
2047 S: Fn(MutRoot) -> Option<MutRoot>,
2048 {
2049 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2050 }
2051
2052 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2053 KpType::identity()
2054 }
2055 }
2056
2057 impl TestKP3 {}
2058
2059 impl TestKP {}
2060 #[test]
2061 fn test_a() {
2062 let instance2 = TestKP2::new();
2063 let mut instance = TestKP::new();
2064 let kp = TestKP::identity();
2065 let kp_a = TestKP::a();
2066 let wres = TestKP::f()
2068 .then(TestKP2::a())
2069 .get_mut(&mut instance)
2070 .unwrap();
2071 *wres = String::from("a3 changed successfully");
2072 let res = (TestKP::f().then(TestKP2::a()).get)(&instance);
2073 println!("{:?}", res);
2074 let res = (TestKP::f().then(TestKP2::identity()).get)(&instance);
2075 println!("{:?}", res);
2076 let res = (kp.get)(&instance);
2077 println!("{:?}", res);
2078
2079 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2080 println!("{:?}", (new_kp_from_hashmap.get)(&instance));
2081 }
2082
2083 #[test]
2162 fn test_enum_kp_result_ok() {
2163 let ok_result: Result<String, i32> = Ok("success".to_string());
2164 let mut err_result: Result<String, i32> = Err(42);
2165
2166 let ok_kp = enum_ok();
2167
2168 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2170 assert_eq!(ok_kp.get(&err_result), None);
2171
2172 let embedded = ok_kp.embed("embedded".to_string());
2174 assert_eq!(embedded, Ok("embedded".to_string()));
2175
2176 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2178 *val = "modified".to_string();
2179 }
2180 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2183 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2184 *val = "modified".to_string();
2185 }
2186 assert_eq!(ok_result2, Ok("modified".to_string()));
2187 }
2188
2189 #[test]
2190 fn test_enum_kp_result_err() {
2191 let ok_result: Result<String, i32> = Ok("success".to_string());
2192 let mut err_result: Result<String, i32> = Err(42);
2193
2194 let err_kp = enum_err();
2195
2196 assert_eq!(err_kp.get(&err_result), Some(&42));
2198 assert_eq!(err_kp.get(&ok_result), None);
2199
2200 let embedded = err_kp.embed(99);
2202 assert_eq!(embedded, Err(99));
2203
2204 if let Some(val) = err_kp.get_mut(&mut err_result) {
2206 *val = 100;
2207 }
2208 assert_eq!(err_result, Err(100));
2209 }
2210
2211 #[test]
2212 fn test_enum_kp_option_some() {
2213 let some_opt = Some("value".to_string());
2214 let mut none_opt: Option<String> = None;
2215
2216 let some_kp = enum_some();
2217
2218 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2220 assert_eq!(some_kp.get(&none_opt), None);
2221
2222 let embedded = some_kp.embed("embedded".to_string());
2224 assert_eq!(embedded, Some("embedded".to_string()));
2225
2226 let mut some_opt2 = Some("original".to_string());
2228 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2229 *val = "modified".to_string();
2230 }
2231 assert_eq!(some_opt2, Some("modified".to_string()));
2232 }
2233
2234 #[test]
2235 fn test_enum_kp_custom_enum() {
2236 #[derive(Debug, PartialEq)]
2237 enum MyEnum {
2238 A(String),
2239 B(i32),
2240 C,
2241 }
2242
2243 let mut enum_a = MyEnum::A("hello".to_string());
2244 let enum_b = MyEnum::B(42);
2245 let enum_c = MyEnum::C;
2246
2247 let kp_a = enum_variant(
2249 |e: &MyEnum| match e {
2250 MyEnum::A(s) => Some(s),
2251 _ => None,
2252 },
2253 |e: &mut MyEnum| match e {
2254 MyEnum::A(s) => Some(s),
2255 _ => None,
2256 },
2257 |s: String| MyEnum::A(s),
2258 );
2259
2260 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2262 assert_eq!(kp_a.get(&enum_b), None);
2263 assert_eq!(kp_a.get(&enum_c), None);
2264
2265 let embedded = kp_a.embed("world".to_string());
2267 assert_eq!(embedded, MyEnum::A("world".to_string()));
2268
2269 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2271 *val = "modified".to_string();
2272 }
2273 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2274 }
2275
2276 #[test]
2277 fn test_container_kp_box() {
2278 let boxed = Box::new("value".to_string());
2279 let mut boxed_mut = Box::new("original".to_string());
2280
2281 let box_kp = kp_box();
2282
2283 assert_eq!((box_kp.get)(&boxed), Some(&"value".to_string()));
2285
2286 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2288 *val = "modified".to_string();
2289 }
2290 assert_eq!(*boxed_mut, "modified".to_string());
2291 }
2292
2293 #[test]
2294 fn test_container_kp_arc() {
2295 let arc = Arc::new("value".to_string());
2296 let mut arc_mut = Arc::new("original".to_string());
2297
2298 let arc_kp = kp_arc();
2299
2300 assert_eq!((arc_kp.get)(&arc), Some(&"value".to_string()));
2302
2303 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2305 *val = "modified".to_string();
2306 }
2307 assert_eq!(*arc_mut, "modified".to_string());
2308
2309 let arc_shared = Arc::new("shared".to_string());
2311 let arc_shared2 = Arc::clone(&arc_shared);
2312 let mut arc_shared_mut = arc_shared;
2313 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2314 }
2315
2316 #[test]
2317 fn test_enum_kp_composition() {
2318 #[derive(Debug, PartialEq)]
2320 struct Inner {
2321 value: String,
2322 }
2323
2324 let result: Result<Inner, i32> = Ok(Inner {
2325 value: "nested".to_string(),
2326 });
2327
2328 let inner_kp = KpType::new(
2330 |i: &Inner| Some(&i.value),
2331 |i: &mut Inner| Some(&mut i.value),
2332 );
2333
2334 let ok_kp = enum_ok::<Inner, i32>();
2336 let ok_kp_base = ok_kp.into_kp();
2337 let composed = ok_kp_base.then(inner_kp);
2338
2339 assert_eq!((composed.get)(&result), Some(&"nested".to_string()));
2340 }
2341
2342 #[test]
2343 fn test_pkp_basic() {
2344 #[derive(Debug)]
2345 struct User {
2346 name: String,
2347 age: i32,
2348 }
2349
2350 let user = User {
2351 name: "Akash".to_string(),
2352 age: 30,
2353 };
2354
2355 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2357 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2358
2359 let name_pkp = PKp::new(name_kp);
2361 let age_pkp = PKp::new(age_kp);
2362
2363 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Akash".to_string()));
2365 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2366
2367 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2369 assert_eq!(age_pkp.get_as::<String>(&user), None);
2370
2371 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2373 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2374 }
2375
2376 #[test]
2377 fn test_pkp_collection() {
2378 #[derive(Debug)]
2379 struct User {
2380 name: String,
2381 age: i32,
2382 }
2383
2384 let user = User {
2385 name: "Bob".to_string(),
2386 age: 25,
2387 };
2388
2389 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2391 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2392
2393 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2394
2395 let name_value = keypaths[0].get_as::<String>(&user);
2397 let age_value = keypaths[1].get_as::<i32>(&user);
2398
2399 assert_eq!(name_value, Some(&"Bob".to_string()));
2400 assert_eq!(age_value, Some(&25));
2401 }
2402
2403 #[test]
2404 fn test_pkp_for_arc() {
2405 #[derive(Debug)]
2406 struct User {
2407 name: String,
2408 }
2409
2410 let user = Arc::new(User {
2411 name: "Charlie".to_string(),
2412 });
2413
2414 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2415 let name_pkp = PKp::new(name_kp);
2416
2417 let arc_pkp = name_pkp.for_arc();
2419
2420 assert_eq!(
2421 arc_pkp.get_as::<String>(&user),
2422 Some(&"Charlie".to_string())
2423 );
2424 }
2425
2426 #[test]
2427 fn test_pkp_for_option() {
2428 #[derive(Debug)]
2429 struct User {
2430 name: String,
2431 }
2432
2433 let some_user = Some(User {
2434 name: "Diana".to_string(),
2435 });
2436 let none_user: Option<User> = None;
2437
2438 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2439 let name_pkp = PKp::new(name_kp);
2440
2441 let opt_pkp = name_pkp.for_option();
2443
2444 assert_eq!(
2445 opt_pkp.get_as::<String>(&some_user),
2446 Some(&"Diana".to_string())
2447 );
2448 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2449 }
2450
2451 #[test]
2452 fn test_akp_basic() {
2453 #[derive(Debug)]
2454 struct User {
2455 name: String,
2456 age: i32,
2457 }
2458
2459 #[derive(Debug)]
2460 struct Product {
2461 title: String,
2462 price: f64,
2463 }
2464
2465 let user = User {
2466 name: "Eve".to_string(),
2467 age: 28,
2468 };
2469
2470 let product = Product {
2471 title: "Book".to_string(),
2472 price: 19.99,
2473 };
2474
2475 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2477 let user_name_akp = AKp::new(user_name_kp);
2478
2479 let product_title_kp = KpType::new(
2480 |p: &Product| Some(&p.title),
2481 |p: &mut Product| Some(&mut p.title),
2482 );
2483 let product_title_akp = AKp::new(product_title_kp);
2484
2485 assert_eq!(
2487 user_name_akp.get_as::<User, String>(&user),
2488 Some(Some(&"Eve".to_string()))
2489 );
2490 assert_eq!(
2491 product_title_akp.get_as::<Product, String>(&product),
2492 Some(Some(&"Book".to_string()))
2493 );
2494
2495 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2497 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2498
2499 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2501 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2502 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2503 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2504 }
2505
2506 #[test]
2507 fn test_akp_heterogeneous_collection() {
2508 #[derive(Debug)]
2509 struct User {
2510 name: String,
2511 }
2512
2513 #[derive(Debug)]
2514 struct Product {
2515 title: String,
2516 }
2517
2518 let user = User {
2519 name: "Frank".to_string(),
2520 };
2521 let product = Product {
2522 title: "Laptop".to_string(),
2523 };
2524
2525 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2527 let product_title_kp = KpType::new(
2528 |p: &Product| Some(&p.title),
2529 |p: &mut Product| Some(&mut p.title),
2530 );
2531
2532 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2533
2534 let user_any: &dyn Any = &user;
2536 let product_any: &dyn Any = &product;
2537
2538 let user_value = keypaths[0].get(user_any);
2539 let product_value = keypaths[1].get(product_any);
2540
2541 assert!(user_value.is_some());
2542 assert!(product_value.is_some());
2543
2544 assert_eq!(
2546 user_value.and_then(|v| v.downcast_ref::<String>()),
2547 Some(&"Frank".to_string())
2548 );
2549 assert_eq!(
2550 product_value.and_then(|v| v.downcast_ref::<String>()),
2551 Some(&"Laptop".to_string())
2552 );
2553 }
2554
2555 #[test]
2556 fn test_akp_for_option() {
2557 #[derive(Debug)]
2558 struct User {
2559 name: String,
2560 }
2561
2562 let some_user = Some(User {
2563 name: "Grace".to_string(),
2564 });
2565 let none_user: Option<User> = None;
2566
2567 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2568 let name_akp = AKp::new(name_kp);
2569
2570 let opt_akp = name_akp.for_option::<User>();
2572
2573 assert_eq!(
2574 opt_akp.get_as::<Option<User>, String>(&some_user),
2575 Some(Some(&"Grace".to_string()))
2576 );
2577 assert_eq!(
2578 opt_akp.get_as::<Option<User>, String>(&none_user),
2579 Some(None)
2580 );
2581 }
2582
2583 #[test]
2584 fn test_akp_for_result() {
2585 #[derive(Debug)]
2586 struct User {
2587 name: String,
2588 }
2589
2590 let ok_user: Result<User, String> = Ok(User {
2591 name: "Henry".to_string(),
2592 });
2593 let err_user: Result<User, String> = Err("Not found".to_string());
2594
2595 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2596 let name_akp = AKp::new(name_kp);
2597
2598 let result_akp = name_akp.for_result::<User, String>();
2600
2601 assert_eq!(
2602 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2603 Some(Some(&"Henry".to_string()))
2604 );
2605 assert_eq!(
2606 result_akp.get_as::<Result<User, String>, String>(&err_user),
2607 Some(None)
2608 );
2609 }
2610
2611 #[test]
2614 fn test_kp_map() {
2615 #[derive(Debug)]
2616 struct User {
2617 name: String,
2618 age: i32,
2619 }
2620
2621 let user = User {
2622 name: "Akash".to_string(),
2623 age: 30,
2624 };
2625
2626 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2628 let len_kp = name_kp.map(|name: &String| name.len());
2629
2630 assert_eq!((len_kp.get)(&user), Some(5));
2631
2632 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2634 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2635
2636 assert_eq!((double_age_kp.get)(&user), Some(60));
2637
2638 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2640 assert_eq!((is_adult_kp.get)(&user), Some(true));
2641 }
2642
2643 #[test]
2644 fn test_kp_filter() {
2645 #[derive(Debug)]
2646 struct User {
2647 name: String,
2648 age: i32,
2649 }
2650
2651 let adult = User {
2652 name: "Akash".to_string(),
2653 age: 30,
2654 };
2655
2656 let minor = User {
2657 name: "Bob".to_string(),
2658 age: 15,
2659 };
2660
2661 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2662 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2663
2664 assert_eq!((adult_age_kp.get)(&adult), Some(&30));
2665 assert_eq!((adult_age_kp.get)(&minor), None);
2666
2667 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2669 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2670
2671 assert_eq!((short_name_kp.get)(&minor), Some(&"Bob".to_string()));
2672 assert_eq!((short_name_kp.get)(&adult), None);
2673 }
2674
2675 #[test]
2676 fn test_kp_map_and_filter() {
2677 #[derive(Debug)]
2678 struct User {
2679 scores: Vec<i32>,
2680 }
2681
2682 let user = User {
2683 scores: vec![85, 92, 78, 95],
2684 };
2685
2686 let scores_kp = KpType::new(
2687 |u: &User| Some(&u.scores),
2688 |u: &mut User| Some(&mut u.scores),
2689 );
2690
2691 let avg_kp =
2693 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2694
2695 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2697
2698 assert_eq!((high_avg_kp.get)(&user), Some(87)); }
2700
2701 #[test]
2702 fn test_enum_kp_map() {
2703 let ok_result: Result<String, i32> = Ok("hello".to_string());
2704 let err_result: Result<String, i32> = Err(42);
2705
2706 let ok_kp = enum_ok::<String, i32>();
2707 let len_kp = ok_kp.map(|s: &String| s.len());
2708
2709 assert_eq!(len_kp.get(&ok_result), Some(5));
2710 assert_eq!(len_kp.get(&err_result), None);
2711
2712 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2714 let none_opt: Option<Vec<i32>> = None;
2715
2716 let some_kp = enum_some::<Vec<i32>>();
2717 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2718
2719 assert_eq!(count_kp.get(&some_opt), Some(5));
2720 assert_eq!(count_kp.get(&none_opt), None);
2721 }
2722
2723 #[test]
2724 fn test_enum_kp_filter() {
2725 let ok_result1: Result<i32, String> = Ok(42);
2726 let ok_result2: Result<i32, String> = Ok(-5);
2727 let err_result: Result<i32, String> = Err("error".to_string());
2728
2729 let ok_kp = enum_ok::<i32, String>();
2730 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2731
2732 assert_eq!((positive_kp.extractor.get)(&ok_result1), Some(&42));
2733 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2738 let short_str = Some("hi".to_string());
2739
2740 let some_kp = enum_some::<String>();
2741 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2742
2743 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2744 assert_eq!(long_kp.get(&short_str), None);
2745 }
2746
2747 #[test]
2748 fn test_pkp_filter() {
2749 #[derive(Debug)]
2750 struct User {
2751 name: String,
2752 age: i32,
2753 }
2754
2755 let adult = User {
2756 name: "Akash".to_string(),
2757 age: 30,
2758 };
2759
2760 let minor = User {
2761 name: "Bob".to_string(),
2762 age: 15,
2763 };
2764
2765 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2766 let age_pkp = PKp::new(age_kp);
2767
2768 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2770
2771 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2772 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2773
2774 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2776 let name_pkp = PKp::new(name_kp);
2777 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2778
2779 assert_eq!(
2780 short_name_pkp.get_as::<String>(&minor),
2781 Some(&"Bob".to_string())
2782 );
2783 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2784 }
2785
2786 #[test]
2787 fn test_akp_filter() {
2788 #[derive(Debug)]
2789 struct User {
2790 age: i32,
2791 }
2792
2793 #[derive(Debug)]
2794 struct Product {
2795 price: f64,
2796 }
2797
2798 let adult = User { age: 30 };
2799 let minor = User { age: 15 };
2800 let expensive = Product { price: 99.99 };
2801 let cheap = Product { price: 5.0 };
2802
2803 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2805 let age_akp = AKp::new(age_kp);
2806 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2807
2808 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2809 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2810
2811 let price_kp = KpType::new(
2813 |p: &Product| Some(&p.price),
2814 |p: &mut Product| Some(&mut p.price),
2815 );
2816 let price_akp = AKp::new(price_kp);
2817 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2818
2819 assert_eq!(
2820 expensive_akp.get_as::<Product, f64>(&expensive),
2821 Some(Some(&99.99))
2822 );
2823 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2824 }
2825
2826 #[test]
2829 fn test_kp_filter_map() {
2830 #[derive(Debug)]
2831 struct User {
2832 middle_name: Option<String>,
2833 }
2834
2835 let user_with = User {
2836 middle_name: Some("Marie".to_string()),
2837 };
2838 let user_without = User { middle_name: None };
2839
2840 let middle_kp = KpType::new(
2841 |u: &User| Some(&u.middle_name),
2842 |u: &mut User| Some(&mut u.middle_name),
2843 );
2844
2845 let first_char_kp = middle_kp
2846 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
2847
2848 assert_eq!((first_char_kp.get)(&user_with), Some('M'));
2849 assert_eq!((first_char_kp.get)(&user_without), None);
2850 }
2851
2852 #[test]
2853 fn test_kp_inspect() {
2854 #[derive(Debug)]
2855 struct User {
2856 name: String,
2857 }
2858
2859 let user = User {
2860 name: "Akash".to_string(),
2861 };
2862
2863 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2867
2868 let result = (name_kp.get)(&user);
2871 assert_eq!(result, Some(&"Akash".to_string()));
2872
2873 }
2876
2877 #[test]
2878 fn test_kp_fold_value() {
2879 #[derive(Debug)]
2880 struct User {
2881 scores: Vec<i32>,
2882 }
2883
2884 let user = User {
2885 scores: vec![85, 92, 78, 95],
2886 };
2887
2888 let scores_kp = KpType::new(
2889 |u: &User| Some(&u.scores),
2890 |u: &mut User| Some(&mut u.scores),
2891 );
2892
2893 let sum_fn =
2895 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
2896
2897 assert_eq!(sum_fn(&user), 350);
2898 }
2899
2900 #[test]
2901 fn test_kp_any_all() {
2902 #[derive(Debug)]
2903 struct User {
2904 scores: Vec<i32>,
2905 }
2906
2907 let user_high = User {
2908 scores: vec![85, 92, 88],
2909 };
2910 let user_mixed = User {
2911 scores: vec![65, 92, 78],
2912 };
2913
2914 let scores_kp = KpType::new(
2915 |u: &User| Some(&u.scores),
2916 |u: &mut User| Some(&mut u.scores),
2917 );
2918
2919 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
2921 assert!(has_high_fn(&user_high));
2922 assert!(has_high_fn(&user_mixed));
2923
2924 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
2926 assert!(all_passing_fn(&user_high));
2927 assert!(!all_passing_fn(&user_mixed));
2928 }
2929
2930 #[test]
2931 fn test_kp_count_items() {
2932 #[derive(Debug)]
2933 struct User {
2934 tags: Vec<String>,
2935 }
2936
2937 let user = User {
2938 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
2939 };
2940
2941 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2942 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
2943
2944 assert_eq!(count_fn(&user), Some(3));
2945 }
2946
2947 #[test]
2948 fn test_kp_find_in() {
2949 #[derive(Debug)]
2950 struct User {
2951 scores: Vec<i32>,
2952 }
2953
2954 let user = User {
2955 scores: vec![85, 92, 78, 95, 88],
2956 };
2957
2958 let scores_kp = KpType::new(
2959 |u: &User| Some(&u.scores),
2960 |u: &mut User| Some(&mut u.scores),
2961 );
2962
2963 let first_high_fn =
2965 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
2966
2967 assert_eq!(first_high_fn(&user), Some(92));
2968
2969 let perfect_fn =
2971 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
2972
2973 assert_eq!(perfect_fn(&user), None);
2974 }
2975
2976 #[test]
2977 fn test_kp_take_skip() {
2978 #[derive(Debug)]
2979 struct User {
2980 tags: Vec<String>,
2981 }
2982
2983 let user = User {
2984 tags: vec![
2985 "a".to_string(),
2986 "b".to_string(),
2987 "c".to_string(),
2988 "d".to_string(),
2989 ],
2990 };
2991
2992 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2993
2994 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
2996 tags.iter().take(n).cloned().collect::<Vec<_>>()
2997 });
2998
2999 let taken = take_fn(&user).unwrap();
3000 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3001
3002 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3004 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3005 });
3006
3007 let skipped = skip_fn(&user).unwrap();
3008 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3009 }
3010
3011 #[test]
3012 fn test_kp_partition() {
3013 #[derive(Debug)]
3014 struct User {
3015 scores: Vec<i32>,
3016 }
3017
3018 let user = User {
3019 scores: vec![85, 92, 65, 95, 72, 58],
3020 };
3021
3022 let scores_kp = KpType::new(
3023 |u: &User| Some(&u.scores),
3024 |u: &mut User| Some(&mut u.scores),
3025 );
3026
3027 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3028 scores.iter().copied().partition(|&s| s >= 70)
3029 });
3030
3031 let (passing, failing) = partition_fn(&user).unwrap();
3032 assert_eq!(passing, vec![85, 92, 95, 72]);
3033 assert_eq!(failing, vec![65, 58]);
3034 }
3035
3036 #[test]
3037 fn test_kp_min_max() {
3038 #[derive(Debug)]
3039 struct User {
3040 scores: Vec<i32>,
3041 }
3042
3043 let user = User {
3044 scores: vec![85, 92, 78, 95, 88],
3045 };
3046
3047 let scores_kp = KpType::new(
3048 |u: &User| Some(&u.scores),
3049 |u: &mut User| Some(&mut u.scores),
3050 );
3051
3052 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3054 assert_eq!(min_fn(&user), Some(78));
3055
3056 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3058 assert_eq!(max_fn(&user), Some(95));
3059 }
3060
3061 #[test]
3062 fn test_kp_sum() {
3063 #[derive(Debug)]
3064 struct User {
3065 scores: Vec<i32>,
3066 }
3067
3068 let user = User {
3069 scores: vec![85, 92, 78],
3070 };
3071
3072 let scores_kp = KpType::new(
3073 |u: &User| Some(&u.scores),
3074 |u: &mut User| Some(&mut u.scores),
3075 );
3076
3077 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3078 assert_eq!(sum_fn(&user), Some(255));
3079
3080 let avg_fn =
3082 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3083 assert_eq!(avg_fn.get(&user), Some(85));
3084 }
3085
3086 #[test]
3087 fn test_kp_chain() {
3088 #[derive(Debug)]
3089 struct User {
3090 profile: Profile,
3091 }
3092
3093 #[derive(Debug)]
3094 struct Profile {
3095 settings: Settings,
3096 }
3097
3098 #[derive(Debug)]
3099 struct Settings {
3100 theme: String,
3101 }
3102
3103 let user = User {
3104 profile: Profile {
3105 settings: Settings {
3106 theme: "dark".to_string(),
3107 },
3108 },
3109 };
3110
3111 let profile_kp = KpType::new(
3112 |u: &User| Some(&u.profile),
3113 |u: &mut User| Some(&mut u.profile),
3114 );
3115 let settings_kp = KpType::new(
3116 |p: &Profile| Some(&p.settings),
3117 |p: &mut Profile| Some(&mut p.settings),
3118 );
3119 let theme_kp = KpType::new(
3120 |s: &Settings| Some(&s.theme),
3121 |s: &mut Settings| Some(&mut s.theme),
3122 );
3123
3124 let profile_settings = profile_kp.then(settings_kp);
3126 let theme_path = profile_settings.then(theme_kp);
3127 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3128 }
3129
3130 #[test]
3131 fn test_kp_zip() {
3132 #[derive(Debug)]
3133 struct User {
3134 name: String,
3135 age: i32,
3136 }
3137
3138 let user = User {
3139 name: "Akash".to_string(),
3140 age: 30,
3141 };
3142
3143 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3144 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3145
3146 let zipped_fn = zip_kps(&name_kp, &age_kp);
3147 let result = zipped_fn(&user);
3148
3149 assert_eq!(result, Some((&"Akash".to_string(), &30)));
3150 }
3151
3152 #[test]
3153 fn test_kp_complex_pipeline() {
3154 #[derive(Debug)]
3155 struct User {
3156 transactions: Vec<Transaction>,
3157 }
3158
3159 #[derive(Debug)]
3160 struct Transaction {
3161 amount: f64,
3162 category: String,
3163 }
3164
3165 let user = User {
3166 transactions: vec![
3167 Transaction {
3168 amount: 50.0,
3169 category: "food".to_string(),
3170 },
3171 Transaction {
3172 amount: 100.0,
3173 category: "transport".to_string(),
3174 },
3175 Transaction {
3176 amount: 25.0,
3177 category: "food".to_string(),
3178 },
3179 Transaction {
3180 amount: 200.0,
3181 category: "shopping".to_string(),
3182 },
3183 ],
3184 };
3185
3186 let txns_kp = KpType::new(
3187 |u: &User| Some(&u.transactions),
3188 |u: &mut User| Some(&mut u.transactions),
3189 );
3190
3191 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3193 txns.iter()
3194 .filter(|t| t.category == "food")
3195 .map(|t| t.amount)
3196 .sum::<f64>()
3197 });
3198
3199 assert_eq!(food_total.get(&user), Some(75.0));
3200
3201 let has_large =
3203 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3204
3205 assert!(has_large(&user));
3206
3207 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3209 assert_eq!(count(&user), Some(4));
3210 }
3211
3212 #[test]
3216 fn test_no_clone_required_for_root() {
3217 use std::sync::Arc;
3218 use std::sync::atomic::{AtomicUsize, Ordering};
3219
3220 struct NonCloneableRoot {
3223 data: Arc<AtomicUsize>,
3224 cached_value: usize,
3225 }
3226
3227 impl NonCloneableRoot {
3228 fn new() -> Self {
3229 Self {
3230 data: Arc::new(AtomicUsize::new(42)),
3231 cached_value: 42,
3232 }
3233 }
3234
3235 fn increment(&mut self) {
3236 self.data.fetch_add(1, Ordering::SeqCst);
3237 self.cached_value = self.data.load(Ordering::SeqCst);
3238 }
3239
3240 fn get_value(&self) -> &usize {
3241 &self.cached_value
3242 }
3243
3244 fn get_value_mut(&mut self) -> &mut usize {
3245 &mut self.cached_value
3246 }
3247 }
3248
3249 let mut root = NonCloneableRoot::new();
3250
3251 let data_kp = KpType::new(
3253 |r: &NonCloneableRoot| Some(r.get_value()),
3254 |r: &mut NonCloneableRoot| {
3255 r.increment();
3256 Some(r.get_value_mut())
3257 },
3258 );
3259
3260 assert_eq!(data_kp.get(&root), Some(&42));
3262
3263 {
3264 let doubled = data_kp.map(|val: &usize| val * 2);
3266 assert_eq!(doubled.get(&root), Some(84));
3267
3268 let filtered = data_kp.filter(|val: &usize| *val > 0);
3270 assert_eq!(filtered.get(&root), Some(&42));
3271 } let value_ref = data_kp.get_mut(&mut root);
3275 assert!(value_ref.is_some());
3276 }
3277
3278 #[test]
3279 fn test_no_clone_required_for_value() {
3280 use std::sync::Arc;
3281 use std::sync::atomic::{AtomicUsize, Ordering};
3282
3283 struct NonCloneableValue {
3285 counter: Arc<AtomicUsize>,
3286 }
3287
3288 impl NonCloneableValue {
3289 fn new(val: usize) -> Self {
3290 Self {
3291 counter: Arc::new(AtomicUsize::new(val)),
3292 }
3293 }
3294
3295 fn get(&self) -> usize {
3296 self.counter.load(Ordering::SeqCst)
3297 }
3298 }
3299
3300 struct Root {
3301 value: NonCloneableValue,
3302 }
3303
3304 let root = Root {
3305 value: NonCloneableValue::new(100),
3306 };
3307
3308 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3310
3311 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3313 assert_eq!(counter_kp.get(&root), Some(100));
3314
3315 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3317 assert!(filtered.get(&root).is_some());
3318 }
3319
3320 #[test]
3321 fn test_static_does_not_leak_memory() {
3322 use std::sync::Arc;
3323 use std::sync::atomic::{AtomicUsize, Ordering};
3324
3325 static CREATED: AtomicUsize = AtomicUsize::new(0);
3327 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3328
3329 struct Tracked {
3330 id: usize,
3331 }
3332
3333 impl Tracked {
3334 fn new() -> Self {
3335 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3336 Self { id }
3337 }
3338 }
3339
3340 impl Drop for Tracked {
3341 fn drop(&mut self) {
3342 DROPPED.fetch_add(1, Ordering::SeqCst);
3343 }
3344 }
3345
3346 struct Root {
3347 data: Tracked,
3348 }
3349
3350 CREATED.store(0, Ordering::SeqCst);
3352 DROPPED.store(0, Ordering::SeqCst);
3353
3354 {
3355 let root = Root {
3356 data: Tracked::new(),
3357 };
3358
3359 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3360
3361 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3363 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3364 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3365
3366 assert_eq!(mapped1.get(&root), Some(0));
3367 assert_eq!(mapped2.get(&root), Some(1));
3368 assert_eq!(mapped3.get(&root), Some(2));
3369
3370 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3372 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3373 }
3374
3375 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3377 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3378
3379 }
3381
3382 #[test]
3383 fn test_references_not_cloned() {
3384 use std::sync::Arc;
3385
3386 struct ExpensiveData {
3388 large_vec: Vec<u8>,
3389 }
3390
3391 impl ExpensiveData {
3392 fn new(size: usize) -> Self {
3393 Self {
3394 large_vec: vec![0u8; size],
3395 }
3396 }
3397
3398 fn size(&self) -> usize {
3399 self.large_vec.len()
3400 }
3401 }
3402
3403 struct Root {
3404 expensive: ExpensiveData,
3405 }
3406
3407 let root = Root {
3408 expensive: ExpensiveData::new(1_000_000), };
3410
3411 let expensive_kp = KpType::new(
3412 |r: &Root| Some(&r.expensive),
3413 |r: &mut Root| Some(&mut r.expensive),
3414 );
3415
3416 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3418 assert_eq!(size_kp.get(&root), Some(1_000_000));
3419
3420 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3422 assert!(large_filter.get(&root).is_some());
3423
3424 }
3426
3427 #[test]
3428 fn test_hof_with_arc_no_extra_clones() {
3429 use std::sync::Arc;
3430
3431 #[derive(Debug)]
3432 struct SharedData {
3433 value: String,
3434 }
3435
3436 struct Root {
3437 shared: Arc<SharedData>,
3438 }
3439
3440 let shared = Arc::new(SharedData {
3441 value: "shared".to_string(),
3442 });
3443
3444 assert_eq!(Arc::strong_count(&shared), 1);
3446
3447 {
3448 let root = Root {
3449 shared: Arc::clone(&shared),
3450 };
3451
3452 assert_eq!(Arc::strong_count(&shared), 2);
3454
3455 let shared_kp = KpType::new(
3456 |r: &Root| Some(&r.shared),
3457 |r: &mut Root| Some(&mut r.shared),
3458 );
3459
3460 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3462
3463 assert_eq!(value_kp.get(&root), Some(6));
3465 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3469 assert!(filtered.get(&root).is_some());
3470 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3475
3476 #[test]
3477 fn test_closure_captures_not_root_values() {
3478 use std::sync::Arc;
3479 use std::sync::atomic::{AtomicUsize, Ordering};
3480
3481 let call_count = Arc::new(AtomicUsize::new(0));
3483 let call_count_clone = Arc::clone(&call_count);
3484
3485 struct Root {
3486 value: i32,
3487 }
3488
3489 let root = Root { value: 42 };
3490
3491 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3492
3493 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3496 call_count_clone.fetch_add(1, Ordering::SeqCst);
3497 v * 2
3498 });
3499
3500 assert_eq!(doubled(&root), 84);
3502 assert_eq!(doubled(&root), 84);
3503 assert_eq!(doubled(&root), 84);
3504
3505 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3507
3508 }
3510
3511 #[test]
3512 fn test_static_with_borrowed_data() {
3513 struct Root {
3517 data: String,
3518 }
3519
3520 {
3521 let root = Root {
3522 data: "temporary".to_string(),
3523 };
3524
3525 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3526
3527 let len_kp = data_kp.map(|s: &String| s.len());
3529 assert_eq!(len_kp.get(&root), Some(9));
3530
3531 } }
3536
3537 #[test]
3538 fn test_multiple_hof_operations_no_accumulation() {
3539 use std::sync::Arc;
3540 use std::sync::atomic::{AtomicUsize, Ordering};
3541
3542 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3543
3544 struct Tracked {
3545 id: usize,
3546 }
3547
3548 impl Drop for Tracked {
3549 fn drop(&mut self) {
3550 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3551 }
3552 }
3553
3554 struct Root {
3555 values: Vec<Tracked>,
3556 }
3557
3558 DROP_COUNT.store(0, Ordering::SeqCst);
3559
3560 {
3561 let root = Root {
3562 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3563 };
3564
3565 let values_kp = KpType::new(
3566 |r: &Root| Some(&r.values),
3567 |r: &mut Root| Some(&mut r.values),
3568 );
3569
3570 let count = values_kp.count_items(|v| v.len());
3572 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3573 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3574 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3575
3576 assert_eq!(count(&root), Some(3));
3577 assert_eq!(sum(&root), Some(6));
3578 assert!(has_2(&root));
3579 assert!(all_positive(&root));
3580
3581 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3583 }
3584
3585 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3587 }
3588
3589 #[test]
3590 fn test_copy_bound_only_for_function_not_data() {
3591 #[derive(Debug)]
3595 struct NonCopyData {
3596 value: String,
3597 }
3598
3599 struct Root {
3600 data: NonCopyData,
3601 }
3602
3603 let root = Root {
3604 data: NonCopyData {
3605 value: "test".to_string(),
3606 },
3607 };
3608
3609 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3610
3611 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3614 assert_eq!(len_kp.get(&root), Some(4));
3615
3616 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3618 assert!(filtered.get(&root).is_some());
3619 }
3620
3621 #[test]
3622 fn test_no_memory_leak_with_cyclic_references() {
3623 use std::sync::atomic::{AtomicUsize, Ordering};
3624 use std::sync::{Arc, Weak};
3625
3626 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3627
3628 struct Node {
3629 id: usize,
3630 parent: Option<Weak<Node>>,
3631 }
3632
3633 impl Drop for Node {
3634 fn drop(&mut self) {
3635 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3636 }
3637 }
3638
3639 struct Root {
3640 node: Arc<Node>,
3641 }
3642
3643 DROP_COUNT.store(0, Ordering::SeqCst);
3644
3645 {
3646 let root = Root {
3647 node: Arc::new(Node {
3648 id: 1,
3649 parent: None,
3650 }),
3651 };
3652
3653 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3654
3655 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3657 assert_eq!(id_kp.get(&root), Some(1));
3658
3659 assert_eq!(Arc::strong_count(&root.node), 1);
3661
3662 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3664 }
3665
3666 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3668 }
3669
3670 #[test]
3671 fn test_hof_operations_are_zero_cost_abstractions() {
3672 struct Root {
3676 value: i32,
3677 }
3678
3679 let root = Root { value: 10 };
3680
3681 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3682
3683 let direct_result = value_kp.get(&root).map(|v| v * 2);
3685 assert_eq!(direct_result, Some(20));
3686
3687 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3689 let hof_result = mapped_kp.get(&root);
3690 assert_eq!(hof_result, Some(20));
3691
3692 assert_eq!(direct_result, hof_result);
3694 }
3695
3696 #[test]
3697 fn test_complex_closure_captures_allowed() {
3698 use std::sync::Arc;
3699
3700 struct Root {
3702 scores: Vec<i32>,
3703 }
3704
3705 let root = Root {
3706 scores: vec![85, 92, 78, 95, 88],
3707 };
3708
3709 let scores_kp = KpType::new(
3710 |r: &Root| Some(&r.scores),
3711 |r: &mut Root| Some(&mut r.scores),
3712 );
3713
3714 let threshold = 90;
3716 let multiplier = Arc::new(2);
3717
3718 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3720 let high: i32 = scores
3721 .iter()
3722 .filter(|&&s| s >= threshold)
3723 .map(|&s| s * *multiplier)
3724 .sum();
3725 acc + high
3726 });
3727
3728 assert_eq!(high_scores_doubled(&root), 374);
3730 }
3731
3732 #[test]
3736 fn test_pkp_filter_by_value_type() {
3737 use std::any::TypeId;
3738
3739 #[derive(Debug)]
3740 struct User {
3741 name: String,
3742 age: i32,
3743 score: f64,
3744 active: bool,
3745 }
3746
3747 let user = User {
3748 name: "Akash".to_string(),
3749 age: 30,
3750 score: 95.5,
3751 active: true,
3752 };
3753
3754 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3756 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3757 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3758 let active_kp = KpType::new(
3759 |u: &User| Some(&u.active),
3760 |u: &mut User| Some(&mut u.active),
3761 );
3762
3763 let all_keypaths: Vec<PKp<User>> = vec![
3765 PKp::new(name_kp),
3766 PKp::new(age_kp),
3767 PKp::new(score_kp),
3768 PKp::new(active_kp),
3769 ];
3770
3771 let string_kps: Vec<_> = all_keypaths
3773 .iter()
3774 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3775 .collect();
3776
3777 assert_eq!(string_kps.len(), 1);
3778 assert_eq!(
3779 string_kps[0].get_as::<String>(&user),
3780 Some(&"Akash".to_string())
3781 );
3782
3783 let i32_kps: Vec<_> = all_keypaths
3785 .iter()
3786 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3787 .collect();
3788
3789 assert_eq!(i32_kps.len(), 1);
3790 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3791
3792 let f64_kps: Vec<_> = all_keypaths
3794 .iter()
3795 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3796 .collect();
3797
3798 assert_eq!(f64_kps.len(), 1);
3799 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3800
3801 let bool_kps: Vec<_> = all_keypaths
3803 .iter()
3804 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3805 .collect();
3806
3807 assert_eq!(bool_kps.len(), 1);
3808 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3809 }
3810
3811 #[test]
3812 fn test_pkp_filter_by_struct_type() {
3813 use std::any::TypeId;
3814
3815 #[derive(Debug, PartialEq)]
3816 struct Address {
3817 street: String,
3818 city: String,
3819 }
3820
3821 #[derive(Debug)]
3822 struct User {
3823 name: String,
3824 age: i32,
3825 address: Address,
3826 }
3827
3828 let user = User {
3829 name: "Bob".to_string(),
3830 age: 25,
3831 address: Address {
3832 street: "123 Main St".to_string(),
3833 city: "NYC".to_string(),
3834 },
3835 };
3836
3837 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3839 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3840 let address_kp = KpType::new(
3841 |u: &User| Some(&u.address),
3842 |u: &mut User| Some(&mut u.address),
3843 );
3844
3845 let all_keypaths: Vec<PKp<User>> =
3846 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
3847
3848 let struct_kps: Vec<_> = all_keypaths
3850 .iter()
3851 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
3852 .collect();
3853
3854 assert_eq!(struct_kps.len(), 1);
3855 assert_eq!(
3856 struct_kps[0].get_as::<Address>(&user),
3857 Some(&Address {
3858 street: "123 Main St".to_string(),
3859 city: "NYC".to_string(),
3860 })
3861 );
3862
3863 let primitive_kps: Vec<_> = all_keypaths
3865 .iter()
3866 .filter(|pkp| {
3867 pkp.value_type_id() == TypeId::of::<String>()
3868 || pkp.value_type_id() == TypeId::of::<i32>()
3869 })
3870 .collect();
3871
3872 assert_eq!(primitive_kps.len(), 2);
3873 }
3874
3875 #[test]
3876 fn test_pkp_filter_by_arc_type() {
3877 use std::any::TypeId;
3878 use std::sync::Arc;
3879
3880 #[derive(Debug)]
3881 struct User {
3882 name: String,
3883 shared_data: Arc<String>,
3884 shared_number: Arc<i32>,
3885 }
3886
3887 let user = User {
3888 name: "Charlie".to_string(),
3889 shared_data: Arc::new("shared".to_string()),
3890 shared_number: Arc::new(42),
3891 };
3892
3893 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3895 let shared_data_kp = KpType::new(
3896 |u: &User| Some(&u.shared_data),
3897 |u: &mut User| Some(&mut u.shared_data),
3898 );
3899 let shared_number_kp = KpType::new(
3900 |u: &User| Some(&u.shared_number),
3901 |u: &mut User| Some(&mut u.shared_number),
3902 );
3903
3904 let all_keypaths: Vec<PKp<User>> = vec![
3905 PKp::new(name_kp),
3906 PKp::new(shared_data_kp),
3907 PKp::new(shared_number_kp),
3908 ];
3909
3910 let arc_string_kps: Vec<_> = all_keypaths
3912 .iter()
3913 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
3914 .collect();
3915
3916 assert_eq!(arc_string_kps.len(), 1);
3917 assert_eq!(
3918 arc_string_kps[0]
3919 .get_as::<Arc<String>>(&user)
3920 .map(|arc| arc.as_str()),
3921 Some("shared")
3922 );
3923
3924 let arc_i32_kps: Vec<_> = all_keypaths
3926 .iter()
3927 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
3928 .collect();
3929
3930 assert_eq!(arc_i32_kps.len(), 1);
3931 assert_eq!(
3932 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
3933 Some(42)
3934 );
3935
3936 let all_arc_kps: Vec<_> = all_keypaths
3938 .iter()
3939 .filter(|pkp| {
3940 pkp.value_type_id() == TypeId::of::<Arc<String>>()
3941 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
3942 })
3943 .collect();
3944
3945 assert_eq!(all_arc_kps.len(), 2);
3946 }
3947
3948 #[test]
3949 fn test_pkp_filter_by_box_type() {
3950 use std::any::TypeId;
3951
3952 #[derive(Debug)]
3953 struct User {
3954 name: String,
3955 boxed_value: Box<i32>,
3956 boxed_string: Box<String>,
3957 }
3958
3959 let user = User {
3960 name: "Diana".to_string(),
3961 boxed_value: Box::new(100),
3962 boxed_string: Box::new("boxed".to_string()),
3963 };
3964
3965 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3967 let boxed_value_kp = KpType::new(
3968 |u: &User| Some(&u.boxed_value),
3969 |u: &mut User| Some(&mut u.boxed_value),
3970 );
3971 let boxed_string_kp = KpType::new(
3972 |u: &User| Some(&u.boxed_string),
3973 |u: &mut User| Some(&mut u.boxed_string),
3974 );
3975
3976 let all_keypaths: Vec<PKp<User>> = vec![
3977 PKp::new(name_kp),
3978 PKp::new(boxed_value_kp),
3979 PKp::new(boxed_string_kp),
3980 ];
3981
3982 let box_i32_kps: Vec<_> = all_keypaths
3984 .iter()
3985 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
3986 .collect();
3987
3988 assert_eq!(box_i32_kps.len(), 1);
3989 assert_eq!(
3990 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
3991 Some(100)
3992 );
3993
3994 let box_string_kps: Vec<_> = all_keypaths
3996 .iter()
3997 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
3998 .collect();
3999
4000 assert_eq!(box_string_kps.len(), 1);
4001 assert_eq!(
4002 box_string_kps[0]
4003 .get_as::<Box<String>>(&user)
4004 .map(|b| b.as_str()),
4005 Some("boxed")
4006 );
4007 }
4008
4009 #[test]
4010 fn test_akp_filter_by_root_and_value_type() {
4011 use std::any::TypeId;
4012
4013 #[derive(Debug)]
4014 struct User {
4015 name: String,
4016 age: i32,
4017 }
4018
4019 #[derive(Debug)]
4020 struct Product {
4021 title: String,
4022 price: f64,
4023 }
4024
4025 let user = User {
4026 name: "Eve".to_string(),
4027 age: 28,
4028 };
4029
4030 let product = Product {
4031 title: "Book".to_string(),
4032 price: 19.99,
4033 };
4034
4035 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4037 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4038 let product_title_kp = KpType::new(
4039 |p: &Product| Some(&p.title),
4040 |p: &mut Product| Some(&mut p.title),
4041 );
4042 let product_price_kp = KpType::new(
4043 |p: &Product| Some(&p.price),
4044 |p: &mut Product| Some(&mut p.price),
4045 );
4046
4047 let all_keypaths: Vec<AKp> = vec![
4048 AKp::new(user_name_kp),
4049 AKp::new(user_age_kp),
4050 AKp::new(product_title_kp),
4051 AKp::new(product_price_kp),
4052 ];
4053
4054 let user_kps: Vec<_> = all_keypaths
4056 .iter()
4057 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4058 .collect();
4059
4060 assert_eq!(user_kps.len(), 2);
4061
4062 let product_kps: Vec<_> = all_keypaths
4064 .iter()
4065 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4066 .collect();
4067
4068 assert_eq!(product_kps.len(), 2);
4069
4070 let string_value_kps: Vec<_> = all_keypaths
4072 .iter()
4073 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4074 .collect();
4075
4076 assert_eq!(string_value_kps.len(), 2);
4077
4078 let user_string_kps: Vec<_> = all_keypaths
4080 .iter()
4081 .filter(|akp| {
4082 akp.root_type_id() == TypeId::of::<User>()
4083 && akp.value_type_id() == TypeId::of::<String>()
4084 })
4085 .collect();
4086
4087 assert_eq!(user_string_kps.len(), 1);
4088 assert_eq!(
4089 user_string_kps[0].get_as::<User, String>(&user),
4090 Some(Some(&"Eve".to_string()))
4091 );
4092
4093 let product_f64_kps: Vec<_> = all_keypaths
4095 .iter()
4096 .filter(|akp| {
4097 akp.root_type_id() == TypeId::of::<Product>()
4098 && akp.value_type_id() == TypeId::of::<f64>()
4099 })
4100 .collect();
4101
4102 assert_eq!(product_f64_kps.len(), 1);
4103 assert_eq!(
4104 product_f64_kps[0].get_as::<Product, f64>(&product),
4105 Some(Some(&19.99))
4106 );
4107 }
4108
4109 #[test]
4110 fn test_akp_filter_by_arc_root_type() {
4111 use std::any::TypeId;
4112 use std::sync::Arc;
4113
4114 #[derive(Debug)]
4115 struct User {
4116 name: String,
4117 }
4118
4119 #[derive(Debug)]
4120 struct Product {
4121 title: String,
4122 }
4123
4124 let user = User {
4125 name: "Frank".to_string(),
4126 };
4127 let product = Product {
4128 title: "Laptop".to_string(),
4129 };
4130
4131 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4133 let product_title_kp = KpType::new(
4134 |p: &Product| Some(&p.title),
4135 |p: &mut Product| Some(&mut p.title),
4136 );
4137
4138 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4140 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4141
4142 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4143
4144 let arc_user_kps: Vec<_> = all_keypaths
4146 .iter()
4147 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4148 .collect();
4149
4150 assert_eq!(arc_user_kps.len(), 1);
4151
4152 let arc_user = Arc::new(user);
4154 assert_eq!(
4155 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4156 Some(Some(&"Frank".to_string()))
4157 );
4158
4159 let arc_product_kps: Vec<_> = all_keypaths
4161 .iter()
4162 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4163 .collect();
4164
4165 assert_eq!(arc_product_kps.len(), 1);
4166
4167 let arc_product = Arc::new(product);
4169 assert_eq!(
4170 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4171 Some(Some(&"Laptop".to_string()))
4172 );
4173 }
4174
4175 #[test]
4176 fn test_akp_filter_by_box_root_type() {
4177 use std::any::TypeId;
4178
4179 #[derive(Debug)]
4180 struct Config {
4181 setting: String,
4182 }
4183
4184 let config = Config {
4185 setting: "enabled".to_string(),
4186 };
4187
4188 let config_kp1 = KpType::new(
4190 |c: &Config| Some(&c.setting),
4191 |c: &mut Config| Some(&mut c.setting),
4192 );
4193 let config_kp2 = KpType::new(
4194 |c: &Config| Some(&c.setting),
4195 |c: &mut Config| Some(&mut c.setting),
4196 );
4197
4198 let regular_akp = AKp::new(config_kp1);
4200 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4201
4202 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4203
4204 let config_kps: Vec<_> = all_keypaths
4206 .iter()
4207 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4208 .collect();
4209
4210 assert_eq!(config_kps.len(), 1);
4211 assert_eq!(
4212 config_kps[0].get_as::<Config, String>(&config),
4213 Some(Some(&"enabled".to_string()))
4214 );
4215
4216 let box_config_kps: Vec<_> = all_keypaths
4218 .iter()
4219 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4220 .collect();
4221
4222 assert_eq!(box_config_kps.len(), 1);
4223
4224 let box_config = Box::new(Config {
4226 setting: "enabled".to_string(),
4227 });
4228 assert_eq!(
4229 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4230 Some(Some(&"enabled".to_string()))
4231 );
4232 }
4233
4234 #[test]
4235 fn test_mixed_collection_type_filtering() {
4236 use std::any::TypeId;
4237 use std::sync::Arc;
4238
4239 #[derive(Debug)]
4240 struct User {
4241 name: String,
4242 email: String,
4243 }
4244
4245 #[derive(Debug)]
4246 struct Product {
4247 title: String,
4248 sku: String,
4249 }
4250
4251 let user = User {
4252 name: "Grace".to_string(),
4253 email: "grace@example.com".to_string(),
4254 };
4255
4256 let product = Product {
4257 title: "Widget".to_string(),
4258 sku: "WID-001".to_string(),
4259 };
4260
4261 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4263 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4264 let user_email_kp1 =
4265 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4266 let user_email_kp2 =
4267 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4268 let product_title_kp = KpType::new(
4269 |p: &Product| Some(&p.title),
4270 |p: &mut Product| Some(&mut p.title),
4271 );
4272 let product_sku_kp = KpType::new(
4273 |p: &Product| Some(&p.sku),
4274 |p: &mut Product| Some(&mut p.sku),
4275 );
4276
4277 let all_keypaths: Vec<AKp> = vec![
4278 AKp::new(user_name_kp1),
4279 AKp::new(user_email_kp1),
4280 AKp::new(product_title_kp),
4281 AKp::new(product_sku_kp),
4282 AKp::new(user_name_kp2).for_arc::<User>(),
4283 AKp::new(user_email_kp2).for_box::<User>(),
4284 ];
4285
4286 let string_value_kps: Vec<_> = all_keypaths
4288 .iter()
4289 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4290 .collect();
4291
4292 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4296 .iter()
4297 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4298 .collect();
4299
4300 assert_eq!(user_root_kps.len(), 2);
4301
4302 let arc_user_kps: Vec<_> = all_keypaths
4304 .iter()
4305 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4306 .collect();
4307
4308 assert_eq!(arc_user_kps.len(), 1);
4309
4310 let box_user_kps: Vec<_> = all_keypaths
4312 .iter()
4313 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4314 .collect();
4315
4316 assert_eq!(box_user_kps.len(), 1);
4317
4318 let product_kps: Vec<_> = all_keypaths
4320 .iter()
4321 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4322 .collect();
4323
4324 assert_eq!(product_kps.len(), 2);
4325
4326 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4328 assert!(user_value.is_some());
4329 assert!(user_value.unwrap().is_some());
4330 }
4331
4332 #[test]
4337 fn test_kp_with_pin() {
4338 use std::pin::Pin;
4339
4340 #[derive(Debug)]
4344 struct SelfReferential {
4345 value: String,
4346 ptr_to_value: *const String, }
4348
4349 impl SelfReferential {
4350 fn new(s: String) -> Self {
4351 let mut sr = Self {
4352 value: s,
4353 ptr_to_value: std::ptr::null(),
4354 };
4355 sr.ptr_to_value = &sr.value as *const String;
4357 sr
4358 }
4359
4360 fn get_value(&self) -> &str {
4361 &self.value
4362 }
4363 }
4364
4365 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4367 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4368
4369 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4371 |p: &Pin<Box<SelfReferential>>| {
4372 Some(&p.as_ref().get_ref().value)
4374 },
4375 |p: &mut Pin<Box<SelfReferential>>| {
4376 unsafe {
4379 let sr = Pin::get_unchecked_mut(p.as_mut());
4380 Some(&mut sr.value)
4381 }
4382 },
4383 );
4384
4385 let result = kp.get(&pinned);
4387 assert_eq!(result, Some(&"pinned_data".to_string()));
4388
4389 assert_eq!(pinned.get_value(), "pinned_data");
4391 }
4392
4393 #[test]
4394 fn test_kp_with_pin_arc() {
4395 use std::pin::Pin;
4396 use std::sync::Arc;
4397
4398 struct AsyncState {
4399 status: String,
4400 data: Vec<i32>,
4401 }
4402
4403 let state = AsyncState {
4405 status: "ready".to_string(),
4406 data: vec![1, 2, 3, 4, 5],
4407 };
4408
4409 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4410
4411 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4413 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4414 |_: &mut Pin<Arc<AsyncState>>| {
4415 None::<&mut String>
4417 },
4418 );
4419
4420 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4422 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4423 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4424 );
4425
4426 let status = status_kp.get(&pinned_arc);
4427 assert_eq!(status, Some(&"ready".to_string()));
4428
4429 let data = data_kp.get(&pinned_arc);
4430 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4431 }
4432
4433 #[test]
4434 fn test_kp_with_maybe_uninit() {
4435 use std::mem::MaybeUninit;
4436
4437 struct Config {
4441 name: MaybeUninit<String>,
4442 value: MaybeUninit<i32>,
4443 initialized: bool,
4444 }
4445
4446 impl Config {
4447 fn new_uninit() -> Self {
4448 Self {
4449 name: MaybeUninit::uninit(),
4450 value: MaybeUninit::uninit(),
4451 initialized: false,
4452 }
4453 }
4454
4455 fn init(&mut self, name: String, value: i32) {
4456 self.name.write(name);
4457 self.value.write(value);
4458 self.initialized = true;
4459 }
4460
4461 fn get_name(&self) -> Option<&String> {
4462 if self.initialized {
4463 unsafe { Some(self.name.assume_init_ref()) }
4464 } else {
4465 None
4466 }
4467 }
4468
4469 fn get_value(&self) -> Option<&i32> {
4470 if self.initialized {
4471 unsafe { Some(self.value.assume_init_ref()) }
4472 } else {
4473 None
4474 }
4475 }
4476 }
4477
4478 let name_kp: KpType<Config, String> = Kp::new(
4480 |c: &Config| c.get_name(),
4481 |c: &mut Config| {
4482 if c.initialized {
4483 unsafe { Some(c.name.assume_init_mut()) }
4484 } else {
4485 None
4486 }
4487 },
4488 );
4489
4490 let value_kp: KpType<Config, i32> = Kp::new(
4491 |c: &Config| c.get_value(),
4492 |c: &mut Config| {
4493 if c.initialized {
4494 unsafe { Some(c.value.assume_init_mut()) }
4495 } else {
4496 None
4497 }
4498 },
4499 );
4500
4501 let uninit_config = Config::new_uninit();
4503 assert_eq!(name_kp.get(&uninit_config), None);
4504 assert_eq!(value_kp.get(&uninit_config), None);
4505
4506 let mut init_config = Config::new_uninit();
4508 init_config.init("test_config".to_string(), 42);
4509
4510 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4511 assert_eq!(value_kp.get(&init_config), Some(&42));
4512
4513 if let Some(val) = value_kp.get_mut(&mut init_config) {
4515 *val = 100;
4516 }
4517
4518 assert_eq!(value_kp.get(&init_config), Some(&100));
4519 }
4520
4521 #[test]
4522 fn test_kp_with_weak() {
4523 use std::sync::{Arc, Weak};
4524
4525 #[derive(Debug, Clone)]
4529 struct Node {
4530 value: i32,
4531 }
4532
4533 struct NodeWithParent {
4534 value: i32,
4535 parent: Option<Arc<Node>>, }
4537
4538 let parent = Arc::new(Node { value: 100 });
4539
4540 let child = NodeWithParent {
4541 value: 42,
4542 parent: Some(parent.clone()),
4543 };
4544
4545 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4547 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4548 |_: &mut NodeWithParent| None::<&mut i32>,
4549 );
4550
4551 let parent_val = parent_value_kp.get(&child);
4553 assert_eq!(parent_val, Some(&100));
4554 }
4555
4556 #[test]
4557 fn test_kp_with_rc_weak() {
4558 use std::rc::Rc;
4559
4560 struct TreeNode {
4563 value: String,
4564 parent: Option<Rc<TreeNode>>, }
4566
4567 let root = Rc::new(TreeNode {
4568 value: "root".to_string(),
4569 parent: None,
4570 });
4571
4572 let child1 = TreeNode {
4573 value: "child1".to_string(),
4574 parent: Some(root.clone()),
4575 };
4576
4577 let child2 = TreeNode {
4578 value: "child2".to_string(),
4579 parent: Some(root.clone()),
4580 };
4581
4582 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4584 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4585 |_: &mut TreeNode| None::<&mut String>,
4586 );
4587
4588 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4590 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4591
4592 assert_eq!(parent_name_kp.get(&root), None);
4594 }
4595
4596 #[test]
4597 fn test_kp_with_complex_weak_structure() {
4598 use std::sync::Arc;
4599
4600 struct Cache {
4603 data: String,
4604 backup: Option<Arc<Cache>>, }
4606
4607 let primary = Arc::new(Cache {
4608 data: "primary_data".to_string(),
4609 backup: None,
4610 });
4611
4612 let backup = Arc::new(Cache {
4613 data: "backup_data".to_string(),
4614 backup: Some(primary.clone()),
4615 });
4616
4617 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4619 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4620 |_: &mut Arc<Cache>| None::<&mut String>,
4621 );
4622
4623 let data = backup_data_kp.get(&backup);
4625 assert_eq!(data, Some(&"primary_data".to_string()));
4626
4627 let no_backup = backup_data_kp.get(&primary);
4629 assert_eq!(no_backup, None);
4630 }
4631
4632 #[test]
4633 fn test_kp_chain_with_pin_and_arc() {
4634 use std::pin::Pin;
4635 use std::sync::Arc;
4636
4637 struct Outer {
4640 inner: Arc<Inner>,
4641 }
4642
4643 struct Inner {
4644 value: String,
4645 }
4646
4647 let outer = Outer {
4648 inner: Arc::new(Inner {
4649 value: "nested_value".to_string(),
4650 }),
4651 };
4652
4653 let pinned_outer = Box::pin(outer);
4654
4655 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4657 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4658 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4659 );
4660
4661 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4663 |a: &Arc<Inner>| Some(&a.value),
4664 |_: &mut Arc<Inner>| None::<&mut String>,
4665 );
4666
4667 let chained = to_inner.then(to_value);
4669
4670 let result = chained.get(&pinned_outer);
4671 assert_eq!(result, Some(&"nested_value".to_string()));
4672 }
4673
4674 #[test]
4675 fn test_kp_with_maybe_uninit_array() {
4676 use std::mem::MaybeUninit;
4677
4678 struct Buffer {
4682 data: [MaybeUninit<u8>; 10],
4683 len: usize,
4684 }
4685
4686 impl Buffer {
4687 fn new() -> Self {
4688 Self {
4689 data: unsafe { MaybeUninit::uninit().assume_init() },
4690 len: 0,
4691 }
4692 }
4693
4694 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4695 if self.len >= self.data.len() {
4696 return Err("Buffer full");
4697 }
4698 self.data[self.len].write(byte);
4699 self.len += 1;
4700 Ok(())
4701 }
4702
4703 fn get(&self, idx: usize) -> Option<&u8> {
4704 if idx < self.len {
4705 unsafe { Some(self.data[idx].assume_init_ref()) }
4706 } else {
4707 None
4708 }
4709 }
4710
4711 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4712 if idx < self.len {
4713 unsafe { Some(self.data[idx].assume_init_mut()) }
4714 } else {
4715 None
4716 }
4717 }
4718 }
4719
4720 let len_kp: KpType<Buffer, usize> =
4722 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4723
4724 let mut buffer = Buffer::new();
4725
4726 assert_eq!(len_kp.get(&buffer), Some(&0));
4728
4729 buffer.push(1).unwrap();
4731 buffer.push(2).unwrap();
4732 buffer.push(3).unwrap();
4733
4734 assert_eq!(len_kp.get(&buffer), Some(&3));
4736
4737 assert_eq!(buffer.get(0), Some(&1));
4739 assert_eq!(buffer.get(1), Some(&2));
4740 assert_eq!(buffer.get(2), Some(&3));
4741 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4745 *elem = 20;
4746 }
4747 assert_eq!(buffer.get(1), Some(&20));
4748 }
4749
4750 #[test]
4751 fn test_kp_then_sync_deep_structs() {
4752 use std::sync::{Arc, Mutex};
4753
4754 #[derive(Clone)]
4755 struct Root {
4756 guard: Arc<Mutex<Level1>>,
4757 }
4758 #[derive(Clone)]
4759 struct Level1 {
4760 name: String,
4761 nested: Level2,
4762 }
4763 #[derive(Clone)]
4764 struct Level2 {
4765 count: i32,
4766 }
4767
4768 let root = Root {
4769 guard: Arc::new(Mutex::new(Level1 {
4770 name: "deep".to_string(),
4771 nested: Level2 { count: 42 },
4772 })),
4773 };
4774
4775 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4776 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4777
4778 let lock_kp = {
4779 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> = Kp::new(
4780 |g: &Arc<Mutex<Level1>>| Some(g),
4781 |g: &mut Arc<Mutex<Level1>>| Some(g),
4782 );
4783 let next: KpType<Level1, Level1> =
4784 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4785 crate::sync_kp::SyncKp::new(prev, crate::sync_kp::ArcMutexAccess::new(), next)
4786 };
4787
4788 let chained = kp_to_guard.then_sync(lock_kp);
4789 let level1 = chained.get(&root);
4790 assert!(level1.is_some());
4791 assert_eq!(level1.unwrap().name, "deep");
4792 assert_eq!(level1.unwrap().nested.count, 42);
4793
4794 let mut_root = &mut root.clone();
4795 let mut_level1 = chained.get_mut(mut_root);
4796 assert!(mut_level1.is_some());
4797 mut_level1.unwrap().nested.count = 99;
4798 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4799 }
4800
4801 #[test]
4802 fn test_kp_then_sync_with_enum() {
4803 use std::sync::{Arc, Mutex};
4804
4805 #[derive(Clone)]
4806 enum Message {
4807 Request(LevelA),
4808 Response(i32),
4809 }
4810 #[derive(Clone)]
4811 struct LevelA {
4812 data: Arc<Mutex<i32>>,
4813 }
4814
4815 struct RootWithEnum {
4816 msg: Arc<Mutex<Message>>,
4817 }
4818
4819 let root = RootWithEnum {
4820 msg: Arc::new(Mutex::new(Message::Request(LevelA {
4821 data: Arc::new(Mutex::new(100)),
4822 }))),
4823 };
4824
4825 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> = Kp::new(
4826 |r: &RootWithEnum| Some(&r.msg),
4827 |r: &mut RootWithEnum| Some(&mut r.msg),
4828 );
4829
4830 let lock_kp_msg = {
4831 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> = Kp::new(
4832 |m: &Arc<Mutex<Message>>| Some(m),
4833 |m: &mut Arc<Mutex<Message>>| Some(m),
4834 );
4835 let next: KpType<Message, Message> =
4836 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4837 crate::sync_kp::SyncKp::new(prev, crate::sync_kp::ArcMutexAccess::new(), next)
4838 };
4839
4840 let chained = kp_msg.then_sync(lock_kp_msg);
4841 let msg = chained.get(&root);
4842 assert!(msg.is_some());
4843 match msg.unwrap() {
4844 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
4845 Message::Response(_) => panic!("expected Request"),
4846 }
4847 }
4848
4849 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4850 #[tokio::test]
4851 async fn test_kp_then_async_deep_chain() {
4852 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4853 use std::sync::Arc;
4854
4855 #[derive(Clone)]
4856 struct Root {
4857 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
4858 }
4859 #[derive(Clone)]
4860 struct Level1 {
4861 value: i32,
4862 }
4863
4864 let root = Root {
4865 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
4866 };
4867
4868 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
4869 |r: &Root| Some(&r.tokio_guard),
4870 |r: &mut Root| Some(&mut r.tokio_guard),
4871 );
4872
4873 let async_kp = {
4874 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
4875 Kp::new(
4876 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
4877 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
4878 );
4879 let next: KpType<Level1, Level1> =
4880 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4881 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4882 };
4883
4884 let chained = kp_to_guard.then_async(async_kp);
4885 let level1 = chained.get(&root).await;
4886 assert!(level1.is_some());
4887 assert_eq!(level1.unwrap().value, 7);
4888 }
4889
4890 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4893 #[tokio::test]
4894 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
4895 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4896 use crate::sync_kp::{ArcMutexAccess, SyncKp};
4897 use std::sync::{Arc, Mutex};
4898
4899 #[derive(Clone)]
4901 struct Root {
4902 sync_mutex: Arc<Mutex<Level1>>,
4903 }
4904 #[derive(Clone)]
4906 struct Level1 {
4907 inner: Level2,
4908 }
4909 #[derive(Clone)]
4911 struct Level2 {
4912 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
4913 }
4914 #[derive(Clone)]
4916 struct Level3 {
4917 leaf: i32,
4918 }
4919
4920 let mut root = Root {
4921 sync_mutex: Arc::new(Mutex::new(Level1 {
4922 inner: Level2 {
4923 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
4924 },
4925 })),
4926 };
4927
4928 let identity_l1: KpType<Level1, Level1> =
4930 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4931 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
4932 |r: &Root| Some(&r.sync_mutex),
4933 |r: &mut Root| Some(&mut r.sync_mutex),
4934 );
4935 let lock_root_to_l1 = SyncKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
4936
4937 let kp_l1_inner: KpType<Level1, Level2> = Kp::new(
4939 |l: &Level1| Some(&l.inner),
4940 |l: &mut Level1| Some(&mut l.inner),
4941 );
4942
4943 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
4945 |l: &Level2| Some(&l.tokio_mutex),
4946 |l: &mut Level2| Some(&mut l.tokio_mutex),
4947 );
4948
4949 let async_l3 = {
4951 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
4952 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
4953 let next: KpType<Level3, Level3> =
4954 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
4955 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4956 };
4957
4958 let kp_l3_leaf: KpType<Level3, i32> = Kp::new(
4960 |l: &Level3| Some(&l.leaf),
4961 |l: &mut Level3| Some(&mut l.leaf),
4962 );
4963
4964 let step1 = lock_root_to_l1.then(kp_l1_inner);
4966 let step2 = step1.then(kp_l2_tokio);
4967 let step3 = step2.then_async(async_l3);
4968 let deep_chain = step3.then(kp_l3_leaf);
4969
4970 let leaf = deep_chain.get(&root).await;
4972 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
4973 assert_eq!(leaf, Some(&100));
4974
4975 let mut root_mut = root.clone();
4977 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
4978 assert!(leaf_mut.is_some());
4979 *leaf_mut.unwrap() = 99;
4980
4981 let leaf_after = deep_chain.get(&root_mut).await;
4983 assert_eq!(leaf_after, Some(&99));
4984 }
4985}