1#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
2
3use std::fmt;
16use std::sync::Arc;
17
18pub use std::ops::Shr;
19
20pub mod sync_kp;
22pub mod prelude;
23
24pub use sync_kp::{
25 ArcMutexAccess, ArcRwLockAccess, LockAccess, SyncKp, SyncKpType, RcRefCellAccess,
26 StdMutexAccess, StdRwLockAccess,
27};
28
29#[cfg(feature = "parking_lot")]
30pub use sync_kp::{
31 DirectParkingLotMutexAccess, DirectParkingLotRwLockAccess, ParkingLotMutexAccess,
32 ParkingLotRwLockAccess,
33};
34
35#[cfg(feature = "arc-swap")]
36pub use sync_kp::{ArcArcSwapAccess, ArcArcSwapOptionAccess};
37
38pub mod async_lock;
40
41pub mod kptrait;
42
43pub use key_paths_core::{
44 AccessorTrait, KeyPath, KeyPathValueTarget, KpTrait, Readable, Writable,
45};
46
47pub use kptrait::{ChainExt, CoercionTrait, HofTrait};
48
49#[cfg(feature = "pin_project")]
92pub mod pin;
93
94#[macro_export]
96macro_rules! keypath {
97 { $root:ident . $field:ident } => { $root::$field() };
98 { $root:ident . $field:ident . $($ty:ident . $f:ident).+ } => {
99 $root::$field() $(.then($ty::$f()))+
100 };
101 ($root:ident . $field:ident) => { $root::$field() };
102 ($root:ident . $field:ident . $($ty:ident . $f:ident).+) => {
103 $root::$field() $(.then($ty::$f()))+
104 };
105}
106
107#[macro_export]
111macro_rules! get_or {
112 ($kp:expr, $root:expr, $default:expr) => {
113 $kp.get($root).unwrap_or($default)
114 };
115 ($root:expr => $($path:tt)*, $default:expr) => {
116 $crate::get_or!($crate::keypath!($($path)*), $root, $default)
117 };
118}
119
120#[macro_export]
125macro_rules! get_or_else {
126 ($kp:expr, $root:expr, $closure:expr) => {
127 $kp.get($root).map(|r| r.clone()).unwrap_or_else($closure)
128 };
129 ($root:expr => ($($path:tt)*), $closure:expr) => {
130 $crate::get_or_else!($crate::keypath!($($path)*), $root, $closure)
131 };
132}
133
134#[macro_export]
155macro_rules! zip_with_kp {
156 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr) => {
157 match ($kp1.get($root), $kp2.get($root)) {
158 (Some(__a), Some(__b)) => Some($closure((__a, __b))),
159 _ => None,
160 }
161 };
162 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr) => {
163 match ($kp1.get($root), $kp2.get($root), $kp3.get($root)) {
164 (Some(__a), Some(__b), Some(__c)) => Some($closure((__a, __b, __c))),
165 _ => None,
166 }
167 };
168 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr) => {
169 match (
170 $kp1.get($root),
171 $kp2.get($root),
172 $kp3.get($root),
173 $kp4.get($root),
174 ) {
175 (Some(__a), Some(__b), Some(__c), Some(__d)) => Some($closure((__a, __b, __c, __d))),
176 _ => None,
177 }
178 };
179 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr) => {
180 match (
181 $kp1.get($root),
182 $kp2.get($root),
183 $kp3.get($root),
184 $kp4.get($root),
185 $kp5.get($root),
186 ) {
187 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e)) => {
188 Some($closure((__a, __b, __c, __d, __e)))
189 }
190 _ => None,
191 }
192 };
193 ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr, $kp6:expr) => {
194 match (
195 $kp1.get($root),
196 $kp2.get($root),
197 $kp3.get($root),
198 $kp4.get($root),
199 $kp5.get($root),
200 $kp6.get($root),
201 ) {
202 (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e), Some(__f)) => {
203 Some($closure((__a, __b, __c, __d, __e, __f)))
204 }
205 _ => None,
206 }
207 };
208}
209
210pub type KpValue<'a, R, V> = Kp<
212 R,
213 V,
214 &'a R,
215 V, &'a mut R,
217 V, for<'b> fn(&'b R) -> Option<V>,
219 for<'b> fn(&'b mut R) -> Option<V>,
220>;
221
222pub type KpOwned<R, V> = Kp<
224 R,
225 V,
226 R,
227 V, R,
229 V, fn(R) -> Option<V>,
231 fn(R) -> Option<V>,
232>;
233
234pub type KpRoot<R> = Kp<
236 R,
237 R,
238 R,
239 R, R,
241 R, fn(R) -> Option<R>,
243 fn(R) -> Option<R>,
244>;
245
246pub type KpVoid = Kp<(), (), (), (), (), (), fn() -> Option<()>, fn() -> Option<()>>;
248
249pub type KpDynamic<R, V> = Kp<
250 R,
251 V,
252 &'static R,
253 &'static V,
254 &'static mut R,
255 &'static mut V,
256 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
257 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
258>;
259
260pub type KpBox<'a, R, V> = Kp<
261 R,
262 V,
263 &'a R,
264 &'a V,
265 &'a mut R,
266 &'a mut V,
267 Box<dyn Fn(&'a R) -> Option<&'a V> + 'a>,
268 Box<dyn Fn(&'a mut R) -> Option<&'a mut V> + 'a>,
269>;
270
271pub type KpArc<'a, R, V> = Kp<
272 R,
273 V,
274 &'a R,
275 &'a V,
276 &'a mut R,
277 &'a mut V,
278 Arc<dyn Fn(&'a R) -> Option<&'a V> + Send + Sync + 'a>,
279 Arc<dyn Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync + 'a>,
280>;
281
282pub type KpType<'a, R, V> = Kp<
283 R,
284 V,
285 &'a R,
286 &'a V,
287 &'a mut R,
288 &'a mut V,
289 for<'b> fn(&'b R) -> Option<&'b V>,
290 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
291>;
292
293pub type KpTraitType<'a, R, V> = dyn KpTrait<R, V, &'a R, &'a V, &'a mut R, &'a mut V>;
294
295pub type KpOptionRefCellType<'a, R, V> = Kp<
298 R,
299 V,
300 &'a R,
301 std::cell::Ref<'a, V>,
302 &'a mut R,
303 std::cell::RefMut<'a, V>,
304 for<'b> fn(&'b R) -> Option<std::cell::Ref<'b, V>>,
305 for<'b> fn(&'b mut R) -> Option<std::cell::RefMut<'b, V>>,
306>;
307
308impl<'a, R, V> KpType<'a, R, V> {
309 #[inline]
311 pub fn to_dynamic(self) -> KpDynamic<R, V> {
312 self.into()
313 }
314}
315
316impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V> {
317 #[inline]
318 fn from(kp: KpType<'a, R, V>) -> Self {
319 let get_fn = kp.get;
320 let set_fn = kp.set;
321 Kp::new(
322 Box::new(move |t: &R| get_fn(t)),
323 Box::new(move |t: &mut R| set_fn(t)),
324 )
325 }
326}
327
328impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
329where
330 Root: std::borrow::Borrow<R>,
331 Value: std::borrow::Borrow<V>,
332 MutRoot: std::borrow::BorrowMut<R>,
333 MutValue: std::borrow::BorrowMut<V>,
334 G: Fn(Root) -> Option<Value> + Send + Sync + 'static,
335 S: Fn(MutRoot) -> Option<MutValue> + Send + Sync + 'static,
336 R: 'static,
337 V: 'static,
338{
339 #[inline]
353 pub fn into_dynamic(self) -> KpDynamic<R, V> {
354 let g = self.get;
355 let s = self.set;
356 Kp::new(
357 Box::new(move |t: &R| unsafe {
358 let root: Root = std::mem::transmute_copy(&t);
361 match g(root) {
362 None => None,
363 Some(v) => {
364 let r: &V = std::borrow::Borrow::borrow(&v);
365 Some(std::mem::transmute::<&V, &V>(r))
367 }
368 }
369 }),
370 Box::new(move |t: &mut R| unsafe {
371 let root: MutRoot = std::mem::transmute_copy(&t);
373 match s(root) {
374 None => None,
375 Some(mut v) => {
376 let r: &mut V = std::borrow::BorrowMut::borrow_mut(&mut v);
377 Some(std::mem::transmute::<&mut V, &mut V>(r))
378 }
379 }
380 }),
381 )
382 }
383}
384
385pub type KpComposed<R, V> = Kp<
421 R,
422 V,
423 &'static R,
424 &'static V,
425 &'static mut R,
426 &'static mut V,
427 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
428 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
429>;
430
431impl<R, V>
432 Kp<
433 R,
434 V,
435 &'static R,
436 &'static V,
437 &'static mut R,
438 &'static mut V,
439 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
440 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
441 >
442{
443 pub fn from_closures<G, S>(get: G, set: S) -> Self
446 where
447 G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
448 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
449 {
450 Self::new(Box::new(get), Box::new(set))
451 }
452}
453
454pub struct AKp {
455 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
456 root_type_id: TypeId,
457 value_type_id: TypeId,
458}
459
460impl AKp {
461 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
463 where
464 R: Any + 'static,
465 V: Any + 'static,
466 {
467 let root_type_id = TypeId::of::<R>();
468 let value_type_id = TypeId::of::<V>();
469 let getter_fn = keypath.get;
470
471 Self {
472 getter: Rc::new(move |any: &dyn Any| {
473 if let Some(root) = any.downcast_ref::<R>() {
474 getter_fn(root).map(|value: &V| value as &dyn Any)
475 } else {
476 None
477 }
478 }),
479 root_type_id,
480 value_type_id,
481 }
482 }
483
484 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
486 where
487 R: Any + 'static,
488 V: Any + 'static,
489 {
490 Self::new(keypath)
491 }
492
493 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
495 (self.getter)(root)
496 }
497
498 pub fn root_type_id(&self) -> TypeId {
500 self.root_type_id
501 }
502
503 pub fn value_type_id(&self) -> TypeId {
505 self.value_type_id
506 }
507
508 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
510 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
511 {
512 Some(
513 self.get(root as &dyn Any)
514 .and_then(|any| any.downcast_ref::<Value>()),
515 )
516 } else {
517 None
518 }
519 }
520
521 pub fn kind_name(&self) -> String {
523 format!("{:?}", self.value_type_id)
524 }
525
526 pub fn root_kind_name(&self) -> String {
528 format!("{:?}", self.root_type_id)
529 }
530
531 pub fn for_arc<Root>(&self) -> AKp
533 where
534 Root: Any + 'static,
535 {
536 let value_type_id = self.value_type_id;
537 let getter = self.getter.clone();
538
539 AKp {
540 getter: Rc::new(move |any: &dyn Any| {
541 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
542 getter(arc.as_ref() as &dyn Any)
543 } else {
544 None
545 }
546 }),
547 root_type_id: TypeId::of::<Arc<Root>>(),
548 value_type_id,
549 }
550 }
551
552 pub fn for_box<Root>(&self) -> AKp
554 where
555 Root: Any + 'static,
556 {
557 let value_type_id = self.value_type_id;
558 let getter = self.getter.clone();
559
560 AKp {
561 getter: Rc::new(move |any: &dyn Any| {
562 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
563 getter(boxed.as_ref() as &dyn Any)
564 } else {
565 None
566 }
567 }),
568 root_type_id: TypeId::of::<Box<Root>>(),
569 value_type_id,
570 }
571 }
572
573 pub fn for_rc<Root>(&self) -> AKp
575 where
576 Root: Any + 'static,
577 {
578 let value_type_id = self.value_type_id;
579 let getter = self.getter.clone();
580
581 AKp {
582 getter: Rc::new(move |any: &dyn Any| {
583 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
584 getter(rc.as_ref() as &dyn Any)
585 } else {
586 None
587 }
588 }),
589 root_type_id: TypeId::of::<Rc<Root>>(),
590 value_type_id,
591 }
592 }
593
594 pub fn for_option<Root>(&self) -> AKp
596 where
597 Root: Any + 'static,
598 {
599 let value_type_id = self.value_type_id;
600 let getter = self.getter.clone();
601
602 AKp {
603 getter: Rc::new(move |any: &dyn Any| {
604 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
605 opt.as_ref().and_then(|root| getter(root as &dyn Any))
606 } else {
607 None
608 }
609 }),
610 root_type_id: TypeId::of::<Option<Root>>(),
611 value_type_id,
612 }
613 }
614
615 pub fn for_result<Root, E>(&self) -> AKp
617 where
618 Root: Any + 'static,
619 E: Any + 'static,
620 {
621 let value_type_id = self.value_type_id;
622 let getter = self.getter.clone();
623
624 AKp {
625 getter: Rc::new(move |any: &dyn Any| {
626 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
627 result
628 .as_ref()
629 .ok()
630 .and_then(|root| getter(root as &dyn Any))
631 } else {
632 None
633 }
634 }),
635 root_type_id: TypeId::of::<Result<Root, E>>(),
636 value_type_id,
637 }
638 }
639
640 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
653 where
654 Root: Any + 'static,
655 OrigValue: Any + 'static,
656 MappedValue: Any + 'static,
657 F: Fn(&OrigValue) -> MappedValue + 'static,
658 {
659 let orig_root_type_id = self.root_type_id;
660 let orig_value_type_id = self.value_type_id;
661 let getter = self.getter.clone();
662 let mapped_type_id = TypeId::of::<MappedValue>();
663
664 AKp {
665 getter: Rc::new(move |any_root: &dyn Any| {
666 if any_root.type_id() == orig_root_type_id {
668 getter(any_root).and_then(|any_value| {
669 if orig_value_type_id == TypeId::of::<OrigValue>() {
671 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
672 let mapped = mapper(orig_val);
673 Box::leak(Box::new(mapped)) as &dyn Any
675 })
676 } else {
677 None
678 }
679 })
680 } else {
681 None
682 }
683 }),
684 root_type_id: orig_root_type_id,
685 value_type_id: mapped_type_id,
686 }
687 }
688
689 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
702 where
703 Root: Any + 'static,
704 Value: Any + 'static,
705 F: Fn(&Value) -> bool + 'static,
706 {
707 let orig_root_type_id = self.root_type_id;
708 let orig_value_type_id = self.value_type_id;
709 let getter = self.getter.clone();
710
711 AKp {
712 getter: Rc::new(move |any_root: &dyn Any| {
713 if any_root.type_id() == orig_root_type_id {
715 getter(any_root).filter(|any_value| {
716 if orig_value_type_id == TypeId::of::<Value>() {
718 any_value
719 .downcast_ref::<Value>()
720 .map(|val| predicate(val))
721 .unwrap_or(false)
722 } else {
723 false
724 }
725 })
726 } else {
727 None
728 }
729 }),
730 root_type_id: orig_root_type_id,
731 value_type_id: orig_value_type_id,
732 }
733 }
734}
735
736impl fmt::Debug for AKp {
737 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
738 f.debug_struct("AKp")
739 .field("root_type_id", &self.root_type_id)
740 .field("value_type_id", &self.value_type_id)
741 .finish_non_exhaustive()
742 }
743}
744
745impl fmt::Display for AKp {
746 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
747 write!(
748 f,
749 "AKp(root_type_id={:?}, value_type_id={:?})",
750 self.root_type_id, self.value_type_id
751 )
752 }
753}
754
755pub struct PKp<Root> {
756 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
757 value_type_id: TypeId,
758 _phantom: std::marker::PhantomData<Root>,
759}
760
761impl<Root> PKp<Root>
762where
763 Root: 'static,
764{
765 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
767 where
768 V: Any + 'static,
769 {
770 let value_type_id = TypeId::of::<V>();
771 let getter_fn = keypath.get;
772
773 Self {
774 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
775 value_type_id,
776 _phantom: std::marker::PhantomData,
777 }
778 }
779
780 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
782 where
783 V: Any + 'static,
784 {
785 Self::new(keypath)
786 }
787
788 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
790 (self.getter)(root)
791 }
792
793 pub fn value_type_id(&self) -> TypeId {
795 self.value_type_id
796 }
797
798 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
800 if self.value_type_id == TypeId::of::<Value>() {
801 self.get(root).and_then(|any| any.downcast_ref::<Value>())
802 } else {
803 None
804 }
805 }
806
807 pub fn kind_name(&self) -> String {
809 format!("{:?}", self.value_type_id)
810 }
811
812 pub fn for_arc(&self) -> PKp<Arc<Root>> {
814 let getter = self.getter.clone();
815 let value_type_id = self.value_type_id;
816
817 PKp {
818 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
819 value_type_id,
820 _phantom: std::marker::PhantomData,
821 }
822 }
823
824 pub fn for_box(&self) -> PKp<Box<Root>> {
826 let getter = self.getter.clone();
827 let value_type_id = self.value_type_id;
828
829 PKp {
830 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
831 value_type_id,
832 _phantom: std::marker::PhantomData,
833 }
834 }
835
836 pub fn for_rc(&self) -> PKp<Rc<Root>> {
838 let getter = self.getter.clone();
839 let value_type_id = self.value_type_id;
840
841 PKp {
842 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
843 value_type_id,
844 _phantom: std::marker::PhantomData,
845 }
846 }
847
848 pub fn for_option(&self) -> PKp<Option<Root>> {
850 let getter = self.getter.clone();
851 let value_type_id = self.value_type_id;
852
853 PKp {
854 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
855 value_type_id,
856 _phantom: std::marker::PhantomData,
857 }
858 }
859
860 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
862 where
863 E: 'static,
864 {
865 let getter = self.getter.clone();
866 let value_type_id = self.value_type_id;
867
868 PKp {
869 getter: Rc::new(move |result: &Result<Root, E>| {
870 result.as_ref().ok().and_then(|root| getter(root))
871 }),
872 value_type_id,
873 _phantom: std::marker::PhantomData,
874 }
875 }
876
877 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
891 where
892 OrigValue: Any + 'static,
893 MappedValue: Any + 'static,
894 F: Fn(&OrigValue) -> MappedValue + 'static,
895 {
896 let orig_type_id = self.value_type_id;
897 let getter = self.getter.clone();
898 let mapped_type_id = TypeId::of::<MappedValue>();
899
900 PKp {
901 getter: Rc::new(move |root: &Root| {
902 getter(root).and_then(|any_value| {
903 if orig_type_id == TypeId::of::<OrigValue>() {
905 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
906 let mapped = mapper(orig_val);
907 Box::leak(Box::new(mapped)) as &dyn Any
910 })
911 } else {
912 None
913 }
914 })
915 }),
916 value_type_id: mapped_type_id,
917 _phantom: std::marker::PhantomData,
918 }
919 }
920
921 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
935 where
936 Value: Any + 'static,
937 F: Fn(&Value) -> bool + 'static,
938 {
939 let orig_type_id = self.value_type_id;
940 let getter = self.getter.clone();
941
942 PKp {
943 getter: Rc::new(move |root: &Root| {
944 getter(root).filter(|any_value| {
945 if orig_type_id == TypeId::of::<Value>() {
947 any_value
948 .downcast_ref::<Value>()
949 .map(|val| predicate(val))
950 .unwrap_or(false)
951 } else {
952 false
953 }
954 })
955 }),
956 value_type_id: orig_type_id,
957 _phantom: std::marker::PhantomData,
958 }
959 }
960}
961
962impl<Root> fmt::Debug for PKp<Root> {
963 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
964 f.debug_struct("PKp")
965 .field("root_ty", &std::any::type_name::<Root>())
966 .field("value_type_id", &self.value_type_id)
967 .finish_non_exhaustive()
968 }
969}
970
971impl<Root> fmt::Display for PKp<Root> {
972 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
973 write!(
974 f,
975 "PKp<{}, value_type_id={:?}>",
976 std::any::type_name::<Root>(),
977 self.value_type_id
978 )
979 }
980}
981
982#[derive(Clone)]
1000pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1001where
1002 Root: std::borrow::Borrow<R>,
1003 MutRoot: std::borrow::BorrowMut<R>,
1004 MutValue: std::borrow::BorrowMut<V>,
1005 G: Fn(Root) -> Option<Value>,
1006 S: Fn(MutRoot) -> Option<MutValue>,
1007{
1008 get: G,
1010 set: S,
1012 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
1013}
1014
1015#[inline]
1017pub fn constrain_get<R, V, F>(f: F) -> F
1018where
1019 F: for<'b> Fn(&'b R) -> Option<&'b V>,
1020{
1021 f
1022}
1023
1024#[inline]
1026pub fn constrain_set<R, V, F>(f: F) -> F
1027where
1028 F: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1029{
1030 f
1031}
1032
1033impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1034where
1035 Root: std::borrow::Borrow<R>,
1036 Value: std::borrow::Borrow<V>,
1037 MutRoot: std::borrow::BorrowMut<R>,
1038 MutValue: std::borrow::BorrowMut<V>,
1039 G: Fn(Root) -> Option<Value>,
1040 S: Fn(MutRoot) -> Option<MutValue>,
1041{
1042 pub fn new(get: G, set: S) -> Self {
1043 Self {
1044 get,
1045 set,
1046 _p: std::marker::PhantomData,
1047 }
1048 }
1049
1050 #[inline]
1053 pub fn get(&self, root: Root) -> Option<Value> {
1054 (self.get)(root)
1055 }
1056
1057 #[inline]
1059 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1060 (self.set)(root)
1061 }
1062
1063 #[inline]
1066 pub fn get_ref<'a>(&self, root: &'a R) -> Option<&'a V>
1067 where
1068 G: for<'b> Fn(&'b R) -> Option<&'b V>,
1069 {
1070 (self.get)(root)
1071 }
1072
1073 #[inline]
1075 pub fn get_mut_ref<'a>(&self, root: &'a mut R) -> Option<&'a mut V>
1076 where
1077 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1078 {
1079 (self.set)(root)
1080 }
1081
1082 #[inline]
1083 pub fn then<SV, G2, S2>(
1084 self,
1085 next: Kp<
1086 V,
1087 SV,
1088 &'static V, &'static SV,
1090 &'static mut V,
1091 &'static mut SV,
1092 G2,
1093 S2,
1094 >,
1095 ) -> Kp<
1096 R,
1097 SV,
1098 &'static R,
1099 &'static SV,
1100 &'static mut R,
1101 &'static mut SV,
1102 impl for<'b> Fn(&'b R) -> Option<&'b SV>,
1103 impl for<'b> Fn(&'b mut R) -> Option<&'b mut SV>,
1104 >
1105 where
1106 G: for<'b> Fn(&'b R) -> Option<&'b V>,
1107 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1108 G2: for<'b> Fn(&'b V) -> Option<&'b SV>,
1109 S2: for<'b> Fn(&'b mut V) -> Option<&'b mut SV>,
1110 {
1111 let first_get = self.get;
1112 let first_set = self.set;
1113 let second_get = next.get;
1114 let second_set = next.set;
1115
1116 Kp::new(
1117 constrain_get(move |root: &R| first_get(root).and_then(|value| second_get(value))),
1118 constrain_set(move |root: &mut R| first_set(root).and_then(|value| second_set(value))),
1119 )
1120 }
1121}
1122
1123#[cfg(feature = "nightly")]
1124mod kp_shr {
1142 use super::{Kp, Shr};
1143
1144 impl<R, V, SV, G, S, G2, S2>
1145 Shr<Kp<V, SV, &'static V, &'static SV, &'static mut V, &'static mut SV, G2, S2>>
1146 for Kp<R, V, &'static R, &'static V, &'static mut R, &'static mut V, G, S>
1147 where
1148 R: 'static,
1149 V: 'static,
1150 SV: 'static,
1151 G: for<'b> Fn(&'b R) -> Option<&'b V>,
1152 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1153 G2: for<'b> Fn(&'b V) -> Option<&'b SV>,
1154 S2: for<'b> Fn(&'b mut V) -> Option<&'b mut SV>,
1155 {
1156 type Output = Kp<
1157 R,
1158 SV,
1159 &'static R,
1160 &'static SV,
1161 &'static mut R,
1162 &'static mut SV,
1163 impl for<'b> Fn(&'b R) -> Option<&'b SV>,
1164 impl for<'b> Fn(&'b mut R) -> Option<&'b mut SV>,
1165 >;
1166
1167 #[inline]
1168 fn shr(
1169 self,
1170 rhs: Kp<V, SV, &'static V, &'static SV, &'static mut V, &'static mut SV, G2, S2>,
1171 ) -> Self::Output {
1172 self.then(rhs)
1173 }
1174 }
1175
1176 impl<R, V, SV, G, S, G2, S2>
1177 Shr<&Kp<V, SV, &'static V, &'static SV, &'static mut V, &'static mut SV, G2, S2>>
1178 for Kp<R, V, &'static R, &'static V, &'static mut R, &'static mut V, G, S>
1179 where
1180 R: 'static,
1181 V: 'static,
1182 SV: 'static,
1183 G: for<'b> Fn(&'b R) -> Option<&'b V>,
1184 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1185 G2: for<'b> Fn(&'b V) -> Option<&'b SV>,
1186 S2: for<'b> Fn(&'b mut V) -> Option<&'b mut SV>,
1187 Kp<V, SV, &'static V, &'static SV, &'static mut V, &'static mut SV, G2, S2>: Clone,
1188 {
1189 type Output = Kp<
1190 R,
1191 SV,
1192 &'static R,
1193 &'static SV,
1194 &'static mut R,
1195 &'static mut SV,
1196 impl for<'b> Fn(&'b R) -> Option<&'b SV>,
1197 impl for<'b> Fn(&'b mut R) -> Option<&'b mut SV>,
1198 >;
1199
1200 #[inline]
1201 fn shr(
1202 self,
1203 rhs: &Kp<V, SV, &'static V, &'static SV, &'static mut V, &'static mut SV, G2, S2>,
1204 ) -> Self::Output {
1205 self.then(rhs.clone())
1206 }
1207 }
1208
1209 impl<R, V, SV, G, S, G2, S2>
1210 Shr<Kp<V, SV, &'static V, &'static SV, &'static mut V, &'static mut SV, G2, S2>>
1211 for &Kp<R, V, &'static R, &'static V, &'static mut R, &'static mut V, G, S>
1212 where
1213 R: 'static,
1214 V: 'static,
1215 SV: 'static,
1216 G: for<'b> Fn(&'b R) -> Option<&'b V>,
1217 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1218 G2: for<'b> Fn(&'b V) -> Option<&'b SV>,
1219 S2: for<'b> Fn(&'b mut V) -> Option<&'b mut SV>,
1220 Kp<R, V, &'static R, &'static V, &'static mut R, &'static mut V, G, S>: Clone,
1221 {
1222 type Output = Kp<
1223 R,
1224 SV,
1225 &'static R,
1226 &'static SV,
1227 &'static mut R,
1228 &'static mut SV,
1229 impl for<'b> Fn(&'b R) -> Option<&'b SV>,
1230 impl for<'b> Fn(&'b mut R) -> Option<&'b mut SV>,
1231 >;
1232
1233 #[inline]
1234 fn shr(
1235 self,
1236 rhs: Kp<V, SV, &'static V, &'static SV, &'static mut V, &'static mut SV, G2, S2>,
1237 ) -> Self::Output {
1238 self.clone().then(rhs)
1239 }
1240 }
1241}
1242
1243#[cfg(feature = "nightly")]
1244pub use kp_shr::*;
1245
1246impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Debug
1247 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1248where
1249 Root: std::borrow::Borrow<R>,
1250 Value: std::borrow::Borrow<V>,
1251 MutRoot: std::borrow::BorrowMut<R>,
1252 MutValue: std::borrow::BorrowMut<V>,
1253 G: Fn(Root) -> Option<Value>,
1254 S: Fn(MutRoot) -> Option<MutValue>,
1255{
1256 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1257 f.debug_struct("Kp")
1258 .field("root_ty", &std::any::type_name::<R>())
1259 .field("value_ty", &std::any::type_name::<V>())
1260 .finish_non_exhaustive()
1261 }
1262}
1263
1264impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Display
1265 for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1266where
1267 Root: std::borrow::Borrow<R>,
1268 Value: std::borrow::Borrow<V>,
1269 MutRoot: std::borrow::BorrowMut<R>,
1270 MutValue: std::borrow::BorrowMut<V>,
1271 G: Fn(Root) -> Option<Value>,
1272 S: Fn(MutRoot) -> Option<MutValue>,
1273{
1274 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1275 write!(
1276 f,
1277 "Kp<{}, {}>",
1278 std::any::type_name::<R>(),
1279 std::any::type_name::<V>()
1280 )
1281 }
1282}
1283
1284pub fn zip_kps<'a, RootType, Value1, Value2>(
1298 kp1: &'a KpType<'a, RootType, Value1>,
1299 kp2: &'a KpType<'a, RootType, Value2>,
1300) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1301where
1302 RootType: 'a,
1303 Value1: 'a,
1304 Value2: 'a,
1305{
1306 move |root: &'a RootType| {
1307 let val1 = (kp1.get)(root)?;
1308 let val2 = (kp2.get)(root)?;
1309 Some((val1, val2))
1310 }
1311}
1312
1313impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1314where
1315 Root: std::borrow::Borrow<R>,
1316 MutRoot: std::borrow::BorrowMut<R>,
1317 G: Fn(Root) -> Option<Root>,
1318 S: Fn(MutRoot) -> Option<MutRoot>,
1319{
1320 pub fn identity_typed() -> Kp<
1321 R,
1322 R,
1323 Root,
1324 Root,
1325 MutRoot,
1326 MutRoot,
1327 fn(Root) -> Option<Root>,
1328 fn(MutRoot) -> Option<MutRoot>,
1329 > {
1330 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1331 }
1332
1333 pub fn identity<'a>() -> KpType<'a, R, R> {
1334 KpType::new(|r| Some(r), |r| Some(r))
1335 }
1336}
1337
1338pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1347where
1348 Root: std::borrow::Borrow<Enum>,
1349 Value: std::borrow::Borrow<Variant>,
1350 MutRoot: std::borrow::BorrowMut<Enum>,
1351 MutValue: std::borrow::BorrowMut<Variant>,
1352 G: Fn(Root) -> Option<Value>,
1353 S: Fn(MutRoot) -> Option<MutValue>,
1354 E: Fn(Variant) -> Enum,
1355{
1356 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1357 embedder: E,
1358}
1359
1360unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1362 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1363where
1364 Root: std::borrow::Borrow<Enum>,
1365 Value: std::borrow::Borrow<Variant>,
1366 MutRoot: std::borrow::BorrowMut<Enum>,
1367 MutValue: std::borrow::BorrowMut<Variant>,
1368 G: Fn(Root) -> Option<Value> + Send,
1369 S: Fn(MutRoot) -> Option<MutValue> + Send,
1370 E: Fn(Variant) -> Enum + Send,
1371{
1372}
1373unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1374 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1375where
1376 Root: std::borrow::Borrow<Enum>,
1377 Value: std::borrow::Borrow<Variant>,
1378 MutRoot: std::borrow::BorrowMut<Enum>,
1379 MutValue: std::borrow::BorrowMut<Variant>,
1380 G: Fn(Root) -> Option<Value> + Sync,
1381 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1382 E: Fn(Variant) -> Enum + Sync,
1383{
1384}
1385
1386impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1387 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1388where
1389 Root: std::borrow::Borrow<Enum>,
1390 Value: std::borrow::Borrow<Variant>,
1391 MutRoot: std::borrow::BorrowMut<Enum>,
1392 MutValue: std::borrow::BorrowMut<Variant>,
1393 G: Fn(Root) -> Option<Value>,
1394 S: Fn(MutRoot) -> Option<MutValue>,
1395 E: Fn(Variant) -> Enum,
1396{
1397 pub fn new(
1399 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1400 embedder: E,
1401 ) -> Self {
1402 Self {
1403 extractor,
1404 embedder,
1405 }
1406 }
1407
1408 pub fn get(&self, enum_value: Root) -> Option<Value> {
1410 (self.extractor.get)(enum_value)
1411 }
1412
1413 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1415 (self.extractor.set)(enum_value)
1416 }
1417
1418 pub fn embed(&self, value: Variant) -> Enum {
1420 (self.embedder)(value)
1421 }
1422
1423 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1425 &self.extractor
1426 }
1427
1428 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1430 self.extractor
1431 }
1432
1433 pub fn map<MappedValue, F>(
1444 &self,
1445 mapper: F,
1446 ) -> EnumKp<
1447 Enum,
1448 MappedValue,
1449 Root,
1450 MappedValue,
1451 MutRoot,
1452 MappedValue,
1453 impl Fn(Root) -> Option<MappedValue>,
1454 impl Fn(MutRoot) -> Option<MappedValue>,
1455 impl Fn(MappedValue) -> Enum,
1456 >
1457 where
1458 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1461 Variant: 'static,
1462 MappedValue: 'static,
1463 E: Fn(Variant) -> Enum + Copy + 'static,
1465 {
1466 let mapped_extractor = self.extractor.map(mapper);
1467
1468 let new_embedder = move |_value: MappedValue| -> Enum {
1472 panic!(
1473 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1474 )
1475 };
1476
1477 EnumKp::new(mapped_extractor, new_embedder)
1478 }
1479
1480 pub fn filter<F>(
1492 &self,
1493 predicate: F,
1494 ) -> EnumKp<
1495 Enum,
1496 Variant,
1497 Root,
1498 Value,
1499 MutRoot,
1500 MutValue,
1501 impl Fn(Root) -> Option<Value>,
1502 impl Fn(MutRoot) -> Option<MutValue>,
1503 E,
1504 >
1505 where
1506 F: Fn(&Variant) -> bool + Copy + 'static,
1509 Variant: 'static,
1510 E: Copy,
1512 {
1513 let filtered_extractor = self.extractor.filter(predicate);
1514 EnumKp::new(filtered_extractor, self.embedder)
1515 }
1516}
1517
1518impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Debug
1519 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1520where
1521 Root: std::borrow::Borrow<Enum>,
1522 Value: std::borrow::Borrow<Variant>,
1523 MutRoot: std::borrow::BorrowMut<Enum>,
1524 MutValue: std::borrow::BorrowMut<Variant>,
1525 G: Fn(Root) -> Option<Value>,
1526 S: Fn(MutRoot) -> Option<MutValue>,
1527 E: Fn(Variant) -> Enum,
1528{
1529 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1530 f.debug_struct("EnumKp")
1531 .field("enum_ty", &std::any::type_name::<Enum>())
1532 .field("variant_ty", &std::any::type_name::<Variant>())
1533 .finish_non_exhaustive()
1534 }
1535}
1536
1537impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Display
1538 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1539where
1540 Root: std::borrow::Borrow<Enum>,
1541 Value: std::borrow::Borrow<Variant>,
1542 MutRoot: std::borrow::BorrowMut<Enum>,
1543 MutValue: std::borrow::BorrowMut<Variant>,
1544 G: Fn(Root) -> Option<Value>,
1545 S: Fn(MutRoot) -> Option<MutValue>,
1546 E: Fn(Variant) -> Enum,
1547{
1548 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1549 write!(
1550 f,
1551 "EnumKp<{}, {}>",
1552 std::any::type_name::<Enum>(),
1553 std::any::type_name::<Variant>()
1554 )
1555 }
1556}
1557
1558pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1560 Enum,
1561 Variant,
1562 &'a Enum,
1563 &'a Variant,
1564 &'a mut Enum,
1565 &'a mut Variant,
1566 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1567 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1568 fn(Variant) -> Enum,
1569>;
1570
1571pub fn enum_variant<'a, Enum, Variant>(
1589 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1590 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1591 embedder: fn(Variant) -> Enum,
1592) -> EnumKpType<'a, Enum, Variant> {
1593 EnumKp::new(Kp::new(getter, setter), embedder)
1594}
1595
1596pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1606 EnumKp::new(
1607 Kp::new(
1608 |r: &Result<T, E>| r.as_ref().ok(),
1609 |r: &mut Result<T, E>| r.as_mut().ok(),
1610 ),
1611 |t: T| Ok(t),
1612 )
1613}
1614
1615pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1625 EnumKp::new(
1626 Kp::new(
1627 |r: &Result<T, E>| r.as_ref().err(),
1628 |r: &mut Result<T, E>| r.as_mut().err(),
1629 ),
1630 |e: E| Err(e),
1631 )
1632}
1633
1634pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1644 EnumKp::new(
1645 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1646 |t: T| Some(t),
1647 )
1648}
1649
1650pub fn variant_of<'a, Enum, Variant>(
1668 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1669 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1670 embedder: fn(Variant) -> Enum,
1671) -> EnumKpType<'a, Enum, Variant> {
1672 enum_variant(getter, setter, embedder)
1673}
1674
1675pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1688 Kp::new(
1689 |b: &Box<T>| Some(b.as_ref()),
1690 |b: &mut Box<T>| Some(b.as_mut()),
1691 )
1692}
1693
1694pub fn kp_arc<'a, T>() -> Kp<
1705 Arc<T>,
1706 T,
1707 &'a Arc<T>,
1708 &'a T,
1709 &'a mut Arc<T>,
1710 &'a mut T,
1711 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
1712 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
1713> {
1714 Kp::new(
1715 |arc: &Arc<T>| Some(arc.as_ref()),
1716 |arc: &mut Arc<T>| Arc::get_mut(arc),
1717 )
1718}
1719
1720pub fn kp_rc<'a, T>() -> Kp<
1731 std::rc::Rc<T>,
1732 T,
1733 &'a std::rc::Rc<T>,
1734 &'a T,
1735 &'a mut std::rc::Rc<T>,
1736 &'a mut T,
1737 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
1738 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
1739> {
1740 Kp::new(
1741 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
1742 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
1743 )
1744}
1745
1746use std::any::{Any, TypeId};
1749use std::rc::Rc;
1750
1751#[cfg(test)]
1766mod tests {
1767 use super::*;
1768 use std::collections::HashMap;
1769
1770 fn kp_adaptable<T, Root, Value, MutRoot, MutValue, G, S>(kp: T)
1771 where
1772 T: KpTrait<TestKP, String, Root, Value, MutRoot, MutValue>,
1773 {
1774 }
1777 fn test_kp_trait() {}
1778
1779 #[derive(Debug)]
1780 struct TestKP {
1781 a: String,
1782 b: String,
1783 c: std::sync::Arc<String>,
1784 d: std::sync::Mutex<String>,
1785 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
1786 f: Option<TestKP2>,
1787 g: HashMap<i32, TestKP2>,
1788 }
1789
1790 impl TestKP {
1791 fn new() -> Self {
1792 Self {
1793 a: String::from("a"),
1794 b: String::from("b"),
1795 c: std::sync::Arc::new(String::from("c")),
1796 d: std::sync::Mutex::new(String::from("d")),
1797 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
1798 f: Some(TestKP2 {
1799 a: String::from("a3"),
1800 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1801 }),
1802 g: HashMap::new(),
1803 }
1804 }
1805
1806 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
1807 KpComposed::from_closures(
1808 move |r: &TestKP| r.g.get(&index),
1809 move |r: &mut TestKP| r.g.get_mut(&index),
1810 )
1811 }
1812
1813 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
1816 TestKP2,
1817 String,
1818 Root,
1819 Value,
1820 MutRoot,
1821 MutValue,
1822 impl Fn(Root) -> Option<Value>,
1823 impl Fn(MutRoot) -> Option<MutValue>,
1824 >
1825 where
1826 Root: std::borrow::Borrow<TestKP2>,
1827 MutRoot: std::borrow::BorrowMut<TestKP2>,
1828 Value: std::borrow::Borrow<String> + From<String>,
1829 MutValue: std::borrow::BorrowMut<String> + From<String>,
1830 {
1831 Kp::new(
1832 |r: Root| Some(Value::from(r.borrow().a.clone())),
1833 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
1834 )
1835 }
1836
1837 fn c<'a>() -> KpType<'a, TestKP, String> {
1840 KpType::new(
1841 |r: &TestKP| Some(r.c.as_ref()),
1842 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
1843 Some(arc_str) => Some(arc_str),
1844 None => None,
1845 },
1846 )
1847 }
1848
1849 fn a<'a>() -> KpType<'a, TestKP, String> {
1850 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
1851 }
1852
1853 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
1854 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
1855 }
1856
1857 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
1858 KpType::identity()
1859 }
1860 }
1861
1862 #[test]
1863 fn kp_debug_display_uses_type_names() {
1864 let kp = TestKP::a();
1865 let dbg = format!("{kp:?}");
1866 assert!(dbg.starts_with("Kp {"), "{dbg}");
1867 assert!(dbg.contains("root_ty") && dbg.contains("value_ty"), "{dbg}");
1868 let disp = format!("{kp}");
1869 assert!(disp.contains("TestKP"), "{disp}");
1870 assert!(disp.contains("String"), "{disp}");
1871 }
1872
1873 #[test]
1874 fn akp_and_pkp_debug_display() {
1875 let akp = AKp::new(TestKP::a());
1876 assert!(format!("{akp:?}").starts_with("AKp"));
1877 let pkp = PKp::new(TestKP::a());
1878 let pkp_dbg = format!("{pkp:?}");
1879 assert!(pkp_dbg.starts_with("PKp"), "{pkp_dbg}");
1880 assert!(format!("{pkp}").contains("TestKP"));
1881 }
1882
1883 #[test]
1884 fn enum_kp_debug_display() {
1885 let ok_kp = enum_ok::<i32, String>();
1886 assert!(format!("{ok_kp:?}").contains("EnumKp"));
1887 let s = format!("{ok_kp}");
1888 assert!(s.contains("Result") && s.contains("i32"), "{s}");
1889 }
1890
1891 #[test]
1892 fn composed_kp_into_dynamic_stores_as_kp_dynamic() {
1893 let path: KpDynamic<TestKP, String> = TestKP::f().then(TestKP2::a()).into_dynamic();
1894 let mut t = TestKP::new();
1895 assert_eq!(path.get(&t), Some(&"a3".to_string()));
1896 path.get_mut(&mut t).map(|s| *s = "x".into());
1897 assert_eq!(t.f.as_ref().unwrap().a, "x");
1898 }
1899
1900 #[derive(Debug)]
1901 struct TestKP2 {
1902 a: String,
1903 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
1904 }
1905
1906 impl TestKP2 {
1907 fn new() -> Self {
1908 TestKP2 {
1909 a: String::from("a2"),
1910 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1911 }
1912 }
1913
1914 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1915 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
1922 fn(MutRoot) -> Option<MutRoot>,
1923 >
1924 where
1925 Root: std::borrow::Borrow<TestKP2>,
1926 MutRoot: std::borrow::BorrowMut<TestKP2>,
1927 G: Fn(Root) -> Option<Root>,
1928 S: Fn(MutRoot) -> Option<MutRoot>,
1929 {
1930 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1931 }
1932
1933 fn a<'a>() -> KpType<'a, TestKP2, String> {
1934 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
1935 }
1936
1937 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
1938 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
1939 }
1940
1941 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
1946 KpType::identity()
1947 }
1948 }
1949
1950 #[derive(Debug)]
1951 struct TestKP3 {
1952 a: String,
1953 b: std::sync::Arc<std::sync::Mutex<String>>,
1954 }
1955
1956 impl TestKP3 {
1957 fn new() -> Self {
1958 TestKP3 {
1959 a: String::from("a2"),
1960 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
1961 }
1962 }
1963
1964 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1965 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
1972 fn(MutRoot) -> Option<MutRoot>,
1973 >
1974 where
1975 Root: std::borrow::Borrow<TestKP3>,
1976 MutRoot: std::borrow::BorrowMut<TestKP3>,
1977 G: Fn(Root) -> Option<Root>,
1978 S: Fn(MutRoot) -> Option<MutRoot>,
1979 {
1980 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1981 }
1982
1983 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
1984 KpType::identity()
1985 }
1986 }
1987
1988 impl TestKP3 {}
1989
1990 impl TestKP {}
1991 #[test]
1992 fn test_a() {
1993 let instance2 = TestKP2::new();
1994 let mut instance = TestKP::new();
1995 let kp = TestKP::identity();
1996 let kp_a = TestKP::a();
1997 let wres = TestKP::f()
1999 .then(TestKP2::a())
2000 .get_mut(&mut instance)
2001 .unwrap();
2002 *wres = String::from("a3 changed successfully");
2003 let res = (TestKP::f().then(TestKP2::a()).get)(&instance);
2004 println!("{:?}", res);
2005 let res = (TestKP::f().then(TestKP2::identity()).get)(&instance);
2006 println!("{:?}", res);
2007 let res = (kp.get)(&instance);
2008 println!("{:?}", res);
2009
2010 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2011 println!("{:?}", (new_kp_from_hashmap.get)(&instance));
2012 }
2013
2014 #[test]
2093 fn test_enum_kp_result_ok() {
2094 let ok_result: Result<String, i32> = Ok("success".to_string());
2095 let mut err_result: Result<String, i32> = Err(42);
2096
2097 let ok_kp = enum_ok();
2098
2099 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2101 assert_eq!(ok_kp.get(&err_result), None);
2102
2103 let embedded = ok_kp.embed("embedded".to_string());
2105 assert_eq!(embedded, Ok("embedded".to_string()));
2106
2107 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2109 *val = "modified".to_string();
2110 }
2111 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2114 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2115 *val = "modified".to_string();
2116 }
2117 assert_eq!(ok_result2, Ok("modified".to_string()));
2118 }
2119
2120 #[test]
2121 fn test_enum_kp_result_err() {
2122 let ok_result: Result<String, i32> = Ok("success".to_string());
2123 let mut err_result: Result<String, i32> = Err(42);
2124
2125 let err_kp = enum_err();
2126
2127 assert_eq!(err_kp.get(&err_result), Some(&42));
2129 assert_eq!(err_kp.get(&ok_result), None);
2130
2131 let embedded = err_kp.embed(99);
2133 assert_eq!(embedded, Err(99));
2134
2135 if let Some(val) = err_kp.get_mut(&mut err_result) {
2137 *val = 100;
2138 }
2139 assert_eq!(err_result, Err(100));
2140 }
2141
2142 #[test]
2143 fn test_enum_kp_option_some() {
2144 let some_opt = Some("value".to_string());
2145 let mut none_opt: Option<String> = None;
2146
2147 let some_kp = enum_some();
2148
2149 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2151 assert_eq!(some_kp.get(&none_opt), None);
2152
2153 let embedded = some_kp.embed("embedded".to_string());
2155 assert_eq!(embedded, Some("embedded".to_string()));
2156
2157 let mut some_opt2 = Some("original".to_string());
2159 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2160 *val = "modified".to_string();
2161 }
2162 assert_eq!(some_opt2, Some("modified".to_string()));
2163 }
2164
2165 #[test]
2166 fn test_enum_kp_custom_enum() {
2167 #[derive(Debug, PartialEq)]
2168 enum MyEnum {
2169 A(String),
2170 B(i32),
2171 C,
2172 }
2173
2174 let mut enum_a = MyEnum::A("hello".to_string());
2175 let enum_b = MyEnum::B(42);
2176 let enum_c = MyEnum::C;
2177
2178 let kp_a = enum_variant(
2180 |e: &MyEnum| match e {
2181 MyEnum::A(s) => Some(s),
2182 _ => None,
2183 },
2184 |e: &mut MyEnum| match e {
2185 MyEnum::A(s) => Some(s),
2186 _ => None,
2187 },
2188 |s: String| MyEnum::A(s),
2189 );
2190
2191 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2193 assert_eq!(kp_a.get(&enum_b), None);
2194 assert_eq!(kp_a.get(&enum_c), None);
2195
2196 let embedded = kp_a.embed("world".to_string());
2198 assert_eq!(embedded, MyEnum::A("world".to_string()));
2199
2200 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2202 *val = "modified".to_string();
2203 }
2204 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2205 }
2206
2207 #[test]
2208 fn test_container_kp_box() {
2209 let boxed = Box::new("value".to_string());
2210 let mut boxed_mut = Box::new("original".to_string());
2211
2212 let box_kp = kp_box();
2213
2214 assert_eq!((box_kp.get)(&boxed), Some(&"value".to_string()));
2216
2217 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2219 *val = "modified".to_string();
2220 }
2221 assert_eq!(*boxed_mut, "modified".to_string());
2222 }
2223
2224 #[test]
2225 fn test_container_kp_arc() {
2226 let arc = Arc::new("value".to_string());
2227 let mut arc_mut = Arc::new("original".to_string());
2228
2229 let arc_kp = kp_arc();
2230
2231 assert_eq!((arc_kp.get)(&arc), Some(&"value".to_string()));
2233
2234 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2236 *val = "modified".to_string();
2237 }
2238 assert_eq!(*arc_mut, "modified".to_string());
2239
2240 let arc_shared = Arc::new("shared".to_string());
2242 let arc_shared2 = Arc::clone(&arc_shared);
2243 let mut arc_shared_mut = arc_shared;
2244 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2245 }
2246
2247 #[test]
2248 fn test_enum_kp_composition() {
2249 #[derive(Debug, PartialEq)]
2251 struct Inner {
2252 value: String,
2253 }
2254
2255 let result: Result<Inner, i32> = Ok(Inner {
2256 value: "nested".to_string(),
2257 });
2258
2259 let inner_kp = KpType::new(
2261 |i: &Inner| Some(&i.value),
2262 |i: &mut Inner| Some(&mut i.value),
2263 );
2264
2265 let ok_kp = enum_ok::<Inner, i32>();
2267 let ok_kp_base = ok_kp.into_kp();
2268 let composed = ok_kp_base.then(inner_kp);
2269
2270 assert_eq!((composed.get)(&result), Some(&"nested".to_string()));
2271 }
2272
2273 #[cfg(feature = "nightly")]
2274 #[test]
2275 fn test_shr_operator_chains_keypaths() {
2276 use std::ops::Shr;
2277
2278 #[derive(Debug)]
2279 struct Inner {
2280 x: i32,
2281 }
2282 #[derive(Debug)]
2283 struct Outer {
2284 inner: Inner,
2285 }
2286
2287 let inner_x = KpType::new(|i: &Inner| Some(&i.x), |i: &mut Inner| Some(&mut i.x));
2288 let outer_inner =
2289 KpType::new(|o: &Outer| Some(&o.inner), |o: &mut Outer| Some(&mut o.inner));
2290 let via_shr = outer_inner >> inner_x;
2291
2292 let inner_x2 = KpType::new(|i: &Inner| Some(&i.x), |i: &mut Inner| Some(&mut i.x));
2293 let outer_inner2 =
2294 KpType::new(|o: &Outer| Some(&o.inner), |o: &mut Outer| Some(&mut o.inner));
2295 let via_then = outer_inner2.then(inner_x2);
2296
2297 let root = Outer {
2298 inner: Inner { x: 7 },
2299 };
2300 assert_eq!(via_then.get(&root), Some(&7));
2301 assert_eq!(via_shr.get(&root), Some(&7));
2302 }
2303
2304 #[test]
2305 fn test_pkp_basic() {
2306 #[derive(Debug)]
2307 struct User {
2308 name: String,
2309 age: i32,
2310 }
2311
2312 let user = User {
2313 name: "Akash".to_string(),
2314 age: 30,
2315 };
2316
2317 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2319 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2320
2321 let name_pkp = PKp::new(name_kp);
2323 let age_pkp = PKp::new(age_kp);
2324
2325 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Akash".to_string()));
2327 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2328
2329 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2331 assert_eq!(age_pkp.get_as::<String>(&user), None);
2332
2333 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2335 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2336 }
2337
2338 #[test]
2339 fn test_pkp_collection() {
2340 #[derive(Debug)]
2341 struct User {
2342 name: String,
2343 age: i32,
2344 }
2345
2346 let user = User {
2347 name: "Bob".to_string(),
2348 age: 25,
2349 };
2350
2351 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2353 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2354
2355 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2356
2357 let name_value = keypaths[0].get_as::<String>(&user);
2359 let age_value = keypaths[1].get_as::<i32>(&user);
2360
2361 assert_eq!(name_value, Some(&"Bob".to_string()));
2362 assert_eq!(age_value, Some(&25));
2363 }
2364
2365 #[test]
2366 fn test_pkp_for_arc() {
2367 #[derive(Debug)]
2368 struct User {
2369 name: String,
2370 }
2371
2372 let user = Arc::new(User {
2373 name: "Charlie".to_string(),
2374 });
2375
2376 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2377 let name_pkp = PKp::new(name_kp);
2378
2379 let arc_pkp = name_pkp.for_arc();
2381
2382 assert_eq!(
2383 arc_pkp.get_as::<String>(&user),
2384 Some(&"Charlie".to_string())
2385 );
2386 }
2387
2388 #[test]
2389 fn test_pkp_for_option() {
2390 #[derive(Debug)]
2391 struct User {
2392 name: String,
2393 }
2394
2395 let some_user = Some(User {
2396 name: "Diana".to_string(),
2397 });
2398 let none_user: Option<User> = None;
2399
2400 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2401 let name_pkp = PKp::new(name_kp);
2402
2403 let opt_pkp = name_pkp.for_option();
2405
2406 assert_eq!(
2407 opt_pkp.get_as::<String>(&some_user),
2408 Some(&"Diana".to_string())
2409 );
2410 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2411 }
2412
2413 #[test]
2414 fn test_akp_basic() {
2415 #[derive(Debug)]
2416 struct User {
2417 name: String,
2418 age: i32,
2419 }
2420
2421 #[derive(Debug)]
2422 struct Product {
2423 title: String,
2424 price: f64,
2425 }
2426
2427 let user = User {
2428 name: "Eve".to_string(),
2429 age: 28,
2430 };
2431
2432 let product = Product {
2433 title: "Book".to_string(),
2434 price: 19.99,
2435 };
2436
2437 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2439 let user_name_akp = AKp::new(user_name_kp);
2440
2441 let product_title_kp = KpType::new(
2442 |p: &Product| Some(&p.title),
2443 |p: &mut Product| Some(&mut p.title),
2444 );
2445 let product_title_akp = AKp::new(product_title_kp);
2446
2447 assert_eq!(
2449 user_name_akp.get_as::<User, String>(&user),
2450 Some(Some(&"Eve".to_string()))
2451 );
2452 assert_eq!(
2453 product_title_akp.get_as::<Product, String>(&product),
2454 Some(Some(&"Book".to_string()))
2455 );
2456
2457 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2459 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2460
2461 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2463 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2464 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2465 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2466 }
2467
2468 #[test]
2469 fn test_akp_heterogeneous_collection() {
2470 #[derive(Debug)]
2471 struct User {
2472 name: String,
2473 }
2474
2475 #[derive(Debug)]
2476 struct Product {
2477 title: String,
2478 }
2479
2480 let user = User {
2481 name: "Frank".to_string(),
2482 };
2483 let product = Product {
2484 title: "Laptop".to_string(),
2485 };
2486
2487 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2489 let product_title_kp = KpType::new(
2490 |p: &Product| Some(&p.title),
2491 |p: &mut Product| Some(&mut p.title),
2492 );
2493
2494 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2495
2496 let user_any: &dyn Any = &user;
2498 let product_any: &dyn Any = &product;
2499
2500 let user_value = keypaths[0].get(user_any);
2501 let product_value = keypaths[1].get(product_any);
2502
2503 assert!(user_value.is_some());
2504 assert!(product_value.is_some());
2505
2506 assert_eq!(
2508 user_value.and_then(|v| v.downcast_ref::<String>()),
2509 Some(&"Frank".to_string())
2510 );
2511 assert_eq!(
2512 product_value.and_then(|v| v.downcast_ref::<String>()),
2513 Some(&"Laptop".to_string())
2514 );
2515 }
2516
2517 #[test]
2518 fn test_akp_for_option() {
2519 #[derive(Debug)]
2520 struct User {
2521 name: String,
2522 }
2523
2524 let some_user = Some(User {
2525 name: "Grace".to_string(),
2526 });
2527 let none_user: Option<User> = None;
2528
2529 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2530 let name_akp = AKp::new(name_kp);
2531
2532 let opt_akp = name_akp.for_option::<User>();
2534
2535 assert_eq!(
2536 opt_akp.get_as::<Option<User>, String>(&some_user),
2537 Some(Some(&"Grace".to_string()))
2538 );
2539 assert_eq!(
2540 opt_akp.get_as::<Option<User>, String>(&none_user),
2541 Some(None)
2542 );
2543 }
2544
2545 #[test]
2546 fn test_akp_for_result() {
2547 #[derive(Debug)]
2548 struct User {
2549 name: String,
2550 }
2551
2552 let ok_user: Result<User, String> = Ok(User {
2553 name: "Henry".to_string(),
2554 });
2555 let err_user: Result<User, String> = Err("Not found".to_string());
2556
2557 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2558 let name_akp = AKp::new(name_kp);
2559
2560 let result_akp = name_akp.for_result::<User, String>();
2562
2563 assert_eq!(
2564 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2565 Some(Some(&"Henry".to_string()))
2566 );
2567 assert_eq!(
2568 result_akp.get_as::<Result<User, String>, String>(&err_user),
2569 Some(None)
2570 );
2571 }
2572
2573 #[test]
2576 fn test_kp_map() {
2577 #[derive(Debug)]
2578 struct User {
2579 name: String,
2580 age: i32,
2581 }
2582
2583 let user = User {
2584 name: "Akash".to_string(),
2585 age: 30,
2586 };
2587
2588 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2590 let len_kp = name_kp.map(|name: &String| name.len());
2591
2592 assert_eq!((len_kp.get)(&user), Some(5));
2593
2594 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2596 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2597
2598 assert_eq!((double_age_kp.get)(&user), Some(60));
2599
2600 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2602 assert_eq!((is_adult_kp.get)(&user), Some(true));
2603 }
2604
2605 #[test]
2606 fn test_kp_filter() {
2607 #[derive(Debug)]
2608 struct User {
2609 name: String,
2610 age: i32,
2611 }
2612
2613 let adult = User {
2614 name: "Akash".to_string(),
2615 age: 30,
2616 };
2617
2618 let minor = User {
2619 name: "Bob".to_string(),
2620 age: 15,
2621 };
2622
2623 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2624 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2625
2626 assert_eq!((adult_age_kp.get)(&adult), Some(&30));
2627 assert_eq!((adult_age_kp.get)(&minor), None);
2628
2629 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2631 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2632
2633 assert_eq!((short_name_kp.get)(&minor), Some(&"Bob".to_string()));
2634 assert_eq!((short_name_kp.get)(&adult), None);
2635 }
2636
2637 #[test]
2638 fn test_kp_map_and_filter() {
2639 #[derive(Debug)]
2640 struct User {
2641 scores: Vec<i32>,
2642 }
2643
2644 let user = User {
2645 scores: vec![85, 92, 78, 95],
2646 };
2647
2648 let scores_kp = KpType::new(
2649 |u: &User| Some(&u.scores),
2650 |u: &mut User| Some(&mut u.scores),
2651 );
2652
2653 let avg_kp =
2655 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2656
2657 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2659
2660 assert_eq!((high_avg_kp.get)(&user), Some(87)); }
2662
2663 #[test]
2664 fn test_enum_kp_map() {
2665 let ok_result: Result<String, i32> = Ok("hello".to_string());
2666 let err_result: Result<String, i32> = Err(42);
2667
2668 let ok_kp = enum_ok::<String, i32>();
2669 let len_kp = ok_kp.map(|s: &String| s.len());
2670
2671 assert_eq!(len_kp.get(&ok_result), Some(5));
2672 assert_eq!(len_kp.get(&err_result), None);
2673
2674 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2676 let none_opt: Option<Vec<i32>> = None;
2677
2678 let some_kp = enum_some::<Vec<i32>>();
2679 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2680
2681 assert_eq!(count_kp.get(&some_opt), Some(5));
2682 assert_eq!(count_kp.get(&none_opt), None);
2683 }
2684
2685 #[test]
2686 fn test_enum_kp_filter() {
2687 let ok_result1: Result<i32, String> = Ok(42);
2688 let ok_result2: Result<i32, String> = Ok(-5);
2689 let err_result: Result<i32, String> = Err("error".to_string());
2690
2691 let ok_kp = enum_ok::<i32, String>();
2692 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2693
2694 assert_eq!((positive_kp.extractor.get)(&ok_result1), Some(&42));
2695 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2700 let short_str = Some("hi".to_string());
2701
2702 let some_kp = enum_some::<String>();
2703 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2704
2705 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2706 assert_eq!(long_kp.get(&short_str), None);
2707 }
2708
2709 #[test]
2710 fn test_pkp_filter() {
2711 #[derive(Debug)]
2712 struct User {
2713 name: String,
2714 age: i32,
2715 }
2716
2717 let adult = User {
2718 name: "Akash".to_string(),
2719 age: 30,
2720 };
2721
2722 let minor = User {
2723 name: "Bob".to_string(),
2724 age: 15,
2725 };
2726
2727 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2728 let age_pkp = PKp::new(age_kp);
2729
2730 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2732
2733 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2734 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2735
2736 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2738 let name_pkp = PKp::new(name_kp);
2739 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2740
2741 assert_eq!(
2742 short_name_pkp.get_as::<String>(&minor),
2743 Some(&"Bob".to_string())
2744 );
2745 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2746 }
2747
2748 #[test]
2749 fn test_akp_filter() {
2750 #[derive(Debug)]
2751 struct User {
2752 age: i32,
2753 }
2754
2755 #[derive(Debug)]
2756 struct Product {
2757 price: f64,
2758 }
2759
2760 let adult = User { age: 30 };
2761 let minor = User { age: 15 };
2762 let expensive = Product { price: 99.99 };
2763 let cheap = Product { price: 5.0 };
2764
2765 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2767 let age_akp = AKp::new(age_kp);
2768 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2769
2770 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2771 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2772
2773 let price_kp = KpType::new(
2775 |p: &Product| Some(&p.price),
2776 |p: &mut Product| Some(&mut p.price),
2777 );
2778 let price_akp = AKp::new(price_kp);
2779 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2780
2781 assert_eq!(
2782 expensive_akp.get_as::<Product, f64>(&expensive),
2783 Some(Some(&99.99))
2784 );
2785 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2786 }
2787
2788 #[test]
2791 fn test_kp_filter_map() {
2792 #[derive(Debug)]
2793 struct User {
2794 middle_name: Option<String>,
2795 }
2796
2797 let user_with = User {
2798 middle_name: Some("Marie".to_string()),
2799 };
2800 let user_without = User { middle_name: None };
2801
2802 let middle_kp = KpType::new(
2803 |u: &User| Some(&u.middle_name),
2804 |u: &mut User| Some(&mut u.middle_name),
2805 );
2806
2807 let first_char_kp = middle_kp
2808 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
2809
2810 assert_eq!((first_char_kp.get)(&user_with), Some('M'));
2811 assert_eq!((first_char_kp.get)(&user_without), None);
2812 }
2813
2814 #[test]
2815 fn test_kp_inspect() {
2816 #[derive(Debug)]
2817 struct User {
2818 name: String,
2819 }
2820
2821 let user = User {
2822 name: "Akash".to_string(),
2823 };
2824
2825 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2829
2830 let result = (name_kp.get)(&user);
2833 assert_eq!(result, Some(&"Akash".to_string()));
2834
2835 }
2838
2839 #[test]
2840 fn test_kp_fold_value() {
2841 #[derive(Debug)]
2842 struct User {
2843 scores: Vec<i32>,
2844 }
2845
2846 let user = User {
2847 scores: vec![85, 92, 78, 95],
2848 };
2849
2850 let scores_kp = KpType::new(
2851 |u: &User| Some(&u.scores),
2852 |u: &mut User| Some(&mut u.scores),
2853 );
2854
2855 let sum_fn =
2857 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
2858
2859 assert_eq!(sum_fn(&user), 350);
2860 }
2861
2862 #[test]
2863 fn test_kp_any_all() {
2864 #[derive(Debug)]
2865 struct User {
2866 scores: Vec<i32>,
2867 }
2868
2869 let user_high = User {
2870 scores: vec![85, 92, 88],
2871 };
2872 let user_mixed = User {
2873 scores: vec![65, 92, 78],
2874 };
2875
2876 let scores_kp = KpType::new(
2877 |u: &User| Some(&u.scores),
2878 |u: &mut User| Some(&mut u.scores),
2879 );
2880
2881 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
2883 assert!(has_high_fn(&user_high));
2884 assert!(has_high_fn(&user_mixed));
2885
2886 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
2888 assert!(all_passing_fn(&user_high));
2889 assert!(!all_passing_fn(&user_mixed));
2890 }
2891
2892 #[test]
2893 fn test_kp_count_items() {
2894 #[derive(Debug)]
2895 struct User {
2896 tags: Vec<String>,
2897 }
2898
2899 let user = User {
2900 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
2901 };
2902
2903 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2904 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
2905
2906 assert_eq!(count_fn(&user), Some(3));
2907 }
2908
2909 #[test]
2910 fn test_kp_find_in() {
2911 #[derive(Debug)]
2912 struct User {
2913 scores: Vec<i32>,
2914 }
2915
2916 let user = User {
2917 scores: vec![85, 92, 78, 95, 88],
2918 };
2919
2920 let scores_kp = KpType::new(
2921 |u: &User| Some(&u.scores),
2922 |u: &mut User| Some(&mut u.scores),
2923 );
2924
2925 let first_high_fn =
2927 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
2928
2929 assert_eq!(first_high_fn(&user), Some(92));
2930
2931 let perfect_fn =
2933 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
2934
2935 assert_eq!(perfect_fn(&user), None);
2936 }
2937
2938 #[test]
2939 fn test_kp_take_skip() {
2940 #[derive(Debug)]
2941 struct User {
2942 tags: Vec<String>,
2943 }
2944
2945 let user = User {
2946 tags: vec![
2947 "a".to_string(),
2948 "b".to_string(),
2949 "c".to_string(),
2950 "d".to_string(),
2951 ],
2952 };
2953
2954 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2955
2956 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
2958 tags.iter().take(n).cloned().collect::<Vec<_>>()
2959 });
2960
2961 let taken = take_fn(&user).unwrap();
2962 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
2963
2964 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
2966 tags.iter().skip(n).cloned().collect::<Vec<_>>()
2967 });
2968
2969 let skipped = skip_fn(&user).unwrap();
2970 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
2971 }
2972
2973 #[test]
2974 fn test_kp_partition() {
2975 #[derive(Debug)]
2976 struct User {
2977 scores: Vec<i32>,
2978 }
2979
2980 let user = User {
2981 scores: vec![85, 92, 65, 95, 72, 58],
2982 };
2983
2984 let scores_kp = KpType::new(
2985 |u: &User| Some(&u.scores),
2986 |u: &mut User| Some(&mut u.scores),
2987 );
2988
2989 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
2990 scores.iter().copied().partition(|&s| s >= 70)
2991 });
2992
2993 let (passing, failing) = partition_fn(&user).unwrap();
2994 assert_eq!(passing, vec![85, 92, 95, 72]);
2995 assert_eq!(failing, vec![65, 58]);
2996 }
2997
2998 #[test]
2999 fn test_kp_min_max() {
3000 #[derive(Debug)]
3001 struct User {
3002 scores: Vec<i32>,
3003 }
3004
3005 let user = User {
3006 scores: vec![85, 92, 78, 95, 88],
3007 };
3008
3009 let scores_kp = KpType::new(
3010 |u: &User| Some(&u.scores),
3011 |u: &mut User| Some(&mut u.scores),
3012 );
3013
3014 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3016 assert_eq!(min_fn(&user), Some(78));
3017
3018 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3020 assert_eq!(max_fn(&user), Some(95));
3021 }
3022
3023 #[test]
3024 fn test_kp_sum() {
3025 #[derive(Debug)]
3026 struct User {
3027 scores: Vec<i32>,
3028 }
3029
3030 let user = User {
3031 scores: vec![85, 92, 78],
3032 };
3033
3034 let scores_kp = KpType::new(
3035 |u: &User| Some(&u.scores),
3036 |u: &mut User| Some(&mut u.scores),
3037 );
3038
3039 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3040 assert_eq!(sum_fn(&user), Some(255));
3041
3042 let avg_fn =
3044 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3045 assert_eq!(avg_fn.get(&user), Some(85));
3046 }
3047
3048 #[test]
3049 fn test_kp_chain() {
3050 #[derive(Debug)]
3051 struct User {
3052 profile: Profile,
3053 }
3054
3055 #[derive(Debug)]
3056 struct Profile {
3057 settings: Settings,
3058 }
3059
3060 #[derive(Debug)]
3061 struct Settings {
3062 theme: String,
3063 }
3064
3065 let user = User {
3066 profile: Profile {
3067 settings: Settings {
3068 theme: "dark".to_string(),
3069 },
3070 },
3071 };
3072
3073 let profile_kp = KpType::new(
3074 |u: &User| Some(&u.profile),
3075 |u: &mut User| Some(&mut u.profile),
3076 );
3077 let settings_kp = KpType::new(
3078 |p: &Profile| Some(&p.settings),
3079 |p: &mut Profile| Some(&mut p.settings),
3080 );
3081 let theme_kp = KpType::new(
3082 |s: &Settings| Some(&s.theme),
3083 |s: &mut Settings| Some(&mut s.theme),
3084 );
3085
3086 let profile_settings = profile_kp.then(settings_kp);
3088 let theme_path = profile_settings.then(theme_kp);
3089 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3090 }
3091
3092 #[test]
3093 fn test_kp_zip() {
3094 #[derive(Debug)]
3095 struct User {
3096 name: String,
3097 age: i32,
3098 }
3099
3100 let user = User {
3101 name: "Akash".to_string(),
3102 age: 30,
3103 };
3104
3105 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3106 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3107
3108 let zipped_fn = zip_kps(&name_kp, &age_kp);
3109 let result = zipped_fn(&user);
3110
3111 assert_eq!(result, Some((&"Akash".to_string(), &30)));
3112 }
3113
3114 #[test]
3115 fn test_kp_complex_pipeline() {
3116 #[derive(Debug)]
3117 struct User {
3118 transactions: Vec<Transaction>,
3119 }
3120
3121 #[derive(Debug)]
3122 struct Transaction {
3123 amount: f64,
3124 category: String,
3125 }
3126
3127 let user = User {
3128 transactions: vec![
3129 Transaction {
3130 amount: 50.0,
3131 category: "food".to_string(),
3132 },
3133 Transaction {
3134 amount: 100.0,
3135 category: "transport".to_string(),
3136 },
3137 Transaction {
3138 amount: 25.0,
3139 category: "food".to_string(),
3140 },
3141 Transaction {
3142 amount: 200.0,
3143 category: "shopping".to_string(),
3144 },
3145 ],
3146 };
3147
3148 let txns_kp = KpType::new(
3149 |u: &User| Some(&u.transactions),
3150 |u: &mut User| Some(&mut u.transactions),
3151 );
3152
3153 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3155 txns.iter()
3156 .filter(|t| t.category == "food")
3157 .map(|t| t.amount)
3158 .sum::<f64>()
3159 });
3160
3161 assert_eq!(food_total.get(&user), Some(75.0));
3162
3163 let has_large =
3165 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3166
3167 assert!(has_large(&user));
3168
3169 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3171 assert_eq!(count(&user), Some(4));
3172 }
3173
3174 #[test]
3178 fn test_no_clone_required_for_root() {
3179 use std::sync::Arc;
3180 use std::sync::atomic::{AtomicUsize, Ordering};
3181
3182 struct NonCloneableRoot {
3185 data: Arc<AtomicUsize>,
3186 cached_value: usize,
3187 }
3188
3189 impl NonCloneableRoot {
3190 fn new() -> Self {
3191 Self {
3192 data: Arc::new(AtomicUsize::new(42)),
3193 cached_value: 42,
3194 }
3195 }
3196
3197 fn increment(&mut self) {
3198 self.data.fetch_add(1, Ordering::SeqCst);
3199 self.cached_value = self.data.load(Ordering::SeqCst);
3200 }
3201
3202 fn get_value(&self) -> &usize {
3203 &self.cached_value
3204 }
3205
3206 fn get_value_mut(&mut self) -> &mut usize {
3207 &mut self.cached_value
3208 }
3209 }
3210
3211 let mut root = NonCloneableRoot::new();
3212
3213 let data_kp = KpType::new(
3215 |r: &NonCloneableRoot| Some(r.get_value()),
3216 |r: &mut NonCloneableRoot| {
3217 r.increment();
3218 Some(r.get_value_mut())
3219 },
3220 );
3221
3222 assert_eq!(data_kp.get(&root), Some(&42));
3224
3225 {
3226 let doubled = data_kp.map(|val: &usize| val * 2);
3228 assert_eq!(doubled.get(&root), Some(84));
3229
3230 let filtered = data_kp.filter(|val: &usize| *val > 0);
3232 assert_eq!(filtered.get(&root), Some(&42));
3233 } let value_ref = data_kp.get_mut(&mut root);
3237 assert!(value_ref.is_some());
3238 }
3239
3240 #[test]
3241 fn test_no_clone_required_for_value() {
3242 use std::sync::Arc;
3243 use std::sync::atomic::{AtomicUsize, Ordering};
3244
3245 struct NonCloneableValue {
3247 counter: Arc<AtomicUsize>,
3248 }
3249
3250 impl NonCloneableValue {
3251 fn new(val: usize) -> Self {
3252 Self {
3253 counter: Arc::new(AtomicUsize::new(val)),
3254 }
3255 }
3256
3257 fn get(&self) -> usize {
3258 self.counter.load(Ordering::SeqCst)
3259 }
3260 }
3261
3262 struct Root {
3263 value: NonCloneableValue,
3264 }
3265
3266 let root = Root {
3267 value: NonCloneableValue::new(100),
3268 };
3269
3270 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3272
3273 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3275 assert_eq!(counter_kp.get(&root), Some(100));
3276
3277 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3279 assert!(filtered.get(&root).is_some());
3280 }
3281
3282 #[test]
3283 fn test_static_does_not_leak_memory() {
3284 use std::sync::Arc;
3285 use std::sync::atomic::{AtomicUsize, Ordering};
3286
3287 static CREATED: AtomicUsize = AtomicUsize::new(0);
3289 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3290
3291 struct Tracked {
3292 id: usize,
3293 }
3294
3295 impl Tracked {
3296 fn new() -> Self {
3297 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3298 Self { id }
3299 }
3300 }
3301
3302 impl Drop for Tracked {
3303 fn drop(&mut self) {
3304 DROPPED.fetch_add(1, Ordering::SeqCst);
3305 }
3306 }
3307
3308 struct Root {
3309 data: Tracked,
3310 }
3311
3312 CREATED.store(0, Ordering::SeqCst);
3314 DROPPED.store(0, Ordering::SeqCst);
3315
3316 {
3317 let root = Root {
3318 data: Tracked::new(),
3319 };
3320
3321 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3322
3323 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3325 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3326 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3327
3328 assert_eq!(mapped1.get(&root), Some(0));
3329 assert_eq!(mapped2.get(&root), Some(1));
3330 assert_eq!(mapped3.get(&root), Some(2));
3331
3332 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3334 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3335 }
3336
3337 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3339 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3340
3341 }
3343
3344 #[test]
3345 fn test_references_not_cloned() {
3346 use std::sync::Arc;
3347
3348 struct ExpensiveData {
3350 large_vec: Vec<u8>,
3351 }
3352
3353 impl ExpensiveData {
3354 fn new(size: usize) -> Self {
3355 Self {
3356 large_vec: vec![0u8; size],
3357 }
3358 }
3359
3360 fn size(&self) -> usize {
3361 self.large_vec.len()
3362 }
3363 }
3364
3365 struct Root {
3366 expensive: ExpensiveData,
3367 }
3368
3369 let root = Root {
3370 expensive: ExpensiveData::new(1_000_000), };
3372
3373 let expensive_kp = KpType::new(
3374 |r: &Root| Some(&r.expensive),
3375 |r: &mut Root| Some(&mut r.expensive),
3376 );
3377
3378 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3380 assert_eq!(size_kp.get(&root), Some(1_000_000));
3381
3382 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3384 assert!(large_filter.get(&root).is_some());
3385
3386 }
3388
3389 #[test]
3390 fn test_hof_with_arc_no_extra_clones() {
3391 use std::sync::Arc;
3392
3393 #[derive(Debug)]
3394 struct SharedData {
3395 value: String,
3396 }
3397
3398 struct Root {
3399 shared: Arc<SharedData>,
3400 }
3401
3402 let shared = Arc::new(SharedData {
3403 value: "shared".to_string(),
3404 });
3405
3406 assert_eq!(Arc::strong_count(&shared), 1);
3408
3409 {
3410 let root = Root {
3411 shared: Arc::clone(&shared),
3412 };
3413
3414 assert_eq!(Arc::strong_count(&shared), 2);
3416
3417 let shared_kp = KpType::new(
3418 |r: &Root| Some(&r.shared),
3419 |r: &mut Root| Some(&mut r.shared),
3420 );
3421
3422 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3424
3425 assert_eq!(value_kp.get(&root), Some(6));
3427 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3431 assert!(filtered.get(&root).is_some());
3432 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3437
3438 #[test]
3439 fn test_closure_captures_not_root_values() {
3440 use std::sync::Arc;
3441 use std::sync::atomic::{AtomicUsize, Ordering};
3442
3443 let call_count = Arc::new(AtomicUsize::new(0));
3445 let call_count_clone = Arc::clone(&call_count);
3446
3447 struct Root {
3448 value: i32,
3449 }
3450
3451 let root = Root { value: 42 };
3452
3453 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3454
3455 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3458 call_count_clone.fetch_add(1, Ordering::SeqCst);
3459 v * 2
3460 });
3461
3462 assert_eq!(doubled(&root), 84);
3464 assert_eq!(doubled(&root), 84);
3465 assert_eq!(doubled(&root), 84);
3466
3467 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3469
3470 }
3472
3473 #[test]
3474 fn test_static_with_borrowed_data() {
3475 struct Root {
3479 data: String,
3480 }
3481
3482 {
3483 let root = Root {
3484 data: "temporary".to_string(),
3485 };
3486
3487 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3488
3489 let len_kp = data_kp.map(|s: &String| s.len());
3491 assert_eq!(len_kp.get(&root), Some(9));
3492
3493 } }
3498
3499 #[test]
3500 fn test_multiple_hof_operations_no_accumulation() {
3501 use std::sync::Arc;
3502 use std::sync::atomic::{AtomicUsize, Ordering};
3503
3504 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3505
3506 struct Tracked {
3507 id: usize,
3508 }
3509
3510 impl Drop for Tracked {
3511 fn drop(&mut self) {
3512 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3513 }
3514 }
3515
3516 struct Root {
3517 values: Vec<Tracked>,
3518 }
3519
3520 DROP_COUNT.store(0, Ordering::SeqCst);
3521
3522 {
3523 let root = Root {
3524 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3525 };
3526
3527 let values_kp = KpType::new(
3528 |r: &Root| Some(&r.values),
3529 |r: &mut Root| Some(&mut r.values),
3530 );
3531
3532 let count = values_kp.count_items(|v| v.len());
3534 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3535 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3536 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3537
3538 assert_eq!(count(&root), Some(3));
3539 assert_eq!(sum(&root), Some(6));
3540 assert!(has_2(&root));
3541 assert!(all_positive(&root));
3542
3543 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3545 }
3546
3547 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3549 }
3550
3551 #[test]
3552 fn test_copy_bound_only_for_function_not_data() {
3553 #[derive(Debug)]
3557 struct NonCopyData {
3558 value: String,
3559 }
3560
3561 struct Root {
3562 data: NonCopyData,
3563 }
3564
3565 let root = Root {
3566 data: NonCopyData {
3567 value: "test".to_string(),
3568 },
3569 };
3570
3571 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3572
3573 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3576 assert_eq!(len_kp.get(&root), Some(4));
3577
3578 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3580 assert!(filtered.get(&root).is_some());
3581 }
3582
3583 #[test]
3584 fn test_no_memory_leak_with_cyclic_references() {
3585 use std::sync::atomic::{AtomicUsize, Ordering};
3586 use std::sync::{Arc, Weak};
3587
3588 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3589
3590 struct Node {
3591 id: usize,
3592 parent: Option<Weak<Node>>,
3593 }
3594
3595 impl Drop for Node {
3596 fn drop(&mut self) {
3597 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3598 }
3599 }
3600
3601 struct Root {
3602 node: Arc<Node>,
3603 }
3604
3605 DROP_COUNT.store(0, Ordering::SeqCst);
3606
3607 {
3608 let root = Root {
3609 node: Arc::new(Node {
3610 id: 1,
3611 parent: None,
3612 }),
3613 };
3614
3615 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3616
3617 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3619 assert_eq!(id_kp.get(&root), Some(1));
3620
3621 assert_eq!(Arc::strong_count(&root.node), 1);
3623
3624 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3626 }
3627
3628 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3630 }
3631
3632 #[test]
3633 fn test_hof_operations_are_zero_cost_abstractions() {
3634 struct Root {
3638 value: i32,
3639 }
3640
3641 let root = Root { value: 10 };
3642
3643 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3644
3645 let direct_result = value_kp.get(&root).map(|v| v * 2);
3647 assert_eq!(direct_result, Some(20));
3648
3649 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3651 let hof_result = mapped_kp.get(&root);
3652 assert_eq!(hof_result, Some(20));
3653
3654 assert_eq!(direct_result, hof_result);
3656 }
3657
3658 #[test]
3659 fn test_complex_closure_captures_allowed() {
3660 use std::sync::Arc;
3661
3662 struct Root {
3664 scores: Vec<i32>,
3665 }
3666
3667 let root = Root {
3668 scores: vec![85, 92, 78, 95, 88],
3669 };
3670
3671 let scores_kp = KpType::new(
3672 |r: &Root| Some(&r.scores),
3673 |r: &mut Root| Some(&mut r.scores),
3674 );
3675
3676 let threshold = 90;
3678 let multiplier = Arc::new(2);
3679
3680 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3682 let high: i32 = scores
3683 .iter()
3684 .filter(|&&s| s >= threshold)
3685 .map(|&s| s * *multiplier)
3686 .sum();
3687 acc + high
3688 });
3689
3690 assert_eq!(high_scores_doubled(&root), 374);
3692 }
3693
3694 #[test]
3698 fn test_pkp_filter_by_value_type() {
3699 use std::any::TypeId;
3700
3701 #[derive(Debug)]
3702 struct User {
3703 name: String,
3704 age: i32,
3705 score: f64,
3706 active: bool,
3707 }
3708
3709 let user = User {
3710 name: "Akash".to_string(),
3711 age: 30,
3712 score: 95.5,
3713 active: true,
3714 };
3715
3716 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3718 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3719 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3720 let active_kp = KpType::new(
3721 |u: &User| Some(&u.active),
3722 |u: &mut User| Some(&mut u.active),
3723 );
3724
3725 let all_keypaths: Vec<PKp<User>> = vec![
3727 PKp::new(name_kp),
3728 PKp::new(age_kp),
3729 PKp::new(score_kp),
3730 PKp::new(active_kp),
3731 ];
3732
3733 let string_kps: Vec<_> = all_keypaths
3735 .iter()
3736 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3737 .collect();
3738
3739 assert_eq!(string_kps.len(), 1);
3740 assert_eq!(
3741 string_kps[0].get_as::<String>(&user),
3742 Some(&"Akash".to_string())
3743 );
3744
3745 let i32_kps: Vec<_> = all_keypaths
3747 .iter()
3748 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3749 .collect();
3750
3751 assert_eq!(i32_kps.len(), 1);
3752 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3753
3754 let f64_kps: Vec<_> = all_keypaths
3756 .iter()
3757 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3758 .collect();
3759
3760 assert_eq!(f64_kps.len(), 1);
3761 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3762
3763 let bool_kps: Vec<_> = all_keypaths
3765 .iter()
3766 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3767 .collect();
3768
3769 assert_eq!(bool_kps.len(), 1);
3770 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3771 }
3772
3773 #[test]
3774 fn test_pkp_filter_by_struct_type() {
3775 use std::any::TypeId;
3776
3777 #[derive(Debug, PartialEq)]
3778 struct Address {
3779 street: String,
3780 city: String,
3781 }
3782
3783 #[derive(Debug)]
3784 struct User {
3785 name: String,
3786 age: i32,
3787 address: Address,
3788 }
3789
3790 let user = User {
3791 name: "Bob".to_string(),
3792 age: 25,
3793 address: Address {
3794 street: "123 Main St".to_string(),
3795 city: "NYC".to_string(),
3796 },
3797 };
3798
3799 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3801 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3802 let address_kp = KpType::new(
3803 |u: &User| Some(&u.address),
3804 |u: &mut User| Some(&mut u.address),
3805 );
3806
3807 let all_keypaths: Vec<PKp<User>> =
3808 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
3809
3810 let struct_kps: Vec<_> = all_keypaths
3812 .iter()
3813 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
3814 .collect();
3815
3816 assert_eq!(struct_kps.len(), 1);
3817 assert_eq!(
3818 struct_kps[0].get_as::<Address>(&user),
3819 Some(&Address {
3820 street: "123 Main St".to_string(),
3821 city: "NYC".to_string(),
3822 })
3823 );
3824
3825 let primitive_kps: Vec<_> = all_keypaths
3827 .iter()
3828 .filter(|pkp| {
3829 pkp.value_type_id() == TypeId::of::<String>()
3830 || pkp.value_type_id() == TypeId::of::<i32>()
3831 })
3832 .collect();
3833
3834 assert_eq!(primitive_kps.len(), 2);
3835 }
3836
3837 #[test]
3838 fn test_pkp_filter_by_arc_type() {
3839 use std::any::TypeId;
3840 use std::sync::Arc;
3841
3842 #[derive(Debug)]
3843 struct User {
3844 name: String,
3845 shared_data: Arc<String>,
3846 shared_number: Arc<i32>,
3847 }
3848
3849 let user = User {
3850 name: "Charlie".to_string(),
3851 shared_data: Arc::new("shared".to_string()),
3852 shared_number: Arc::new(42),
3853 };
3854
3855 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3857 let shared_data_kp = KpType::new(
3858 |u: &User| Some(&u.shared_data),
3859 |u: &mut User| Some(&mut u.shared_data),
3860 );
3861 let shared_number_kp = KpType::new(
3862 |u: &User| Some(&u.shared_number),
3863 |u: &mut User| Some(&mut u.shared_number),
3864 );
3865
3866 let all_keypaths: Vec<PKp<User>> = vec![
3867 PKp::new(name_kp),
3868 PKp::new(shared_data_kp),
3869 PKp::new(shared_number_kp),
3870 ];
3871
3872 let arc_string_kps: Vec<_> = all_keypaths
3874 .iter()
3875 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
3876 .collect();
3877
3878 assert_eq!(arc_string_kps.len(), 1);
3879 assert_eq!(
3880 arc_string_kps[0]
3881 .get_as::<Arc<String>>(&user)
3882 .map(|arc| arc.as_str()),
3883 Some("shared")
3884 );
3885
3886 let arc_i32_kps: Vec<_> = all_keypaths
3888 .iter()
3889 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
3890 .collect();
3891
3892 assert_eq!(arc_i32_kps.len(), 1);
3893 assert_eq!(
3894 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
3895 Some(42)
3896 );
3897
3898 let all_arc_kps: Vec<_> = all_keypaths
3900 .iter()
3901 .filter(|pkp| {
3902 pkp.value_type_id() == TypeId::of::<Arc<String>>()
3903 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
3904 })
3905 .collect();
3906
3907 assert_eq!(all_arc_kps.len(), 2);
3908 }
3909
3910 #[test]
3911 fn test_pkp_filter_by_box_type() {
3912 use std::any::TypeId;
3913
3914 #[derive(Debug)]
3915 struct User {
3916 name: String,
3917 boxed_value: Box<i32>,
3918 boxed_string: Box<String>,
3919 }
3920
3921 let user = User {
3922 name: "Diana".to_string(),
3923 boxed_value: Box::new(100),
3924 boxed_string: Box::new("boxed".to_string()),
3925 };
3926
3927 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3929 let boxed_value_kp = KpType::new(
3930 |u: &User| Some(&u.boxed_value),
3931 |u: &mut User| Some(&mut u.boxed_value),
3932 );
3933 let boxed_string_kp = KpType::new(
3934 |u: &User| Some(&u.boxed_string),
3935 |u: &mut User| Some(&mut u.boxed_string),
3936 );
3937
3938 let all_keypaths: Vec<PKp<User>> = vec![
3939 PKp::new(name_kp),
3940 PKp::new(boxed_value_kp),
3941 PKp::new(boxed_string_kp),
3942 ];
3943
3944 let box_i32_kps: Vec<_> = all_keypaths
3946 .iter()
3947 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
3948 .collect();
3949
3950 assert_eq!(box_i32_kps.len(), 1);
3951 assert_eq!(
3952 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
3953 Some(100)
3954 );
3955
3956 let box_string_kps: Vec<_> = all_keypaths
3958 .iter()
3959 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
3960 .collect();
3961
3962 assert_eq!(box_string_kps.len(), 1);
3963 assert_eq!(
3964 box_string_kps[0]
3965 .get_as::<Box<String>>(&user)
3966 .map(|b| b.as_str()),
3967 Some("boxed")
3968 );
3969 }
3970
3971 #[test]
3972 fn test_akp_filter_by_root_and_value_type() {
3973 use std::any::TypeId;
3974
3975 #[derive(Debug)]
3976 struct User {
3977 name: String,
3978 age: i32,
3979 }
3980
3981 #[derive(Debug)]
3982 struct Product {
3983 title: String,
3984 price: f64,
3985 }
3986
3987 let user = User {
3988 name: "Eve".to_string(),
3989 age: 28,
3990 };
3991
3992 let product = Product {
3993 title: "Book".to_string(),
3994 price: 19.99,
3995 };
3996
3997 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3999 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4000 let product_title_kp = KpType::new(
4001 |p: &Product| Some(&p.title),
4002 |p: &mut Product| Some(&mut p.title),
4003 );
4004 let product_price_kp = KpType::new(
4005 |p: &Product| Some(&p.price),
4006 |p: &mut Product| Some(&mut p.price),
4007 );
4008
4009 let all_keypaths: Vec<AKp> = vec![
4010 AKp::new(user_name_kp),
4011 AKp::new(user_age_kp),
4012 AKp::new(product_title_kp),
4013 AKp::new(product_price_kp),
4014 ];
4015
4016 let user_kps: Vec<_> = all_keypaths
4018 .iter()
4019 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4020 .collect();
4021
4022 assert_eq!(user_kps.len(), 2);
4023
4024 let product_kps: Vec<_> = all_keypaths
4026 .iter()
4027 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4028 .collect();
4029
4030 assert_eq!(product_kps.len(), 2);
4031
4032 let string_value_kps: Vec<_> = all_keypaths
4034 .iter()
4035 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4036 .collect();
4037
4038 assert_eq!(string_value_kps.len(), 2);
4039
4040 let user_string_kps: Vec<_> = all_keypaths
4042 .iter()
4043 .filter(|akp| {
4044 akp.root_type_id() == TypeId::of::<User>()
4045 && akp.value_type_id() == TypeId::of::<String>()
4046 })
4047 .collect();
4048
4049 assert_eq!(user_string_kps.len(), 1);
4050 assert_eq!(
4051 user_string_kps[0].get_as::<User, String>(&user),
4052 Some(Some(&"Eve".to_string()))
4053 );
4054
4055 let product_f64_kps: Vec<_> = all_keypaths
4057 .iter()
4058 .filter(|akp| {
4059 akp.root_type_id() == TypeId::of::<Product>()
4060 && akp.value_type_id() == TypeId::of::<f64>()
4061 })
4062 .collect();
4063
4064 assert_eq!(product_f64_kps.len(), 1);
4065 assert_eq!(
4066 product_f64_kps[0].get_as::<Product, f64>(&product),
4067 Some(Some(&19.99))
4068 );
4069 }
4070
4071 #[test]
4072 fn test_akp_filter_by_arc_root_type() {
4073 use std::any::TypeId;
4074 use std::sync::Arc;
4075
4076 #[derive(Debug)]
4077 struct User {
4078 name: String,
4079 }
4080
4081 #[derive(Debug)]
4082 struct Product {
4083 title: String,
4084 }
4085
4086 let user = User {
4087 name: "Frank".to_string(),
4088 };
4089 let product = Product {
4090 title: "Laptop".to_string(),
4091 };
4092
4093 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4095 let product_title_kp = KpType::new(
4096 |p: &Product| Some(&p.title),
4097 |p: &mut Product| Some(&mut p.title),
4098 );
4099
4100 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4102 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4103
4104 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4105
4106 let arc_user_kps: Vec<_> = all_keypaths
4108 .iter()
4109 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4110 .collect();
4111
4112 assert_eq!(arc_user_kps.len(), 1);
4113
4114 let arc_user = Arc::new(user);
4116 assert_eq!(
4117 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4118 Some(Some(&"Frank".to_string()))
4119 );
4120
4121 let arc_product_kps: Vec<_> = all_keypaths
4123 .iter()
4124 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4125 .collect();
4126
4127 assert_eq!(arc_product_kps.len(), 1);
4128
4129 let arc_product = Arc::new(product);
4131 assert_eq!(
4132 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4133 Some(Some(&"Laptop".to_string()))
4134 );
4135 }
4136
4137 #[test]
4138 fn test_akp_filter_by_box_root_type() {
4139 use std::any::TypeId;
4140
4141 #[derive(Debug)]
4142 struct Config {
4143 setting: String,
4144 }
4145
4146 let config = Config {
4147 setting: "enabled".to_string(),
4148 };
4149
4150 let config_kp1 = KpType::new(
4152 |c: &Config| Some(&c.setting),
4153 |c: &mut Config| Some(&mut c.setting),
4154 );
4155 let config_kp2 = KpType::new(
4156 |c: &Config| Some(&c.setting),
4157 |c: &mut Config| Some(&mut c.setting),
4158 );
4159
4160 let regular_akp = AKp::new(config_kp1);
4162 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4163
4164 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4165
4166 let config_kps: Vec<_> = all_keypaths
4168 .iter()
4169 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4170 .collect();
4171
4172 assert_eq!(config_kps.len(), 1);
4173 assert_eq!(
4174 config_kps[0].get_as::<Config, String>(&config),
4175 Some(Some(&"enabled".to_string()))
4176 );
4177
4178 let box_config_kps: Vec<_> = all_keypaths
4180 .iter()
4181 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4182 .collect();
4183
4184 assert_eq!(box_config_kps.len(), 1);
4185
4186 let box_config = Box::new(Config {
4188 setting: "enabled".to_string(),
4189 });
4190 assert_eq!(
4191 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4192 Some(Some(&"enabled".to_string()))
4193 );
4194 }
4195
4196 #[test]
4197 fn test_mixed_collection_type_filtering() {
4198 use std::any::TypeId;
4199 use std::sync::Arc;
4200
4201 #[derive(Debug)]
4202 struct User {
4203 name: String,
4204 email: String,
4205 }
4206
4207 #[derive(Debug)]
4208 struct Product {
4209 title: String,
4210 sku: String,
4211 }
4212
4213 let user = User {
4214 name: "Grace".to_string(),
4215 email: "grace@example.com".to_string(),
4216 };
4217
4218 let product = Product {
4219 title: "Widget".to_string(),
4220 sku: "WID-001".to_string(),
4221 };
4222
4223 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4225 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4226 let user_email_kp1 =
4227 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4228 let user_email_kp2 =
4229 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4230 let product_title_kp = KpType::new(
4231 |p: &Product| Some(&p.title),
4232 |p: &mut Product| Some(&mut p.title),
4233 );
4234 let product_sku_kp = KpType::new(
4235 |p: &Product| Some(&p.sku),
4236 |p: &mut Product| Some(&mut p.sku),
4237 );
4238
4239 let all_keypaths: Vec<AKp> = vec![
4240 AKp::new(user_name_kp1),
4241 AKp::new(user_email_kp1),
4242 AKp::new(product_title_kp),
4243 AKp::new(product_sku_kp),
4244 AKp::new(user_name_kp2).for_arc::<User>(),
4245 AKp::new(user_email_kp2).for_box::<User>(),
4246 ];
4247
4248 let string_value_kps: Vec<_> = all_keypaths
4250 .iter()
4251 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4252 .collect();
4253
4254 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4258 .iter()
4259 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4260 .collect();
4261
4262 assert_eq!(user_root_kps.len(), 2);
4263
4264 let arc_user_kps: Vec<_> = all_keypaths
4266 .iter()
4267 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4268 .collect();
4269
4270 assert_eq!(arc_user_kps.len(), 1);
4271
4272 let box_user_kps: Vec<_> = all_keypaths
4274 .iter()
4275 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4276 .collect();
4277
4278 assert_eq!(box_user_kps.len(), 1);
4279
4280 let product_kps: Vec<_> = all_keypaths
4282 .iter()
4283 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4284 .collect();
4285
4286 assert_eq!(product_kps.len(), 2);
4287
4288 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4290 assert!(user_value.is_some());
4291 assert!(user_value.unwrap().is_some());
4292 }
4293
4294 #[test]
4299 fn test_kp_with_pin() {
4300 use std::pin::Pin;
4301
4302 #[derive(Debug)]
4306 struct SelfReferential {
4307 value: String,
4308 ptr_to_value: *const String, }
4310
4311 impl SelfReferential {
4312 fn new(s: String) -> Self {
4313 let mut sr = Self {
4314 value: s,
4315 ptr_to_value: std::ptr::null(),
4316 };
4317 sr.ptr_to_value = &sr.value as *const String;
4319 sr
4320 }
4321
4322 fn get_value(&self) -> &str {
4323 &self.value
4324 }
4325 }
4326
4327 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4329 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4330
4331 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4333 |p: &Pin<Box<SelfReferential>>| {
4334 Some(&p.as_ref().get_ref().value)
4336 },
4337 |p: &mut Pin<Box<SelfReferential>>| {
4338 unsafe {
4341 let sr = Pin::get_unchecked_mut(p.as_mut());
4342 Some(&mut sr.value)
4343 }
4344 },
4345 );
4346
4347 let result = kp.get(&pinned);
4349 assert_eq!(result, Some(&"pinned_data".to_string()));
4350
4351 assert_eq!(pinned.get_value(), "pinned_data");
4353 }
4354
4355 #[test]
4356 fn test_kp_with_pin_arc() {
4357 use std::pin::Pin;
4358 use std::sync::Arc;
4359
4360 struct AsyncState {
4361 status: String,
4362 data: Vec<i32>,
4363 }
4364
4365 let state = AsyncState {
4367 status: "ready".to_string(),
4368 data: vec![1, 2, 3, 4, 5],
4369 };
4370
4371 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4372
4373 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4375 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4376 |_: &mut Pin<Arc<AsyncState>>| {
4377 None::<&mut String>
4379 },
4380 );
4381
4382 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4384 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4385 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4386 );
4387
4388 let status = status_kp.get(&pinned_arc);
4389 assert_eq!(status, Some(&"ready".to_string()));
4390
4391 let data = data_kp.get(&pinned_arc);
4392 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4393 }
4394
4395 #[test]
4396 fn test_kp_with_maybe_uninit() {
4397 use std::mem::MaybeUninit;
4398
4399 struct Config {
4403 name: MaybeUninit<String>,
4404 value: MaybeUninit<i32>,
4405 initialized: bool,
4406 }
4407
4408 impl Config {
4409 fn new_uninit() -> Self {
4410 Self {
4411 name: MaybeUninit::uninit(),
4412 value: MaybeUninit::uninit(),
4413 initialized: false,
4414 }
4415 }
4416
4417 fn init(&mut self, name: String, value: i32) {
4418 self.name.write(name);
4419 self.value.write(value);
4420 self.initialized = true;
4421 }
4422
4423 fn get_name(&self) -> Option<&String> {
4424 if self.initialized {
4425 unsafe { Some(self.name.assume_init_ref()) }
4426 } else {
4427 None
4428 }
4429 }
4430
4431 fn get_value(&self) -> Option<&i32> {
4432 if self.initialized {
4433 unsafe { Some(self.value.assume_init_ref()) }
4434 } else {
4435 None
4436 }
4437 }
4438 }
4439
4440 let name_kp: KpType<Config, String> = Kp::new(
4442 |c: &Config| c.get_name(),
4443 |c: &mut Config| {
4444 if c.initialized {
4445 unsafe { Some(c.name.assume_init_mut()) }
4446 } else {
4447 None
4448 }
4449 },
4450 );
4451
4452 let value_kp: KpType<Config, i32> = Kp::new(
4453 |c: &Config| c.get_value(),
4454 |c: &mut Config| {
4455 if c.initialized {
4456 unsafe { Some(c.value.assume_init_mut()) }
4457 } else {
4458 None
4459 }
4460 },
4461 );
4462
4463 let uninit_config = Config::new_uninit();
4465 assert_eq!(name_kp.get(&uninit_config), None);
4466 assert_eq!(value_kp.get(&uninit_config), None);
4467
4468 let mut init_config = Config::new_uninit();
4470 init_config.init("test_config".to_string(), 42);
4471
4472 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4473 assert_eq!(value_kp.get(&init_config), Some(&42));
4474
4475 if let Some(val) = value_kp.get_mut(&mut init_config) {
4477 *val = 100;
4478 }
4479
4480 assert_eq!(value_kp.get(&init_config), Some(&100));
4481 }
4482
4483 #[test]
4484 fn test_kp_with_weak() {
4485 use std::sync::{Arc, Weak};
4486
4487 #[derive(Debug, Clone)]
4491 struct Node {
4492 value: i32,
4493 }
4494
4495 struct NodeWithParent {
4496 value: i32,
4497 parent: Option<Arc<Node>>, }
4499
4500 let parent = Arc::new(Node { value: 100 });
4501
4502 let child = NodeWithParent {
4503 value: 42,
4504 parent: Some(parent.clone()),
4505 };
4506
4507 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4509 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4510 |_: &mut NodeWithParent| None::<&mut i32>,
4511 );
4512
4513 let parent_val = parent_value_kp.get(&child);
4515 assert_eq!(parent_val, Some(&100));
4516 }
4517
4518 #[test]
4519 fn test_kp_with_rc_weak() {
4520 use std::rc::Rc;
4521
4522 struct TreeNode {
4525 value: String,
4526 parent: Option<Rc<TreeNode>>, }
4528
4529 let root = Rc::new(TreeNode {
4530 value: "root".to_string(),
4531 parent: None,
4532 });
4533
4534 let child1 = TreeNode {
4535 value: "child1".to_string(),
4536 parent: Some(root.clone()),
4537 };
4538
4539 let child2 = TreeNode {
4540 value: "child2".to_string(),
4541 parent: Some(root.clone()),
4542 };
4543
4544 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4546 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4547 |_: &mut TreeNode| None::<&mut String>,
4548 );
4549
4550 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4552 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4553
4554 assert_eq!(parent_name_kp.get(&root), None);
4556 }
4557
4558 #[test]
4559 fn test_kp_with_complex_weak_structure() {
4560 use std::sync::Arc;
4561
4562 struct Cache {
4565 data: String,
4566 backup: Option<Arc<Cache>>, }
4568
4569 let primary = Arc::new(Cache {
4570 data: "primary_data".to_string(),
4571 backup: None,
4572 });
4573
4574 let backup = Arc::new(Cache {
4575 data: "backup_data".to_string(),
4576 backup: Some(primary.clone()),
4577 });
4578
4579 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4581 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4582 |_: &mut Arc<Cache>| None::<&mut String>,
4583 );
4584
4585 let data = backup_data_kp.get(&backup);
4587 assert_eq!(data, Some(&"primary_data".to_string()));
4588
4589 let no_backup = backup_data_kp.get(&primary);
4591 assert_eq!(no_backup, None);
4592 }
4593
4594 #[test]
4595 fn test_kp_chain_with_pin_and_arc() {
4596 use std::pin::Pin;
4597 use std::sync::Arc;
4598
4599 struct Outer {
4602 inner: Arc<Inner>,
4603 }
4604
4605 struct Inner {
4606 value: String,
4607 }
4608
4609 let outer = Outer {
4610 inner: Arc::new(Inner {
4611 value: "nested_value".to_string(),
4612 }),
4613 };
4614
4615 let pinned_outer = Box::pin(outer);
4616
4617 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4619 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4620 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4621 );
4622
4623 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4625 |a: &Arc<Inner>| Some(&a.value),
4626 |_: &mut Arc<Inner>| None::<&mut String>,
4627 );
4628
4629 let chained = to_inner.then(to_value);
4631
4632 let result = chained.get(&pinned_outer);
4633 assert_eq!(result, Some(&"nested_value".to_string()));
4634 }
4635
4636 #[test]
4637 fn test_kp_with_maybe_uninit_array() {
4638 use std::mem::MaybeUninit;
4639
4640 struct Buffer {
4644 data: [MaybeUninit<u8>; 10],
4645 len: usize,
4646 }
4647
4648 impl Buffer {
4649 fn new() -> Self {
4650 Self {
4651 data: unsafe { MaybeUninit::uninit().assume_init() },
4652 len: 0,
4653 }
4654 }
4655
4656 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4657 if self.len >= self.data.len() {
4658 return Err("Buffer full");
4659 }
4660 self.data[self.len].write(byte);
4661 self.len += 1;
4662 Ok(())
4663 }
4664
4665 fn get(&self, idx: usize) -> Option<&u8> {
4666 if idx < self.len {
4667 unsafe { Some(self.data[idx].assume_init_ref()) }
4668 } else {
4669 None
4670 }
4671 }
4672
4673 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4674 if idx < self.len {
4675 unsafe { Some(self.data[idx].assume_init_mut()) }
4676 } else {
4677 None
4678 }
4679 }
4680 }
4681
4682 let len_kp: KpType<Buffer, usize> =
4684 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4685
4686 let mut buffer = Buffer::new();
4687
4688 assert_eq!(len_kp.get(&buffer), Some(&0));
4690
4691 buffer.push(1).unwrap();
4693 buffer.push(2).unwrap();
4694 buffer.push(3).unwrap();
4695
4696 assert_eq!(len_kp.get(&buffer), Some(&3));
4698
4699 assert_eq!(buffer.get(0), Some(&1));
4701 assert_eq!(buffer.get(1), Some(&2));
4702 assert_eq!(buffer.get(2), Some(&3));
4703 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4707 *elem = 20;
4708 }
4709 assert_eq!(buffer.get(1), Some(&20));
4710 }
4711
4712 #[test]
4713 fn test_kp_then_sync_deep_structs() {
4714 use std::sync::{Arc, Mutex};
4715
4716 #[derive(Clone)]
4717 struct Root {
4718 guard: Arc<Mutex<Level1>>,
4719 }
4720 #[derive(Clone)]
4721 struct Level1 {
4722 name: String,
4723 nested: Level2,
4724 }
4725 #[derive(Clone)]
4726 struct Level2 {
4727 count: i32,
4728 }
4729
4730 let root = Root {
4731 guard: Arc::new(Mutex::new(Level1 {
4732 name: "deep".to_string(),
4733 nested: Level2 { count: 42 },
4734 })),
4735 };
4736
4737 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4738 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4739
4740 let lock_kp = {
4741 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> = Kp::new(
4742 |g: &Arc<Mutex<Level1>>| Some(g),
4743 |g: &mut Arc<Mutex<Level1>>| Some(g),
4744 );
4745 let next: KpType<Level1, Level1> =
4746 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4747 crate::sync_kp::SyncKp::new(prev, crate::sync_kp::ArcMutexAccess::new(), next)
4748 };
4749
4750 let chained = kp_to_guard.then_sync(lock_kp);
4751 let level1 = chained.get(&root);
4752 assert!(level1.is_some());
4753 assert_eq!(level1.unwrap().name, "deep");
4754 assert_eq!(level1.unwrap().nested.count, 42);
4755
4756 let mut_root = &mut root.clone();
4757 let mut_level1 = chained.get_mut(mut_root);
4758 assert!(mut_level1.is_some());
4759 mut_level1.unwrap().nested.count = 99;
4760 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4761 }
4762
4763 #[test]
4764 fn test_kp_then_sync_with_enum() {
4765 use std::sync::{Arc, Mutex};
4766
4767 #[derive(Clone)]
4768 enum Message {
4769 Request(LevelA),
4770 Response(i32),
4771 }
4772 #[derive(Clone)]
4773 struct LevelA {
4774 data: Arc<Mutex<i32>>,
4775 }
4776
4777 struct RootWithEnum {
4778 msg: Arc<Mutex<Message>>,
4779 }
4780
4781 let root = RootWithEnum {
4782 msg: Arc::new(Mutex::new(Message::Request(LevelA {
4783 data: Arc::new(Mutex::new(100)),
4784 }))),
4785 };
4786
4787 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> = Kp::new(
4788 |r: &RootWithEnum| Some(&r.msg),
4789 |r: &mut RootWithEnum| Some(&mut r.msg),
4790 );
4791
4792 let lock_kp_msg = {
4793 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> = Kp::new(
4794 |m: &Arc<Mutex<Message>>| Some(m),
4795 |m: &mut Arc<Mutex<Message>>| Some(m),
4796 );
4797 let next: KpType<Message, Message> =
4798 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4799 crate::sync_kp::SyncKp::new(prev, crate::sync_kp::ArcMutexAccess::new(), next)
4800 };
4801
4802 let chained = kp_msg.then_sync(lock_kp_msg);
4803 let msg = chained.get(&root);
4804 assert!(msg.is_some());
4805 match msg.unwrap() {
4806 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
4807 Message::Response(_) => panic!("expected Request"),
4808 }
4809 }
4810
4811 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4812 #[tokio::test]
4813 async fn test_kp_then_async_deep_chain() {
4814 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4815 use std::sync::Arc;
4816
4817 #[derive(Clone)]
4818 struct Root {
4819 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
4820 }
4821 #[derive(Clone)]
4822 struct Level1 {
4823 value: i32,
4824 }
4825
4826 let root = Root {
4827 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
4828 };
4829
4830 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
4831 |r: &Root| Some(&r.tokio_guard),
4832 |r: &mut Root| Some(&mut r.tokio_guard),
4833 );
4834
4835 let async_kp = {
4836 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
4837 Kp::new(
4838 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
4839 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
4840 );
4841 let next: KpType<Level1, Level1> =
4842 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4843 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4844 };
4845
4846 let chained = kp_to_guard.then_async(async_kp);
4847 let level1 = chained.get(&root).await;
4848 assert!(level1.is_some());
4849 assert_eq!(level1.unwrap().value, 7);
4850 }
4851
4852 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4855 #[tokio::test]
4856 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
4857 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4858 use crate::sync_kp::{ArcMutexAccess, SyncKp};
4859 use std::sync::{Arc, Mutex};
4860
4861 #[derive(Clone)]
4863 struct Root {
4864 sync_mutex: Arc<Mutex<Level1>>,
4865 }
4866 #[derive(Clone)]
4868 struct Level1 {
4869 inner: Level2,
4870 }
4871 #[derive(Clone)]
4873 struct Level2 {
4874 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
4875 }
4876 #[derive(Clone)]
4878 struct Level3 {
4879 leaf: i32,
4880 }
4881
4882 let mut root = Root {
4883 sync_mutex: Arc::new(Mutex::new(Level1 {
4884 inner: Level2 {
4885 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
4886 },
4887 })),
4888 };
4889
4890 let identity_l1: KpType<Level1, Level1> =
4892 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4893 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
4894 |r: &Root| Some(&r.sync_mutex),
4895 |r: &mut Root| Some(&mut r.sync_mutex),
4896 );
4897 let lock_root_to_l1 = SyncKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
4898
4899 let kp_l1_inner: KpType<Level1, Level2> = Kp::new(
4901 |l: &Level1| Some(&l.inner),
4902 |l: &mut Level1| Some(&mut l.inner),
4903 );
4904
4905 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
4907 |l: &Level2| Some(&l.tokio_mutex),
4908 |l: &mut Level2| Some(&mut l.tokio_mutex),
4909 );
4910
4911 let async_l3 = {
4913 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
4914 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
4915 let next: KpType<Level3, Level3> =
4916 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
4917 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4918 };
4919
4920 let kp_l3_leaf: KpType<Level3, i32> = Kp::new(
4922 |l: &Level3| Some(&l.leaf),
4923 |l: &mut Level3| Some(&mut l.leaf),
4924 );
4925
4926 let step1 = lock_root_to_l1.then(kp_l1_inner);
4928 let step2 = step1.then(kp_l2_tokio);
4929 let step3 = step2.then_async(async_l3);
4930 let deep_chain = step3.then(kp_l3_leaf);
4931
4932 let leaf = deep_chain.get(&root).await;
4934 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
4935 assert_eq!(leaf, Some(&100));
4936
4937 let mut root_mut = root.clone();
4939 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
4940 assert!(leaf_mut.is_some());
4941 *leaf_mut.unwrap() = 99;
4942
4943 let leaf_after = deep_chain.get(&root_mut).await;
4945 assert_eq!(leaf_after, Some(&99));
4946 }
4947}