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