1use std::sync::{Arc, Mutex};
14
15pub mod lock;
17pub use lock::{
18 ArcMutexAccess, ArcRwLockAccess, LockAccess, LockKp, LockKpType, RcRefCellAccess,
19 StdMutexAccess, StdRwLockAccess,
20};
21
22#[cfg(feature = "parking_lot")]
23pub use lock::{
24 DirectParkingLotMutexAccess, DirectParkingLotRwLockAccess, ParkingLotMutexAccess,
25 ParkingLotRwLockAccess,
26};
27
28pub mod async_lock;
30
31pub trait KeyPathValueTarget {
35 type Target: Sized;
36}
37impl<T> KeyPathValueTarget for &T {
38 type Target = T;
39}
40impl<T> KeyPathValueTarget for &mut T {
41 type Target = T;
42}
43
44pub type KpDynamic<R, V> = Kp<
45 R,
46 V,
47 &'static R,
48 &'static V,
49 &'static mut R,
50 &'static mut V,
51 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V>>,
52 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V>>,
53>;
54
55pub type KpType<'a, R, V> = Kp<
56 R,
57 V,
58 &'a R,
59 &'a V,
60 &'a mut R,
61 &'a mut V,
62 for<'b> fn(&'b R) -> Option<&'b V>,
63 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
64>;
65
66pub type KpComposed<R, V> = Kp<
102 R,
103 V,
104 &'static R,
105 &'static V,
106 &'static mut R,
107 &'static mut V,
108 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V>>,
109 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V>>,
110>;
111
112impl<R, V> Kp<
113 R,
114 V,
115 &'static R,
116 &'static V,
117 &'static mut R,
118 &'static mut V,
119 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V>>,
120 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V>>,
121> {
122 pub fn from_closures<G, S>(get: G, set: S) -> Self
125 where
126 G: for<'b> Fn(&'b R) -> Option<&'b V> + 'static,
127 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + 'static,
128 {
129 Self::new(Box::new(get), Box::new(set))
130 }
131}
132
133pub struct AKp {
134 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
135 root_type_id: TypeId,
136 value_type_id: TypeId,
137}
138
139impl AKp {
140 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
142 where
143 R: Any + 'static,
144 V: Any + 'static,
145 {
146 let root_type_id = TypeId::of::<R>();
147 let value_type_id = TypeId::of::<V>();
148 let getter_fn = keypath.get;
149
150 Self {
151 getter: Rc::new(move |any: &dyn Any| {
152 if let Some(root) = any.downcast_ref::<R>() {
153 getter_fn(root).map(|value: &V| value as &dyn Any)
154 } else {
155 None
156 }
157 }),
158 root_type_id,
159 value_type_id,
160 }
161 }
162
163 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
165 where
166 R: Any + 'static,
167 V: Any + 'static,
168 {
169 Self::new(keypath)
170 }
171
172 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
174 (self.getter)(root)
175 }
176
177 pub fn root_type_id(&self) -> TypeId {
179 self.root_type_id
180 }
181
182 pub fn value_type_id(&self) -> TypeId {
184 self.value_type_id
185 }
186
187 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
189 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
190 {
191 Some(
192 self.get(root as &dyn Any)
193 .and_then(|any| any.downcast_ref::<Value>()),
194 )
195 } else {
196 None
197 }
198 }
199
200 pub fn kind_name(&self) -> String {
202 format!("{:?}", self.value_type_id)
203 }
204
205 pub fn root_kind_name(&self) -> String {
207 format!("{:?}", self.root_type_id)
208 }
209
210 pub fn for_arc<Root>(&self) -> AKp
212 where
213 Root: Any + 'static,
214 {
215 let value_type_id = self.value_type_id;
216 let getter = self.getter.clone();
217
218 AKp {
219 getter: Rc::new(move |any: &dyn Any| {
220 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
221 getter(arc.as_ref() as &dyn Any)
222 } else {
223 None
224 }
225 }),
226 root_type_id: TypeId::of::<Arc<Root>>(),
227 value_type_id,
228 }
229 }
230
231 pub fn for_box<Root>(&self) -> AKp
233 where
234 Root: Any + 'static,
235 {
236 let value_type_id = self.value_type_id;
237 let getter = self.getter.clone();
238
239 AKp {
240 getter: Rc::new(move |any: &dyn Any| {
241 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
242 getter(boxed.as_ref() as &dyn Any)
243 } else {
244 None
245 }
246 }),
247 root_type_id: TypeId::of::<Box<Root>>(),
248 value_type_id,
249 }
250 }
251
252 pub fn for_rc<Root>(&self) -> AKp
254 where
255 Root: Any + 'static,
256 {
257 let value_type_id = self.value_type_id;
258 let getter = self.getter.clone();
259
260 AKp {
261 getter: Rc::new(move |any: &dyn Any| {
262 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
263 getter(rc.as_ref() as &dyn Any)
264 } else {
265 None
266 }
267 }),
268 root_type_id: TypeId::of::<Rc<Root>>(),
269 value_type_id,
270 }
271 }
272
273 pub fn for_option<Root>(&self) -> AKp
275 where
276 Root: Any + 'static,
277 {
278 let value_type_id = self.value_type_id;
279 let getter = self.getter.clone();
280
281 AKp {
282 getter: Rc::new(move |any: &dyn Any| {
283 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
284 opt.as_ref().and_then(|root| getter(root as &dyn Any))
285 } else {
286 None
287 }
288 }),
289 root_type_id: TypeId::of::<Option<Root>>(),
290 value_type_id,
291 }
292 }
293
294 pub fn for_result<Root, E>(&self) -> AKp
296 where
297 Root: Any + 'static,
298 E: Any + 'static,
299 {
300 let value_type_id = self.value_type_id;
301 let getter = self.getter.clone();
302
303 AKp {
304 getter: Rc::new(move |any: &dyn Any| {
305 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
306 result
307 .as_ref()
308 .ok()
309 .and_then(|root| getter(root as &dyn Any))
310 } else {
311 None
312 }
313 }),
314 root_type_id: TypeId::of::<Result<Root, E>>(),
315 value_type_id,
316 }
317 }
318
319 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
330 where
331 Root: Any + 'static,
332 OrigValue: Any + 'static,
333 MappedValue: Any + 'static,
334 F: Fn(&OrigValue) -> MappedValue + 'static,
335 {
336 let orig_root_type_id = self.root_type_id;
337 let orig_value_type_id = self.value_type_id;
338 let getter = self.getter.clone();
339 let mapped_type_id = TypeId::of::<MappedValue>();
340
341 AKp {
342 getter: Rc::new(move |any_root: &dyn Any| {
343 if any_root.type_id() == orig_root_type_id {
345 getter(any_root).and_then(|any_value| {
346 if orig_value_type_id == TypeId::of::<OrigValue>() {
348 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
349 let mapped = mapper(orig_val);
350 Box::leak(Box::new(mapped)) as &dyn Any
352 })
353 } else {
354 None
355 }
356 })
357 } else {
358 None
359 }
360 }),
361 root_type_id: orig_root_type_id,
362 value_type_id: mapped_type_id,
363 }
364 }
365
366 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
377 where
378 Root: Any + 'static,
379 Value: Any + 'static,
380 F: Fn(&Value) -> bool + 'static,
381 {
382 let orig_root_type_id = self.root_type_id;
383 let orig_value_type_id = self.value_type_id;
384 let getter = self.getter.clone();
385
386 AKp {
387 getter: Rc::new(move |any_root: &dyn Any| {
388 if any_root.type_id() == orig_root_type_id {
390 getter(any_root).filter(|any_value| {
391 if orig_value_type_id == TypeId::of::<Value>() {
393 any_value
394 .downcast_ref::<Value>()
395 .map(|val| predicate(val))
396 .unwrap_or(false)
397 } else {
398 false
399 }
400 })
401 } else {
402 None
403 }
404 }),
405 root_type_id: orig_root_type_id,
406 value_type_id: orig_value_type_id,
407 }
408 }
409}
410pub struct PKp<Root> {
411 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
412 value_type_id: TypeId,
413 _phantom: std::marker::PhantomData<Root>,
414}
415
416impl<Root> PKp<Root>
417where
418 Root: 'static,
419{
420 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
422 where
423 V: Any + 'static,
424 {
425 let value_type_id = TypeId::of::<V>();
426 let getter_fn = keypath.get;
427
428 Self {
429 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
430 value_type_id,
431 _phantom: std::marker::PhantomData,
432 }
433 }
434
435 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
437 where
438 V: Any + 'static,
439 {
440 Self::new(keypath)
441 }
442
443 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
445 (self.getter)(root)
446 }
447
448 pub fn value_type_id(&self) -> TypeId {
450 self.value_type_id
451 }
452
453 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
455 if self.value_type_id == TypeId::of::<Value>() {
456 self.get(root).and_then(|any| any.downcast_ref::<Value>())
457 } else {
458 None
459 }
460 }
461
462 pub fn kind_name(&self) -> String {
464 format!("{:?}", self.value_type_id)
465 }
466
467 pub fn for_arc(&self) -> PKp<Arc<Root>> {
469 let getter = self.getter.clone();
470 let value_type_id = self.value_type_id;
471
472 PKp {
473 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
474 value_type_id,
475 _phantom: std::marker::PhantomData,
476 }
477 }
478
479 pub fn for_box(&self) -> PKp<Box<Root>> {
481 let getter = self.getter.clone();
482 let value_type_id = self.value_type_id;
483
484 PKp {
485 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
486 value_type_id,
487 _phantom: std::marker::PhantomData,
488 }
489 }
490
491 pub fn for_rc(&self) -> PKp<Rc<Root>> {
493 let getter = self.getter.clone();
494 let value_type_id = self.value_type_id;
495
496 PKp {
497 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
498 value_type_id,
499 _phantom: std::marker::PhantomData,
500 }
501 }
502
503 pub fn for_option(&self) -> PKp<Option<Root>> {
505 let getter = self.getter.clone();
506 let value_type_id = self.value_type_id;
507
508 PKp {
509 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
510 value_type_id,
511 _phantom: std::marker::PhantomData,
512 }
513 }
514
515 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
517 where
518 E: 'static,
519 {
520 let getter = self.getter.clone();
521 let value_type_id = self.value_type_id;
522
523 PKp {
524 getter: Rc::new(move |result: &Result<Root, E>| {
525 result.as_ref().ok().and_then(|root| getter(root))
526 }),
527 value_type_id,
528 _phantom: std::marker::PhantomData,
529 }
530 }
531
532 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
544 where
545 OrigValue: Any + 'static,
546 MappedValue: Any + 'static,
547 F: Fn(&OrigValue) -> MappedValue + 'static,
548 {
549 let orig_type_id = self.value_type_id;
550 let getter = self.getter.clone();
551 let mapped_type_id = TypeId::of::<MappedValue>();
552
553 PKp {
554 getter: Rc::new(move |root: &Root| {
555 getter(root).and_then(|any_value| {
556 if orig_type_id == TypeId::of::<OrigValue>() {
558 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
559 let mapped = mapper(orig_val);
560 Box::leak(Box::new(mapped)) as &dyn Any
563 })
564 } else {
565 None
566 }
567 })
568 }),
569 value_type_id: mapped_type_id,
570 _phantom: std::marker::PhantomData,
571 }
572 }
573
574 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
586 where
587 Value: Any + 'static,
588 F: Fn(&Value) -> bool + 'static,
589 {
590 let orig_type_id = self.value_type_id;
591 let getter = self.getter.clone();
592
593 PKp {
594 getter: Rc::new(move |root: &Root| {
595 getter(root).filter(|any_value| {
596 if orig_type_id == TypeId::of::<Value>() {
598 any_value
599 .downcast_ref::<Value>()
600 .map(|val| predicate(val))
601 .unwrap_or(false)
602 } else {
603 false
604 }
605 })
606 }),
607 value_type_id: orig_type_id,
608 _phantom: std::marker::PhantomData,
609 }
610 }
611}
612
613#[derive(Clone)]
627pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
628where
629 Root: std::borrow::Borrow<R>,
630 MutRoot: std::borrow::BorrowMut<R>,
631 MutValue: std::borrow::BorrowMut<V>,
632 G: Fn(Root) -> Option<Value>,
633 S: Fn(MutRoot) -> Option<MutValue>,
634{
635 pub get: G,
637 pub set: S,
639 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
640}
641
642impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
643where
644 Root: std::borrow::Borrow<R>,
645 Value: std::borrow::Borrow<V>,
646 MutRoot: std::borrow::BorrowMut<R>,
647 MutValue: std::borrow::BorrowMut<V>,
648 G: Fn(Root) -> Option<Value>,
649 S: Fn(MutRoot) -> Option<MutValue>,
650{
651 pub fn new(get: G, set: S) -> Self {
652 Self {
653 get: get,
654 set: set,
655 _p: std::marker::PhantomData,
656 }
657 }
658
659 #[inline]
660 pub fn get(&self, root: Root) -> Option<Value> {
661 (self.get)(root)
662 }
663 #[inline]
664 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
665 (self.set)(root)
666 }
667
668 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
669 &self,
670 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
671 ) -> Kp<
672 R,
673 SV,
674 Root,
675 SubValue,
676 MutRoot,
677 MutSubValue,
678 impl Fn(Root) -> Option<SubValue>,
682 impl Fn(MutRoot) -> Option<MutSubValue>,
683 >
684 where
685 SubValue: std::borrow::Borrow<SV>,
686 MutSubValue: std::borrow::BorrowMut<SV>,
687 G2: Fn(Value) -> Option<SubValue>,
688 S2: Fn(MutValue) -> Option<MutSubValue>,
689 V: 'static,
690 {
691 Kp::new(
692 move |root: Root| (&self.get)(root).and_then(|value| (next.get)(value)),
693 move |root: MutRoot| (&self.set)(root).and_then(|value| (next.set)(value)),
694 )
695 }
696
697 pub fn then_lock<
699 Lock,
700 Mid,
701 V2,
702 LockValue,
703 MidValue,
704 Value2,
705 MutLock,
706 MutMid,
707 MutValue2,
708 G1,
709 S1,
710 L,
711 G2,
712 S2,
713 >(
714 self,
715 lock_kp: crate::lock::LockKp<
716 V,
717 Lock,
718 Mid,
719 V2,
720 Value,
721 LockValue,
722 MidValue,
723 Value2,
724 MutValue,
725 MutLock,
726 MutMid,
727 MutValue2,
728 G1,
729 S1,
730 L,
731 G2,
732 S2,
733 >,
734 ) -> crate::lock::KpThenLockKp<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, Self, crate::lock::LockKp<V, Lock, Mid, V2, Value, LockValue, MidValue, Value2, MutValue, MutLock, MutMid, MutValue2, G1, S1, L, G2, S2>>
735 where
736 V: 'static + Clone,
737 V2: 'static,
738 Value: std::borrow::Borrow<V>,
739 Value2: std::borrow::Borrow<V2>,
740 MutValue: std::borrow::BorrowMut<V>,
741 MutValue2: std::borrow::BorrowMut<V2>,
742 LockValue: std::borrow::Borrow<Lock>,
743 MidValue: std::borrow::Borrow<Mid>,
744 MutLock: std::borrow::BorrowMut<Lock>,
745 MutMid: std::borrow::BorrowMut<Mid>,
746 G1: Fn(Value) -> Option<LockValue>,
747 S1: Fn(MutValue) -> Option<MutLock>,
748 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
749 G2: Fn(MidValue) -> Option<Value2>,
750 S2: Fn(MutMid) -> Option<MutValue2>,
751 {
752 crate::lock::KpThenLockKp {
753 first: self,
754 second: lock_kp,
755 _p: std::marker::PhantomData,
756 }
757 }
758
759 pub fn then_async<AsyncKp>(
762 self,
763 async_kp: AsyncKp,
764 ) -> crate::async_lock::KpThenAsyncKeyPath<
765 R,
766 V,
767 <AsyncKp::Value as KeyPathValueTarget>::Target,
768 Root,
769 Value,
770 AsyncKp::Value,
771 MutRoot,
772 MutValue,
773 AsyncKp::MutValue,
774 Self,
775 AsyncKp,
776 >
777 where
778 V: 'static,
779 Value: std::borrow::Borrow<V>,
780 MutValue: std::borrow::BorrowMut<V>,
781 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
782 AsyncKp::Value: KeyPathValueTarget
783 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
784 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
785 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
786 {
787 crate::async_lock::KpThenAsyncKeyPath {
788 first: self,
789 second: async_kp,
790 _p: std::marker::PhantomData,
791 }
792 }
793
794 pub fn map<MappedValue, F>(
805 &self,
806 mapper: F,
807 ) -> Kp<
808 R,
809 MappedValue,
810 Root,
811 MappedValue,
812 MutRoot,
813 MappedValue,
814 impl Fn(Root) -> Option<MappedValue>,
815 impl Fn(MutRoot) -> Option<MappedValue>,
816 >
817 where
818 F: Fn(&V) -> MappedValue + Copy + 'static,
821 V: 'static,
822 MappedValue: 'static,
823 {
824 Kp::new(
825 move |root: Root| {
826 (&self.get)(root).map(|value| {
827 let v: &V = value.borrow();
828 mapper(v)
829 })
830 },
831 move |root: MutRoot| {
832 (&self.set)(root).map(|value| {
833 let v: &V = value.borrow();
834 mapper(v)
835 })
836 },
837 )
838 }
839
840 pub fn filter<F>(
851 &self,
852 predicate: F,
853 ) -> Kp<
854 R,
855 V,
856 Root,
857 Value,
858 MutRoot,
859 MutValue,
860 impl Fn(Root) -> Option<Value>,
861 impl Fn(MutRoot) -> Option<MutValue>,
862 >
863 where
864 F: Fn(&V) -> bool + Copy + 'static,
867 V: 'static,
868 {
869 Kp::new(
870 move |root: Root| {
871 (&self.get)(root).filter(|value| {
872 let v: &V = value.borrow();
873 predicate(v)
874 })
875 },
876 move |root: MutRoot| {
877 (&self.set)(root).filter(|value| {
878 let v: &V = value.borrow();
879 predicate(v)
880 })
881 },
882 )
883 }
884
885 pub fn filter_map<MappedValue, F>(
896 &self,
897 mapper: F,
898 ) -> Kp<
899 R,
900 MappedValue,
901 Root,
902 MappedValue,
903 MutRoot,
904 MappedValue,
905 impl Fn(Root) -> Option<MappedValue>,
906 impl Fn(MutRoot) -> Option<MappedValue>,
907 >
908 where
909 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
912 V: 'static,
913 MappedValue: 'static,
914 {
915 Kp::new(
916 move |root: Root| {
917 (&self.get)(root).and_then(|value| {
918 let v: &V = value.borrow();
919 mapper(v)
920 })
921 },
922 move |root: MutRoot| {
923 (&self.set)(root).and_then(|value| {
924 let v: &V = value.borrow();
925 mapper(v)
926 })
927 },
928 )
929 }
930
931 pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
941 where
942 F: Fn(&V) -> I + 'static,
945 V: 'static,
946 I: IntoIterator<Item = Item>,
947 Item: 'static,
948 {
949 move |root: Root| {
950 (&self.get)(root)
951 .map(|value| {
952 let v: &V = value.borrow();
953 mapper(v).into_iter().collect()
954 })
955 .unwrap_or_else(Vec::new)
956 }
957 }
958
959 pub fn inspect<F>(
968 &self,
969 inspector: F,
970 ) -> Kp<
971 R,
972 V,
973 Root,
974 Value,
975 MutRoot,
976 MutValue,
977 impl Fn(Root) -> Option<Value>,
978 impl Fn(MutRoot) -> Option<MutValue>,
979 >
980 where
981 F: Fn(&V) + Copy + 'static,
984 V: 'static,
985 {
986 Kp::new(
987 move |root: Root| {
988 (&self.get)(root).map(|value| {
989 let v: &V = value.borrow();
990 inspector(v);
991 value
992 })
993 },
994 move |root: MutRoot| {
995 (&self.set)(root).map(|value| {
996 let v: &V = value.borrow();
997 inspector(v);
998 value
999 })
1000 },
1001 )
1002 }
1003
1004 pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
1016 where
1017 F: Fn(Acc, &V) -> Acc + 'static,
1020 V: 'static,
1021 Acc: Copy + 'static,
1023 {
1024 move |root: Root| {
1025 (&self.get)(root)
1026 .map(|value| {
1027 let v: &V = value.borrow();
1028 folder(init, v)
1029 })
1030 .unwrap_or(init)
1031 }
1032 }
1033
1034 pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1044 where
1045 F: Fn(&V) -> bool + 'static,
1048 V: 'static,
1049 {
1050 move |root: Root| {
1051 (&self.get)(root)
1052 .map(|value| {
1053 let v: &V = value.borrow();
1054 predicate(v)
1055 })
1056 .unwrap_or(false)
1057 }
1058 }
1059
1060 pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1070 where
1071 F: Fn(&V) -> bool + 'static,
1074 V: 'static,
1075 {
1076 move |root: Root| {
1077 (&self.get)(root)
1078 .map(|value| {
1079 let v: &V = value.borrow();
1080 predicate(v)
1081 })
1082 .unwrap_or(true)
1083 }
1084 }
1085
1086 pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
1096 where
1097 F: Fn(&V) -> usize + 'static,
1100 V: 'static,
1101 {
1102 move |root: Root| {
1103 (&self.get)(root).map(|value| {
1104 let v: &V = value.borrow();
1105 counter(v)
1106 })
1107 }
1108 }
1109
1110 pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
1122 where
1123 F: Fn(&V) -> Option<Item> + 'static,
1126 V: 'static,
1127 Item: 'static,
1128 {
1129 move |root: Root| {
1130 (&self.get)(root).and_then(|value| {
1131 let v: &V = value.borrow();
1132 finder(v)
1133 })
1134 }
1135 }
1136
1137 pub fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output>
1146 where
1147 F: Fn(&V, usize) -> Output + 'static,
1150 V: 'static,
1151 Output: 'static,
1152 {
1153 move |root: Root| {
1154 (&self.get)(root).map(|value| {
1155 let v: &V = value.borrow();
1156 taker(v, n)
1157 })
1158 }
1159 }
1160
1161 pub fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output>
1170 where
1171 F: Fn(&V, usize) -> Output + 'static,
1174 V: 'static,
1175 Output: 'static,
1176 {
1177 move |root: Root| {
1178 (&self.get)(root).map(|value| {
1179 let v: &V = value.borrow();
1180 skipper(v, n)
1181 })
1182 }
1183 }
1184
1185 pub fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output>
1196 where
1197 F: Fn(&V) -> Output + 'static,
1200 V: 'static,
1201 Output: 'static,
1202 {
1203 move |root: Root| {
1204 (&self.get)(root).map(|value| {
1205 let v: &V = value.borrow();
1206 partitioner(v)
1207 })
1208 }
1209 }
1210
1211 pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
1221 where
1222 F: Fn(&V) -> Option<Item> + 'static,
1225 V: 'static,
1226 Item: 'static,
1227 {
1228 move |root: Root| {
1229 (&self.get)(root).and_then(|value| {
1230 let v: &V = value.borrow();
1231 min_fn(v)
1232 })
1233 }
1234 }
1235
1236 pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
1246 where
1247 F: Fn(&V) -> Option<Item> + 'static,
1250 V: 'static,
1251 Item: 'static,
1252 {
1253 move |root: Root| {
1254 (&self.get)(root).and_then(|value| {
1255 let v: &V = value.borrow();
1256 max_fn(v)
1257 })
1258 }
1259 }
1260
1261 pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
1271 where
1272 F: Fn(&V) -> Sum + 'static,
1275 V: 'static,
1276 Sum: 'static,
1277 {
1278 move |root: Root| {
1279 (&self.get)(root).map(|value| {
1280 let v: &V = value.borrow();
1281 sum_fn(v)
1282 })
1283 }
1284 }
1285
1286 pub fn chain<SV, SubValue, MutSubValue, G2, S2>(
1289 &self,
1290 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1291 ) -> Kp<
1292 R,
1293 SV,
1294 Root,
1295 SubValue,
1296 MutRoot,
1297 MutSubValue,
1298 impl Fn(Root) -> Option<SubValue>,
1299 impl Fn(MutRoot) -> Option<MutSubValue>,
1300 >
1301 where
1302 SubValue: std::borrow::Borrow<SV>,
1303 MutSubValue: std::borrow::BorrowMut<SV>,
1304 G2: Fn(Value) -> Option<SubValue>,
1305 S2: Fn(MutValue) -> Option<MutSubValue>,
1306 V: 'static,
1307 {
1308 self.then(next)
1309 }
1310
1311 pub fn for_arc<'b>(
1312 &self,
1313 ) -> Kp<
1314 std::sync::Arc<R>,
1315 V,
1316 std::sync::Arc<R>,
1317 Value,
1318 std::sync::Arc<R>,
1319 MutValue,
1320 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1321 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1322 >
1323 where
1324 R: 'b,
1325 V: 'b,
1326 Root: for<'a> From<&'a R>,
1327 MutRoot: for<'a> From<&'a mut R>,
1328 {
1329 Kp::new(
1330 move |arc_root: std::sync::Arc<R>| {
1331 let r_ref: &R = &*arc_root;
1332 (&self.get)(Root::from(r_ref))
1333 },
1334 move |mut arc_root: std::sync::Arc<R>| {
1335 std::sync::Arc::get_mut(&mut arc_root)
1337 .and_then(|r_mut| (&self.set)(MutRoot::from(r_mut)))
1338 },
1339 )
1340 }
1341
1342 pub fn for_box<'a>(
1343 &self,
1344 ) -> Kp<
1345 Box<R>,
1346 V,
1347 Box<R>,
1348 Value,
1349 Box<R>,
1350 MutValue,
1351 impl Fn(Box<R>) -> Option<Value>,
1352 impl Fn(Box<R>) -> Option<MutValue>,
1353 >
1354 where
1355 R: 'a,
1356 V: 'a,
1357 Root: for<'b> From<&'b R>,
1358 MutRoot: for<'b> From<&'b mut R>,
1359 {
1360 Kp::new(
1361 move |r: Box<R>| {
1362 let r_ref: &R = r.as_ref();
1363 (&self.get)(Root::from(r_ref))
1364 },
1365 move |mut r: Box<R>| {
1366 (self.set)(MutRoot::from(r.as_mut()))
1368 },
1369 )
1370 }
1371}
1372
1373pub fn zip_kps<'a, RootType, Value1, Value2>(
1385 kp1: &'a KpType<'a, RootType, Value1>,
1386 kp2: &'a KpType<'a, RootType, Value2>,
1387) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1388where
1389 RootType: 'a,
1390 Value1: 'a,
1391 Value2: 'a,
1392{
1393 move |root: &'a RootType| {
1394 let val1 = (kp1.get)(root)?;
1395 let val2 = (kp2.get)(root)?;
1396 Some((val1, val2))
1397 }
1398}
1399
1400impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1401where
1402 Root: std::borrow::Borrow<R>,
1403 MutRoot: std::borrow::BorrowMut<R>,
1404 G: Fn(Root) -> Option<Root>,
1405 S: Fn(MutRoot) -> Option<MutRoot>,
1406{
1407 pub fn identity_typed() -> Kp<
1408 R,
1409 R,
1410 Root,
1411 Root,
1412 MutRoot,
1413 MutRoot,
1414 fn(Root) -> Option<Root>,
1415 fn(MutRoot) -> Option<MutRoot>,
1416 > {
1417 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1418 }
1419
1420 pub fn identity<'a>() -> KpType<'a, R, R> {
1421 KpType::new(|r| Some(r), |r| Some(r))
1422 }
1423}
1424
1425pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1434where
1435 Root: std::borrow::Borrow<Enum>,
1436 Value: std::borrow::Borrow<Variant>,
1437 MutRoot: std::borrow::BorrowMut<Enum>,
1438 MutValue: std::borrow::BorrowMut<Variant>,
1439 G: Fn(Root) -> Option<Value>,
1440 S: Fn(MutRoot) -> Option<MutValue>,
1441 E: Fn(Variant) -> Enum,
1442{
1443 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1444 embedder: E,
1445}
1446
1447impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1448 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1449where
1450 Root: std::borrow::Borrow<Enum>,
1451 Value: std::borrow::Borrow<Variant>,
1452 MutRoot: std::borrow::BorrowMut<Enum>,
1453 MutValue: std::borrow::BorrowMut<Variant>,
1454 G: Fn(Root) -> Option<Value>,
1455 S: Fn(MutRoot) -> Option<MutValue>,
1456 E: Fn(Variant) -> Enum,
1457{
1458 pub fn new(
1460 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1461 embedder: E,
1462 ) -> Self {
1463 Self {
1464 extractor,
1465 embedder,
1466 }
1467 }
1468
1469 pub fn get(&self, enum_value: Root) -> Option<Value> {
1471 self.extractor.get(enum_value)
1472 }
1473
1474 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1476 self.extractor.get_mut(enum_value)
1477 }
1478
1479 pub fn embed(&self, value: Variant) -> Enum {
1481 (self.embedder)(value)
1482 }
1483
1484 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1486 &self.extractor
1487 }
1488
1489 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1491 self.extractor
1492 }
1493
1494 pub fn map<MappedValue, F>(
1504 &self,
1505 mapper: F,
1506 ) -> EnumKp<
1507 Enum,
1508 MappedValue,
1509 Root,
1510 MappedValue,
1511 MutRoot,
1512 MappedValue,
1513 impl Fn(Root) -> Option<MappedValue>,
1514 impl Fn(MutRoot) -> Option<MappedValue>,
1515 impl Fn(MappedValue) -> Enum,
1516 >
1517 where
1518 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1521 Variant: 'static,
1522 MappedValue: 'static,
1523 E: Fn(Variant) -> Enum + Copy + 'static,
1525 {
1526 let mapped_extractor = self.extractor.map(mapper);
1527
1528 let new_embedder = move |_value: MappedValue| -> Enum {
1532 panic!(
1533 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1534 )
1535 };
1536
1537 EnumKp::new(mapped_extractor, new_embedder)
1538 }
1539
1540 pub fn filter<F>(
1551 &self,
1552 predicate: F,
1553 ) -> EnumKp<
1554 Enum,
1555 Variant,
1556 Root,
1557 Value,
1558 MutRoot,
1559 MutValue,
1560 impl Fn(Root) -> Option<Value>,
1561 impl Fn(MutRoot) -> Option<MutValue>,
1562 E,
1563 >
1564 where
1565 F: Fn(&Variant) -> bool + Copy + 'static,
1568 Variant: 'static,
1569 E: Copy,
1571 {
1572 let filtered_extractor = self.extractor.filter(predicate);
1573 EnumKp::new(filtered_extractor, self.embedder)
1574 }
1575}
1576
1577pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1579 Enum,
1580 Variant,
1581 &'a Enum,
1582 &'a Variant,
1583 &'a mut Enum,
1584 &'a mut Variant,
1585 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1586 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1587 fn(Variant) -> Enum,
1588>;
1589
1590pub fn enum_variant<'a, Enum, Variant>(
1607 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1608 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1609 embedder: fn(Variant) -> Enum,
1610) -> EnumKpType<'a, Enum, Variant> {
1611 EnumKp::new(Kp::new(getter, setter), embedder)
1612}
1613
1614pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1623 EnumKp::new(
1624 Kp::new(
1625 |r: &Result<T, E>| r.as_ref().ok(),
1626 |r: &mut Result<T, E>| r.as_mut().ok(),
1627 ),
1628 |t: T| Ok(t),
1629 )
1630}
1631
1632pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1641 EnumKp::new(
1642 Kp::new(
1643 |r: &Result<T, E>| r.as_ref().err(),
1644 |r: &mut Result<T, E>| r.as_mut().err(),
1645 ),
1646 |e: E| Err(e),
1647 )
1648}
1649
1650pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1659 EnumKp::new(
1660 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1661 |t: T| Some(t),
1662 )
1663}
1664
1665pub fn variant_of<'a, Enum, Variant>(
1682 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1683 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1684 embedder: fn(Variant) -> Enum,
1685) -> EnumKpType<'a, Enum, Variant> {
1686 enum_variant(getter, setter, embedder)
1687}
1688
1689pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1701 Kp::new(
1702 |b: &Box<T>| Some(b.as_ref()),
1703 |b: &mut Box<T>| Some(b.as_mut()),
1704 )
1705}
1706
1707pub fn kp_arc<'a, T>() -> Kp<
1716 Arc<T>,
1717 T,
1718 &'a Arc<T>,
1719 &'a T,
1720 &'a mut Arc<T>,
1721 &'a mut T,
1722 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
1723 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
1724> {
1725 Kp::new(
1726 |arc: &Arc<T>| Some(arc.as_ref()),
1727 |arc: &mut Arc<T>| Arc::get_mut(arc),
1728 )
1729}
1730
1731pub fn kp_rc<'a, T>() -> Kp<
1740 std::rc::Rc<T>,
1741 T,
1742 &'a std::rc::Rc<T>,
1743 &'a T,
1744 &'a mut std::rc::Rc<T>,
1745 &'a mut T,
1746 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
1747 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
1748> {
1749 Kp::new(
1750 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
1751 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
1752 )
1753}
1754
1755use std::any::{Any, TypeId};
1758use std::rc::Rc;
1759
1760#[cfg(test)]
1775mod tests {
1776 use super::*;
1777 use std::collections::HashMap;
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 #[derive(Debug)]
1863 struct TestKP2 {
1864 a: String,
1865 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
1866 }
1867
1868 impl TestKP2 {
1869 fn new() -> Self {
1870 TestKP2 {
1871 a: String::from("a2"),
1872 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1873 }
1874 }
1875
1876 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1877 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
1884 fn(MutRoot) -> Option<MutRoot>,
1885 >
1886 where
1887 Root: std::borrow::Borrow<TestKP2>,
1888 MutRoot: std::borrow::BorrowMut<TestKP2>,
1889 G: Fn(Root) -> Option<Root>,
1890 S: Fn(MutRoot) -> Option<MutRoot>,
1891 {
1892 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1893 }
1894
1895 fn a<'a>() -> KpType<'a, TestKP2, String> {
1896 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
1897 }
1898
1899 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
1900 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
1901 }
1902
1903 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
1908 KpType::identity()
1909 }
1910 }
1911
1912 #[derive(Debug)]
1913 struct TestKP3 {
1914 a: String,
1915 b: std::sync::Arc<std::sync::Mutex<String>>,
1916 }
1917
1918 impl TestKP3 {
1919 fn new() -> Self {
1920 TestKP3 {
1921 a: String::from("a2"),
1922 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
1923 }
1924 }
1925
1926 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1927 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
1934 fn(MutRoot) -> Option<MutRoot>,
1935 >
1936 where
1937 Root: std::borrow::Borrow<TestKP3>,
1938 MutRoot: std::borrow::BorrowMut<TestKP3>,
1939 G: Fn(Root) -> Option<Root>,
1940 S: Fn(MutRoot) -> Option<MutRoot>,
1941 {
1942 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1943 }
1944
1945 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
1946 KpType::identity()
1947 }
1948 }
1949
1950 impl TestKP3 {}
1951
1952 impl TestKP {}
1953 #[test]
1954 fn test_a() {
1955 let instance2 = TestKP2::new();
1956 let mut instance = TestKP::new();
1957 let kp = TestKP::identity();
1958 let kp_a = TestKP::a();
1959 let kp_f = TestKP::f();
1961 let wres = kp_f.then(TestKP2::a()).get_mut(&mut instance).unwrap();
1962 *wres = String::from("a3 changed successfully");
1963 let res = kp_f.then(TestKP2::a()).get(&instance);
1964 println!("{:?}", res);
1965 let res = kp_f.then(TestKP2::identity()).get(&instance);
1966 println!("{:?}", res);
1967 let res = kp.get(&instance);
1968 println!("{:?}", res);
1969
1970 let hash_kp = TestKP::g(0);
1971 let new_kp_from_hashmap = hash_kp.then(TestKP2::a());
1972 println!("{:?}", new_kp_from_hashmap.get(&instance));
1973 }
1974
1975 #[test]
2011 fn test_enum_kp_result_ok() {
2012 let ok_result: Result<String, i32> = Ok("success".to_string());
2013 let mut err_result: Result<String, i32> = Err(42);
2014
2015 let ok_kp = enum_ok();
2016
2017 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2019 assert_eq!(ok_kp.get(&err_result), None);
2020
2021 let embedded = ok_kp.embed("embedded".to_string());
2023 assert_eq!(embedded, Ok("embedded".to_string()));
2024
2025 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2027 *val = "modified".to_string();
2028 }
2029 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2032 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2033 *val = "modified".to_string();
2034 }
2035 assert_eq!(ok_result2, Ok("modified".to_string()));
2036 }
2037
2038 #[test]
2039 fn test_enum_kp_result_err() {
2040 let ok_result: Result<String, i32> = Ok("success".to_string());
2041 let mut err_result: Result<String, i32> = Err(42);
2042
2043 let err_kp = enum_err();
2044
2045 assert_eq!(err_kp.get(&err_result), Some(&42));
2047 assert_eq!(err_kp.get(&ok_result), None);
2048
2049 let embedded = err_kp.embed(99);
2051 assert_eq!(embedded, Err(99));
2052
2053 if let Some(val) = err_kp.get_mut(&mut err_result) {
2055 *val = 100;
2056 }
2057 assert_eq!(err_result, Err(100));
2058 }
2059
2060 #[test]
2061 fn test_enum_kp_option_some() {
2062 let some_opt = Some("value".to_string());
2063 let mut none_opt: Option<String> = None;
2064
2065 let some_kp = enum_some();
2066
2067 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2069 assert_eq!(some_kp.get(&none_opt), None);
2070
2071 let embedded = some_kp.embed("embedded".to_string());
2073 assert_eq!(embedded, Some("embedded".to_string()));
2074
2075 let mut some_opt2 = Some("original".to_string());
2077 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2078 *val = "modified".to_string();
2079 }
2080 assert_eq!(some_opt2, Some("modified".to_string()));
2081 }
2082
2083 #[test]
2084 fn test_enum_kp_custom_enum() {
2085 #[derive(Debug, PartialEq)]
2086 enum MyEnum {
2087 A(String),
2088 B(i32),
2089 C,
2090 }
2091
2092 let mut enum_a = MyEnum::A("hello".to_string());
2093 let enum_b = MyEnum::B(42);
2094 let enum_c = MyEnum::C;
2095
2096 let kp_a = enum_variant(
2098 |e: &MyEnum| match e {
2099 MyEnum::A(s) => Some(s),
2100 _ => None,
2101 },
2102 |e: &mut MyEnum| match e {
2103 MyEnum::A(s) => Some(s),
2104 _ => None,
2105 },
2106 |s: String| MyEnum::A(s),
2107 );
2108
2109 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2111 assert_eq!(kp_a.get(&enum_b), None);
2112 assert_eq!(kp_a.get(&enum_c), None);
2113
2114 let embedded = kp_a.embed("world".to_string());
2116 assert_eq!(embedded, MyEnum::A("world".to_string()));
2117
2118 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2120 *val = "modified".to_string();
2121 }
2122 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2123 }
2124
2125 #[test]
2126 fn test_container_kp_box() {
2127 let boxed = Box::new("value".to_string());
2128 let mut boxed_mut = Box::new("original".to_string());
2129
2130 let box_kp = kp_box();
2131
2132 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2134
2135 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2137 *val = "modified".to_string();
2138 }
2139 assert_eq!(*boxed_mut, "modified".to_string());
2140 }
2141
2142 #[test]
2143 fn test_container_kp_arc() {
2144 let arc = Arc::new("value".to_string());
2145 let mut arc_mut = Arc::new("original".to_string());
2146
2147 let arc_kp = kp_arc();
2148
2149 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2151
2152 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2154 *val = "modified".to_string();
2155 }
2156 assert_eq!(*arc_mut, "modified".to_string());
2157
2158 let arc_shared = Arc::new("shared".to_string());
2160 let arc_shared2 = Arc::clone(&arc_shared);
2161 let mut arc_shared_mut = arc_shared;
2162 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2163 }
2164
2165 #[test]
2166 fn test_enum_kp_composition() {
2167 #[derive(Debug, PartialEq)]
2169 struct Inner {
2170 value: String,
2171 }
2172
2173 let result: Result<Inner, i32> = Ok(Inner {
2174 value: "nested".to_string(),
2175 });
2176
2177 let inner_kp = KpType::new(
2179 |i: &Inner| Some(&i.value),
2180 |i: &mut Inner| Some(&mut i.value),
2181 );
2182
2183 let ok_kp = enum_ok::<Inner, i32>();
2185 let ok_kp_base = ok_kp.into_kp();
2186 let composed = ok_kp_base.then(inner_kp);
2187
2188 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2189 }
2190
2191 #[test]
2192 fn test_pkp_basic() {
2193 #[derive(Debug)]
2194 struct User {
2195 name: String,
2196 age: i32,
2197 }
2198
2199 let user = User {
2200 name: "Alice".to_string(),
2201 age: 30,
2202 };
2203
2204 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2206 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2207
2208 let name_pkp = PKp::new(name_kp);
2210 let age_pkp = PKp::new(age_kp);
2211
2212 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2214 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2215
2216 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2218 assert_eq!(age_pkp.get_as::<String>(&user), None);
2219
2220 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2222 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2223 }
2224
2225 #[test]
2226 fn test_pkp_collection() {
2227 #[derive(Debug)]
2228 struct User {
2229 name: String,
2230 age: i32,
2231 }
2232
2233 let user = User {
2234 name: "Bob".to_string(),
2235 age: 25,
2236 };
2237
2238 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2240 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2241
2242 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2243
2244 let name_value = keypaths[0].get_as::<String>(&user);
2246 let age_value = keypaths[1].get_as::<i32>(&user);
2247
2248 assert_eq!(name_value, Some(&"Bob".to_string()));
2249 assert_eq!(age_value, Some(&25));
2250 }
2251
2252 #[test]
2253 fn test_pkp_for_arc() {
2254 #[derive(Debug)]
2255 struct User {
2256 name: String,
2257 }
2258
2259 let user = Arc::new(User {
2260 name: "Charlie".to_string(),
2261 });
2262
2263 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2264 let name_pkp = PKp::new(name_kp);
2265
2266 let arc_pkp = name_pkp.for_arc();
2268
2269 assert_eq!(
2270 arc_pkp.get_as::<String>(&user),
2271 Some(&"Charlie".to_string())
2272 );
2273 }
2274
2275 #[test]
2276 fn test_pkp_for_option() {
2277 #[derive(Debug)]
2278 struct User {
2279 name: String,
2280 }
2281
2282 let some_user = Some(User {
2283 name: "Diana".to_string(),
2284 });
2285 let none_user: Option<User> = None;
2286
2287 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2288 let name_pkp = PKp::new(name_kp);
2289
2290 let opt_pkp = name_pkp.for_option();
2292
2293 assert_eq!(
2294 opt_pkp.get_as::<String>(&some_user),
2295 Some(&"Diana".to_string())
2296 );
2297 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2298 }
2299
2300 #[test]
2301 fn test_akp_basic() {
2302 #[derive(Debug)]
2303 struct User {
2304 name: String,
2305 age: i32,
2306 }
2307
2308 #[derive(Debug)]
2309 struct Product {
2310 title: String,
2311 price: f64,
2312 }
2313
2314 let user = User {
2315 name: "Eve".to_string(),
2316 age: 28,
2317 };
2318
2319 let product = Product {
2320 title: "Book".to_string(),
2321 price: 19.99,
2322 };
2323
2324 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2326 let user_name_akp = AKp::new(user_name_kp);
2327
2328 let product_title_kp = KpType::new(
2329 |p: &Product| Some(&p.title),
2330 |p: &mut Product| Some(&mut p.title),
2331 );
2332 let product_title_akp = AKp::new(product_title_kp);
2333
2334 assert_eq!(
2336 user_name_akp.get_as::<User, String>(&user),
2337 Some(Some(&"Eve".to_string()))
2338 );
2339 assert_eq!(
2340 product_title_akp.get_as::<Product, String>(&product),
2341 Some(Some(&"Book".to_string()))
2342 );
2343
2344 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2346 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2347
2348 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2350 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2351 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2352 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2353 }
2354
2355 #[test]
2356 fn test_akp_heterogeneous_collection() {
2357 #[derive(Debug)]
2358 struct User {
2359 name: String,
2360 }
2361
2362 #[derive(Debug)]
2363 struct Product {
2364 title: String,
2365 }
2366
2367 let user = User {
2368 name: "Frank".to_string(),
2369 };
2370 let product = Product {
2371 title: "Laptop".to_string(),
2372 };
2373
2374 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2376 let product_title_kp = KpType::new(
2377 |p: &Product| Some(&p.title),
2378 |p: &mut Product| Some(&mut p.title),
2379 );
2380
2381 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2382
2383 let user_any: &dyn Any = &user;
2385 let product_any: &dyn Any = &product;
2386
2387 let user_value = keypaths[0].get(user_any);
2388 let product_value = keypaths[1].get(product_any);
2389
2390 assert!(user_value.is_some());
2391 assert!(product_value.is_some());
2392
2393 assert_eq!(
2395 user_value.and_then(|v| v.downcast_ref::<String>()),
2396 Some(&"Frank".to_string())
2397 );
2398 assert_eq!(
2399 product_value.and_then(|v| v.downcast_ref::<String>()),
2400 Some(&"Laptop".to_string())
2401 );
2402 }
2403
2404 #[test]
2405 fn test_akp_for_option() {
2406 #[derive(Debug)]
2407 struct User {
2408 name: String,
2409 }
2410
2411 let some_user = Some(User {
2412 name: "Grace".to_string(),
2413 });
2414 let none_user: Option<User> = None;
2415
2416 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2417 let name_akp = AKp::new(name_kp);
2418
2419 let opt_akp = name_akp.for_option::<User>();
2421
2422 assert_eq!(
2423 opt_akp.get_as::<Option<User>, String>(&some_user),
2424 Some(Some(&"Grace".to_string()))
2425 );
2426 assert_eq!(
2427 opt_akp.get_as::<Option<User>, String>(&none_user),
2428 Some(None)
2429 );
2430 }
2431
2432 #[test]
2433 fn test_akp_for_result() {
2434 #[derive(Debug)]
2435 struct User {
2436 name: String,
2437 }
2438
2439 let ok_user: Result<User, String> = Ok(User {
2440 name: "Henry".to_string(),
2441 });
2442 let err_user: Result<User, String> = Err("Not found".to_string());
2443
2444 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2445 let name_akp = AKp::new(name_kp);
2446
2447 let result_akp = name_akp.for_result::<User, String>();
2449
2450 assert_eq!(
2451 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2452 Some(Some(&"Henry".to_string()))
2453 );
2454 assert_eq!(
2455 result_akp.get_as::<Result<User, String>, String>(&err_user),
2456 Some(None)
2457 );
2458 }
2459
2460 #[test]
2463 fn test_kp_map() {
2464 #[derive(Debug)]
2465 struct User {
2466 name: String,
2467 age: i32,
2468 }
2469
2470 let user = User {
2471 name: "Alice".to_string(),
2472 age: 30,
2473 };
2474
2475 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2477 let len_kp = name_kp.map(|name: &String| name.len());
2478
2479 assert_eq!(len_kp.get(&user), Some(5));
2480
2481 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2483 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2484
2485 assert_eq!(double_age_kp.get(&user), Some(60));
2486
2487 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2489 assert_eq!(is_adult_kp.get(&user), Some(true));
2490 }
2491
2492 #[test]
2493 fn test_kp_filter() {
2494 #[derive(Debug)]
2495 struct User {
2496 name: String,
2497 age: i32,
2498 }
2499
2500 let adult = User {
2501 name: "Alice".to_string(),
2502 age: 30,
2503 };
2504
2505 let minor = User {
2506 name: "Bob".to_string(),
2507 age: 15,
2508 };
2509
2510 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2511 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2512
2513 assert_eq!(adult_age_kp.get(&adult), Some(&30));
2514 assert_eq!(adult_age_kp.get(&minor), None);
2515
2516 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2518 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2519
2520 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2521 assert_eq!(short_name_kp.get(&adult), None);
2522 }
2523
2524 #[test]
2525 fn test_kp_map_and_filter() {
2526 #[derive(Debug)]
2527 struct User {
2528 scores: Vec<i32>,
2529 }
2530
2531 let user = User {
2532 scores: vec![85, 92, 78, 95],
2533 };
2534
2535 let scores_kp = KpType::new(
2536 |u: &User| Some(&u.scores),
2537 |u: &mut User| Some(&mut u.scores),
2538 );
2539
2540 let avg_kp =
2542 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2543
2544 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2546
2547 assert_eq!(high_avg_kp.get(&user), Some(87)); }
2549
2550 #[test]
2551 fn test_enum_kp_map() {
2552 let ok_result: Result<String, i32> = Ok("hello".to_string());
2553 let err_result: Result<String, i32> = Err(42);
2554
2555 let ok_kp = enum_ok::<String, i32>();
2556 let len_kp = ok_kp.map(|s: &String| s.len());
2557
2558 assert_eq!(len_kp.get(&ok_result), Some(5));
2559 assert_eq!(len_kp.get(&err_result), None);
2560
2561 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2563 let none_opt: Option<Vec<i32>> = None;
2564
2565 let some_kp = enum_some::<Vec<i32>>();
2566 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2567
2568 assert_eq!(count_kp.get(&some_opt), Some(5));
2569 assert_eq!(count_kp.get(&none_opt), None);
2570 }
2571
2572 #[test]
2573 fn test_enum_kp_filter() {
2574 let ok_result1: Result<i32, String> = Ok(42);
2575 let ok_result2: Result<i32, String> = Ok(-5);
2576 let err_result: Result<i32, String> = Err("error".to_string());
2577
2578 let ok_kp = enum_ok::<i32, String>();
2579 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2580
2581 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2582 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2587 let short_str = Some("hi".to_string());
2588
2589 let some_kp = enum_some::<String>();
2590 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2591
2592 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2593 assert_eq!(long_kp.get(&short_str), None);
2594 }
2595
2596 #[test]
2597 fn test_pkp_filter() {
2598 #[derive(Debug)]
2599 struct User {
2600 name: String,
2601 age: i32,
2602 }
2603
2604 let adult = User {
2605 name: "Alice".to_string(),
2606 age: 30,
2607 };
2608
2609 let minor = User {
2610 name: "Bob".to_string(),
2611 age: 15,
2612 };
2613
2614 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2615 let age_pkp = PKp::new(age_kp);
2616
2617 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2619
2620 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2621 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2622
2623 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2625 let name_pkp = PKp::new(name_kp);
2626 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2627
2628 assert_eq!(
2629 short_name_pkp.get_as::<String>(&minor),
2630 Some(&"Bob".to_string())
2631 );
2632 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2633 }
2634
2635 #[test]
2636 fn test_akp_filter() {
2637 #[derive(Debug)]
2638 struct User {
2639 age: i32,
2640 }
2641
2642 #[derive(Debug)]
2643 struct Product {
2644 price: f64,
2645 }
2646
2647 let adult = User { age: 30 };
2648 let minor = User { age: 15 };
2649 let expensive = Product { price: 99.99 };
2650 let cheap = Product { price: 5.0 };
2651
2652 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2654 let age_akp = AKp::new(age_kp);
2655 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2656
2657 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2658 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2659
2660 let price_kp = KpType::new(
2662 |p: &Product| Some(&p.price),
2663 |p: &mut Product| Some(&mut p.price),
2664 );
2665 let price_akp = AKp::new(price_kp);
2666 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2667
2668 assert_eq!(
2669 expensive_akp.get_as::<Product, f64>(&expensive),
2670 Some(Some(&99.99))
2671 );
2672 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2673 }
2674
2675 #[test]
2678 fn test_kp_filter_map() {
2679 #[derive(Debug)]
2680 struct User {
2681 middle_name: Option<String>,
2682 }
2683
2684 let user_with = User {
2685 middle_name: Some("Marie".to_string()),
2686 };
2687 let user_without = User { middle_name: None };
2688
2689 let middle_kp = KpType::new(
2690 |u: &User| Some(&u.middle_name),
2691 |u: &mut User| Some(&mut u.middle_name),
2692 );
2693
2694 let first_char_kp = middle_kp
2695 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
2696
2697 assert_eq!(first_char_kp.get(&user_with), Some('M'));
2698 assert_eq!(first_char_kp.get(&user_without), None);
2699 }
2700
2701 #[test]
2702 fn test_kp_inspect() {
2703 #[derive(Debug)]
2704 struct User {
2705 name: String,
2706 }
2707
2708 let user = User {
2709 name: "Alice".to_string(),
2710 };
2711
2712 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2716
2717 let result = name_kp.get(&user);
2720 assert_eq!(result, Some(&"Alice".to_string()));
2721
2722 }
2725
2726 #[test]
2727 fn test_kp_fold_value() {
2728 #[derive(Debug)]
2729 struct User {
2730 scores: Vec<i32>,
2731 }
2732
2733 let user = User {
2734 scores: vec![85, 92, 78, 95],
2735 };
2736
2737 let scores_kp = KpType::new(
2738 |u: &User| Some(&u.scores),
2739 |u: &mut User| Some(&mut u.scores),
2740 );
2741
2742 let sum_fn =
2744 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
2745
2746 assert_eq!(sum_fn(&user), 350);
2747 }
2748
2749 #[test]
2750 fn test_kp_any_all() {
2751 #[derive(Debug)]
2752 struct User {
2753 scores: Vec<i32>,
2754 }
2755
2756 let user_high = User {
2757 scores: vec![85, 92, 88],
2758 };
2759 let user_mixed = User {
2760 scores: vec![65, 92, 78],
2761 };
2762
2763 let scores_kp = KpType::new(
2764 |u: &User| Some(&u.scores),
2765 |u: &mut User| Some(&mut u.scores),
2766 );
2767
2768 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
2770 assert!(has_high_fn(&user_high));
2771 assert!(has_high_fn(&user_mixed));
2772
2773 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
2775 assert!(all_passing_fn(&user_high));
2776 assert!(!all_passing_fn(&user_mixed));
2777 }
2778
2779 #[test]
2780 fn test_kp_count_items() {
2781 #[derive(Debug)]
2782 struct User {
2783 tags: Vec<String>,
2784 }
2785
2786 let user = User {
2787 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
2788 };
2789
2790 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2791 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
2792
2793 assert_eq!(count_fn(&user), Some(3));
2794 }
2795
2796 #[test]
2797 fn test_kp_find_in() {
2798 #[derive(Debug)]
2799 struct User {
2800 scores: Vec<i32>,
2801 }
2802
2803 let user = User {
2804 scores: vec![85, 92, 78, 95, 88],
2805 };
2806
2807 let scores_kp = KpType::new(
2808 |u: &User| Some(&u.scores),
2809 |u: &mut User| Some(&mut u.scores),
2810 );
2811
2812 let first_high_fn =
2814 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
2815
2816 assert_eq!(first_high_fn(&user), Some(92));
2817
2818 let perfect_fn =
2820 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
2821
2822 assert_eq!(perfect_fn(&user), None);
2823 }
2824
2825 #[test]
2826 fn test_kp_take_skip() {
2827 #[derive(Debug)]
2828 struct User {
2829 tags: Vec<String>,
2830 }
2831
2832 let user = User {
2833 tags: vec![
2834 "a".to_string(),
2835 "b".to_string(),
2836 "c".to_string(),
2837 "d".to_string(),
2838 ],
2839 };
2840
2841 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2842
2843 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
2845 tags.iter().take(n).cloned().collect::<Vec<_>>()
2846 });
2847
2848 let taken = take_fn(&user).unwrap();
2849 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
2850
2851 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
2853 tags.iter().skip(n).cloned().collect::<Vec<_>>()
2854 });
2855
2856 let skipped = skip_fn(&user).unwrap();
2857 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
2858 }
2859
2860 #[test]
2861 fn test_kp_partition() {
2862 #[derive(Debug)]
2863 struct User {
2864 scores: Vec<i32>,
2865 }
2866
2867 let user = User {
2868 scores: vec![85, 92, 65, 95, 72, 58],
2869 };
2870
2871 let scores_kp = KpType::new(
2872 |u: &User| Some(&u.scores),
2873 |u: &mut User| Some(&mut u.scores),
2874 );
2875
2876 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
2877 scores.iter().copied().partition(|&s| s >= 70)
2878 });
2879
2880 let (passing, failing) = partition_fn(&user).unwrap();
2881 assert_eq!(passing, vec![85, 92, 95, 72]);
2882 assert_eq!(failing, vec![65, 58]);
2883 }
2884
2885 #[test]
2886 fn test_kp_min_max() {
2887 #[derive(Debug)]
2888 struct User {
2889 scores: Vec<i32>,
2890 }
2891
2892 let user = User {
2893 scores: vec![85, 92, 78, 95, 88],
2894 };
2895
2896 let scores_kp = KpType::new(
2897 |u: &User| Some(&u.scores),
2898 |u: &mut User| Some(&mut u.scores),
2899 );
2900
2901 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
2903 assert_eq!(min_fn(&user), Some(78));
2904
2905 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
2907 assert_eq!(max_fn(&user), Some(95));
2908 }
2909
2910 #[test]
2911 fn test_kp_sum() {
2912 #[derive(Debug)]
2913 struct User {
2914 scores: Vec<i32>,
2915 }
2916
2917 let user = User {
2918 scores: vec![85, 92, 78],
2919 };
2920
2921 let scores_kp = KpType::new(
2922 |u: &User| Some(&u.scores),
2923 |u: &mut User| Some(&mut u.scores),
2924 );
2925
2926 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
2927 assert_eq!(sum_fn(&user), Some(255));
2928
2929 let avg_fn =
2931 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2932 assert_eq!(avg_fn.get(&user), Some(85));
2933 }
2934
2935 #[test]
2936 fn test_kp_chain() {
2937 #[derive(Debug)]
2938 struct User {
2939 profile: Profile,
2940 }
2941
2942 #[derive(Debug)]
2943 struct Profile {
2944 settings: Settings,
2945 }
2946
2947 #[derive(Debug)]
2948 struct Settings {
2949 theme: String,
2950 }
2951
2952 let user = User {
2953 profile: Profile {
2954 settings: Settings {
2955 theme: "dark".to_string(),
2956 },
2957 },
2958 };
2959
2960 let profile_kp = KpType::new(
2961 |u: &User| Some(&u.profile),
2962 |u: &mut User| Some(&mut u.profile),
2963 );
2964 let settings_kp = KpType::new(
2965 |p: &Profile| Some(&p.settings),
2966 |p: &mut Profile| Some(&mut p.settings),
2967 );
2968 let theme_kp = KpType::new(
2969 |s: &Settings| Some(&s.theme),
2970 |s: &mut Settings| Some(&mut s.theme),
2971 );
2972
2973 let profile_settings = profile_kp.chain(settings_kp);
2975 let theme_path = profile_settings.chain(theme_kp);
2976 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
2977 }
2978
2979 #[test]
2980 fn test_kp_zip() {
2981 #[derive(Debug)]
2982 struct User {
2983 name: String,
2984 age: i32,
2985 }
2986
2987 let user = User {
2988 name: "Alice".to_string(),
2989 age: 30,
2990 };
2991
2992 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2993 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2994
2995 let zipped_fn = zip_kps(&name_kp, &age_kp);
2996 let result = zipped_fn(&user);
2997
2998 assert_eq!(result, Some((&"Alice".to_string(), &30)));
2999 }
3000
3001 #[test]
3002 fn test_kp_complex_pipeline() {
3003 #[derive(Debug)]
3004 struct User {
3005 transactions: Vec<Transaction>,
3006 }
3007
3008 #[derive(Debug)]
3009 struct Transaction {
3010 amount: f64,
3011 category: String,
3012 }
3013
3014 let user = User {
3015 transactions: vec![
3016 Transaction {
3017 amount: 50.0,
3018 category: "food".to_string(),
3019 },
3020 Transaction {
3021 amount: 100.0,
3022 category: "transport".to_string(),
3023 },
3024 Transaction {
3025 amount: 25.0,
3026 category: "food".to_string(),
3027 },
3028 Transaction {
3029 amount: 200.0,
3030 category: "shopping".to_string(),
3031 },
3032 ],
3033 };
3034
3035 let txns_kp = KpType::new(
3036 |u: &User| Some(&u.transactions),
3037 |u: &mut User| Some(&mut u.transactions),
3038 );
3039
3040 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3042 txns.iter()
3043 .filter(|t| t.category == "food")
3044 .map(|t| t.amount)
3045 .sum::<f64>()
3046 });
3047
3048 assert_eq!(food_total.get(&user), Some(75.0));
3049
3050 let has_large =
3052 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3053
3054 assert!(has_large(&user));
3055
3056 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3058 assert_eq!(count(&user), Some(4));
3059 }
3060
3061 #[test]
3065 fn test_no_clone_required_for_root() {
3066 use std::sync::Arc;
3067 use std::sync::atomic::{AtomicUsize, Ordering};
3068
3069 struct NonCloneableRoot {
3072 data: Arc<AtomicUsize>,
3073 cached_value: usize,
3074 }
3075
3076 impl NonCloneableRoot {
3077 fn new() -> Self {
3078 Self {
3079 data: Arc::new(AtomicUsize::new(42)),
3080 cached_value: 42,
3081 }
3082 }
3083
3084 fn increment(&mut self) {
3085 self.data.fetch_add(1, Ordering::SeqCst);
3086 self.cached_value = self.data.load(Ordering::SeqCst);
3087 }
3088
3089 fn get_value(&self) -> &usize {
3090 &self.cached_value
3091 }
3092
3093 fn get_value_mut(&mut self) -> &mut usize {
3094 &mut self.cached_value
3095 }
3096 }
3097
3098 let mut root = NonCloneableRoot::new();
3099
3100 let data_kp = KpType::new(
3102 |r: &NonCloneableRoot| Some(r.get_value()),
3103 |r: &mut NonCloneableRoot| {
3104 r.increment();
3105 Some(r.get_value_mut())
3106 },
3107 );
3108
3109 assert_eq!(data_kp.get(&root), Some(&42));
3111
3112 {
3113 let doubled = data_kp.map(|val: &usize| val * 2);
3115 assert_eq!(doubled.get(&root), Some(84));
3116
3117 let filtered = data_kp.filter(|val: &usize| *val > 0);
3119 assert_eq!(filtered.get(&root), Some(&42));
3120 } let value_ref = data_kp.get_mut(&mut root);
3124 assert!(value_ref.is_some());
3125 }
3126
3127 #[test]
3128 fn test_no_clone_required_for_value() {
3129 use std::sync::Arc;
3130 use std::sync::atomic::{AtomicUsize, Ordering};
3131
3132 struct NonCloneableValue {
3134 counter: Arc<AtomicUsize>,
3135 }
3136
3137 impl NonCloneableValue {
3138 fn new(val: usize) -> Self {
3139 Self {
3140 counter: Arc::new(AtomicUsize::new(val)),
3141 }
3142 }
3143
3144 fn get(&self) -> usize {
3145 self.counter.load(Ordering::SeqCst)
3146 }
3147 }
3148
3149 struct Root {
3150 value: NonCloneableValue,
3151 }
3152
3153 let root = Root {
3154 value: NonCloneableValue::new(100),
3155 };
3156
3157 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3159
3160 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3162 assert_eq!(counter_kp.get(&root), Some(100));
3163
3164 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3166 assert!(filtered.get(&root).is_some());
3167 }
3168
3169 #[test]
3170 fn test_static_does_not_leak_memory() {
3171 use std::sync::Arc;
3172 use std::sync::atomic::{AtomicUsize, Ordering};
3173
3174 static CREATED: AtomicUsize = AtomicUsize::new(0);
3176 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3177
3178 struct Tracked {
3179 id: usize,
3180 }
3181
3182 impl Tracked {
3183 fn new() -> Self {
3184 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3185 Self { id }
3186 }
3187 }
3188
3189 impl Drop for Tracked {
3190 fn drop(&mut self) {
3191 DROPPED.fetch_add(1, Ordering::SeqCst);
3192 }
3193 }
3194
3195 struct Root {
3196 data: Tracked,
3197 }
3198
3199 CREATED.store(0, Ordering::SeqCst);
3201 DROPPED.store(0, Ordering::SeqCst);
3202
3203 {
3204 let root = Root {
3205 data: Tracked::new(),
3206 };
3207
3208 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3209
3210 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3212 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3213 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3214
3215 assert_eq!(mapped1.get(&root), Some(0));
3216 assert_eq!(mapped2.get(&root), Some(1));
3217 assert_eq!(mapped3.get(&root), Some(2));
3218
3219 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3221 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3222 }
3223
3224 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3226 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3227
3228 }
3230
3231 #[test]
3232 fn test_references_not_cloned() {
3233 use std::sync::Arc;
3234
3235 struct ExpensiveData {
3237 large_vec: Vec<u8>,
3238 }
3239
3240 impl ExpensiveData {
3241 fn new(size: usize) -> Self {
3242 Self {
3243 large_vec: vec![0u8; size],
3244 }
3245 }
3246
3247 fn size(&self) -> usize {
3248 self.large_vec.len()
3249 }
3250 }
3251
3252 struct Root {
3253 expensive: ExpensiveData,
3254 }
3255
3256 let root = Root {
3257 expensive: ExpensiveData::new(1_000_000), };
3259
3260 let expensive_kp = KpType::new(
3261 |r: &Root| Some(&r.expensive),
3262 |r: &mut Root| Some(&mut r.expensive),
3263 );
3264
3265 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3267 assert_eq!(size_kp.get(&root), Some(1_000_000));
3268
3269 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3271 assert!(large_filter.get(&root).is_some());
3272
3273 }
3275
3276 #[test]
3277 fn test_hof_with_arc_no_extra_clones() {
3278 use std::sync::Arc;
3279
3280 #[derive(Debug)]
3281 struct SharedData {
3282 value: String,
3283 }
3284
3285 struct Root {
3286 shared: Arc<SharedData>,
3287 }
3288
3289 let shared = Arc::new(SharedData {
3290 value: "shared".to_string(),
3291 });
3292
3293 assert_eq!(Arc::strong_count(&shared), 1);
3295
3296 {
3297 let root = Root {
3298 shared: Arc::clone(&shared),
3299 };
3300
3301 assert_eq!(Arc::strong_count(&shared), 2);
3303
3304 let shared_kp = KpType::new(
3305 |r: &Root| Some(&r.shared),
3306 |r: &mut Root| Some(&mut r.shared),
3307 );
3308
3309 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3311
3312 assert_eq!(value_kp.get(&root), Some(6));
3314 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3318 assert!(filtered.get(&root).is_some());
3319 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3324
3325 #[test]
3326 fn test_closure_captures_not_root_values() {
3327 use std::sync::Arc;
3328 use std::sync::atomic::{AtomicUsize, Ordering};
3329
3330 let call_count = Arc::new(AtomicUsize::new(0));
3332 let call_count_clone = Arc::clone(&call_count);
3333
3334 struct Root {
3335 value: i32,
3336 }
3337
3338 let root = Root { value: 42 };
3339
3340 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3341
3342 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3345 call_count_clone.fetch_add(1, Ordering::SeqCst);
3346 v * 2
3347 });
3348
3349 assert_eq!(doubled(&root), 84);
3351 assert_eq!(doubled(&root), 84);
3352 assert_eq!(doubled(&root), 84);
3353
3354 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3356
3357 }
3359
3360 #[test]
3361 fn test_static_with_borrowed_data() {
3362 struct Root {
3366 data: String,
3367 }
3368
3369 {
3370 let root = Root {
3371 data: "temporary".to_string(),
3372 };
3373
3374 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3375
3376 let len_kp = data_kp.map(|s: &String| s.len());
3378 assert_eq!(len_kp.get(&root), Some(9));
3379
3380 } }
3385
3386 #[test]
3387 fn test_multiple_hof_operations_no_accumulation() {
3388 use std::sync::Arc;
3389 use std::sync::atomic::{AtomicUsize, Ordering};
3390
3391 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3392
3393 struct Tracked {
3394 id: usize,
3395 }
3396
3397 impl Drop for Tracked {
3398 fn drop(&mut self) {
3399 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3400 }
3401 }
3402
3403 struct Root {
3404 values: Vec<Tracked>,
3405 }
3406
3407 DROP_COUNT.store(0, Ordering::SeqCst);
3408
3409 {
3410 let root = Root {
3411 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3412 };
3413
3414 let values_kp = KpType::new(
3415 |r: &Root| Some(&r.values),
3416 |r: &mut Root| Some(&mut r.values),
3417 );
3418
3419 let count = values_kp.count_items(|v| v.len());
3421 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3422 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3423 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3424
3425 assert_eq!(count(&root), Some(3));
3426 assert_eq!(sum(&root), Some(6));
3427 assert!(has_2(&root));
3428 assert!(all_positive(&root));
3429
3430 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3432 }
3433
3434 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3436 }
3437
3438 #[test]
3439 fn test_copy_bound_only_for_function_not_data() {
3440 #[derive(Debug)]
3444 struct NonCopyData {
3445 value: String,
3446 }
3447
3448 struct Root {
3449 data: NonCopyData,
3450 }
3451
3452 let root = Root {
3453 data: NonCopyData {
3454 value: "test".to_string(),
3455 },
3456 };
3457
3458 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3459
3460 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3463 assert_eq!(len_kp.get(&root), Some(4));
3464
3465 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3467 assert!(filtered.get(&root).is_some());
3468 }
3469
3470 #[test]
3471 fn test_no_memory_leak_with_cyclic_references() {
3472 use std::sync::atomic::{AtomicUsize, Ordering};
3473 use std::sync::{Arc, Weak};
3474
3475 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3476
3477 struct Node {
3478 id: usize,
3479 parent: Option<Weak<Node>>,
3480 }
3481
3482 impl Drop for Node {
3483 fn drop(&mut self) {
3484 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3485 }
3486 }
3487
3488 struct Root {
3489 node: Arc<Node>,
3490 }
3491
3492 DROP_COUNT.store(0, Ordering::SeqCst);
3493
3494 {
3495 let root = Root {
3496 node: Arc::new(Node {
3497 id: 1,
3498 parent: None,
3499 }),
3500 };
3501
3502 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3503
3504 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3506 assert_eq!(id_kp.get(&root), Some(1));
3507
3508 assert_eq!(Arc::strong_count(&root.node), 1);
3510
3511 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3513 }
3514
3515 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3517 }
3518
3519 #[test]
3520 fn test_hof_operations_are_zero_cost_abstractions() {
3521 struct Root {
3525 value: i32,
3526 }
3527
3528 let root = Root { value: 10 };
3529
3530 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3531
3532 let direct_result = value_kp.get(&root).map(|v| v * 2);
3534 assert_eq!(direct_result, Some(20));
3535
3536 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3538 let hof_result = mapped_kp.get(&root);
3539 assert_eq!(hof_result, Some(20));
3540
3541 assert_eq!(direct_result, hof_result);
3543 }
3544
3545 #[test]
3546 fn test_complex_closure_captures_allowed() {
3547 use std::sync::Arc;
3548
3549 struct Root {
3551 scores: Vec<i32>,
3552 }
3553
3554 let root = Root {
3555 scores: vec![85, 92, 78, 95, 88],
3556 };
3557
3558 let scores_kp = KpType::new(
3559 |r: &Root| Some(&r.scores),
3560 |r: &mut Root| Some(&mut r.scores),
3561 );
3562
3563 let threshold = 90;
3565 let multiplier = Arc::new(2);
3566
3567 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3569 let high: i32 = scores
3570 .iter()
3571 .filter(|&&s| s >= threshold)
3572 .map(|&s| s * *multiplier)
3573 .sum();
3574 acc + high
3575 });
3576
3577 assert_eq!(high_scores_doubled(&root), 374);
3579 }
3580
3581 #[test]
3585 fn test_pkp_filter_by_value_type() {
3586 use std::any::TypeId;
3587
3588 #[derive(Debug)]
3589 struct User {
3590 name: String,
3591 age: i32,
3592 score: f64,
3593 active: bool,
3594 }
3595
3596 let user = User {
3597 name: "Alice".to_string(),
3598 age: 30,
3599 score: 95.5,
3600 active: true,
3601 };
3602
3603 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3605 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3606 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3607 let active_kp = KpType::new(
3608 |u: &User| Some(&u.active),
3609 |u: &mut User| Some(&mut u.active),
3610 );
3611
3612 let all_keypaths: Vec<PKp<User>> = vec![
3614 PKp::new(name_kp),
3615 PKp::new(age_kp),
3616 PKp::new(score_kp),
3617 PKp::new(active_kp),
3618 ];
3619
3620 let string_kps: Vec<_> = all_keypaths
3622 .iter()
3623 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3624 .collect();
3625
3626 assert_eq!(string_kps.len(), 1);
3627 assert_eq!(
3628 string_kps[0].get_as::<String>(&user),
3629 Some(&"Alice".to_string())
3630 );
3631
3632 let i32_kps: Vec<_> = all_keypaths
3634 .iter()
3635 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3636 .collect();
3637
3638 assert_eq!(i32_kps.len(), 1);
3639 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3640
3641 let f64_kps: Vec<_> = all_keypaths
3643 .iter()
3644 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3645 .collect();
3646
3647 assert_eq!(f64_kps.len(), 1);
3648 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3649
3650 let bool_kps: Vec<_> = all_keypaths
3652 .iter()
3653 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3654 .collect();
3655
3656 assert_eq!(bool_kps.len(), 1);
3657 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3658 }
3659
3660 #[test]
3661 fn test_pkp_filter_by_struct_type() {
3662 use std::any::TypeId;
3663
3664 #[derive(Debug, PartialEq)]
3665 struct Address {
3666 street: String,
3667 city: String,
3668 }
3669
3670 #[derive(Debug)]
3671 struct User {
3672 name: String,
3673 age: i32,
3674 address: Address,
3675 }
3676
3677 let user = User {
3678 name: "Bob".to_string(),
3679 age: 25,
3680 address: Address {
3681 street: "123 Main St".to_string(),
3682 city: "NYC".to_string(),
3683 },
3684 };
3685
3686 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3688 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3689 let address_kp = KpType::new(
3690 |u: &User| Some(&u.address),
3691 |u: &mut User| Some(&mut u.address),
3692 );
3693
3694 let all_keypaths: Vec<PKp<User>> =
3695 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
3696
3697 let struct_kps: Vec<_> = all_keypaths
3699 .iter()
3700 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
3701 .collect();
3702
3703 assert_eq!(struct_kps.len(), 1);
3704 assert_eq!(
3705 struct_kps[0].get_as::<Address>(&user),
3706 Some(&Address {
3707 street: "123 Main St".to_string(),
3708 city: "NYC".to_string(),
3709 })
3710 );
3711
3712 let primitive_kps: Vec<_> = all_keypaths
3714 .iter()
3715 .filter(|pkp| {
3716 pkp.value_type_id() == TypeId::of::<String>()
3717 || pkp.value_type_id() == TypeId::of::<i32>()
3718 })
3719 .collect();
3720
3721 assert_eq!(primitive_kps.len(), 2);
3722 }
3723
3724 #[test]
3725 fn test_pkp_filter_by_arc_type() {
3726 use std::any::TypeId;
3727 use std::sync::Arc;
3728
3729 #[derive(Debug)]
3730 struct User {
3731 name: String,
3732 shared_data: Arc<String>,
3733 shared_number: Arc<i32>,
3734 }
3735
3736 let user = User {
3737 name: "Charlie".to_string(),
3738 shared_data: Arc::new("shared".to_string()),
3739 shared_number: Arc::new(42),
3740 };
3741
3742 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3744 let shared_data_kp = KpType::new(
3745 |u: &User| Some(&u.shared_data),
3746 |u: &mut User| Some(&mut u.shared_data),
3747 );
3748 let shared_number_kp = KpType::new(
3749 |u: &User| Some(&u.shared_number),
3750 |u: &mut User| Some(&mut u.shared_number),
3751 );
3752
3753 let all_keypaths: Vec<PKp<User>> = vec![
3754 PKp::new(name_kp),
3755 PKp::new(shared_data_kp),
3756 PKp::new(shared_number_kp),
3757 ];
3758
3759 let arc_string_kps: Vec<_> = all_keypaths
3761 .iter()
3762 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
3763 .collect();
3764
3765 assert_eq!(arc_string_kps.len(), 1);
3766 assert_eq!(
3767 arc_string_kps[0]
3768 .get_as::<Arc<String>>(&user)
3769 .map(|arc| arc.as_str()),
3770 Some("shared")
3771 );
3772
3773 let arc_i32_kps: Vec<_> = all_keypaths
3775 .iter()
3776 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
3777 .collect();
3778
3779 assert_eq!(arc_i32_kps.len(), 1);
3780 assert_eq!(
3781 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
3782 Some(42)
3783 );
3784
3785 let all_arc_kps: Vec<_> = all_keypaths
3787 .iter()
3788 .filter(|pkp| {
3789 pkp.value_type_id() == TypeId::of::<Arc<String>>()
3790 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
3791 })
3792 .collect();
3793
3794 assert_eq!(all_arc_kps.len(), 2);
3795 }
3796
3797 #[test]
3798 fn test_pkp_filter_by_box_type() {
3799 use std::any::TypeId;
3800
3801 #[derive(Debug)]
3802 struct User {
3803 name: String,
3804 boxed_value: Box<i32>,
3805 boxed_string: Box<String>,
3806 }
3807
3808 let user = User {
3809 name: "Diana".to_string(),
3810 boxed_value: Box::new(100),
3811 boxed_string: Box::new("boxed".to_string()),
3812 };
3813
3814 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3816 let boxed_value_kp = KpType::new(
3817 |u: &User| Some(&u.boxed_value),
3818 |u: &mut User| Some(&mut u.boxed_value),
3819 );
3820 let boxed_string_kp = KpType::new(
3821 |u: &User| Some(&u.boxed_string),
3822 |u: &mut User| Some(&mut u.boxed_string),
3823 );
3824
3825 let all_keypaths: Vec<PKp<User>> = vec![
3826 PKp::new(name_kp),
3827 PKp::new(boxed_value_kp),
3828 PKp::new(boxed_string_kp),
3829 ];
3830
3831 let box_i32_kps: Vec<_> = all_keypaths
3833 .iter()
3834 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
3835 .collect();
3836
3837 assert_eq!(box_i32_kps.len(), 1);
3838 assert_eq!(
3839 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
3840 Some(100)
3841 );
3842
3843 let box_string_kps: Vec<_> = all_keypaths
3845 .iter()
3846 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
3847 .collect();
3848
3849 assert_eq!(box_string_kps.len(), 1);
3850 assert_eq!(
3851 box_string_kps[0]
3852 .get_as::<Box<String>>(&user)
3853 .map(|b| b.as_str()),
3854 Some("boxed")
3855 );
3856 }
3857
3858 #[test]
3859 fn test_akp_filter_by_root_and_value_type() {
3860 use std::any::TypeId;
3861
3862 #[derive(Debug)]
3863 struct User {
3864 name: String,
3865 age: i32,
3866 }
3867
3868 #[derive(Debug)]
3869 struct Product {
3870 title: String,
3871 price: f64,
3872 }
3873
3874 let user = User {
3875 name: "Eve".to_string(),
3876 age: 28,
3877 };
3878
3879 let product = Product {
3880 title: "Book".to_string(),
3881 price: 19.99,
3882 };
3883
3884 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3886 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3887 let product_title_kp = KpType::new(
3888 |p: &Product| Some(&p.title),
3889 |p: &mut Product| Some(&mut p.title),
3890 );
3891 let product_price_kp = KpType::new(
3892 |p: &Product| Some(&p.price),
3893 |p: &mut Product| Some(&mut p.price),
3894 );
3895
3896 let all_keypaths: Vec<AKp> = vec![
3897 AKp::new(user_name_kp),
3898 AKp::new(user_age_kp),
3899 AKp::new(product_title_kp),
3900 AKp::new(product_price_kp),
3901 ];
3902
3903 let user_kps: Vec<_> = all_keypaths
3905 .iter()
3906 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
3907 .collect();
3908
3909 assert_eq!(user_kps.len(), 2);
3910
3911 let product_kps: Vec<_> = all_keypaths
3913 .iter()
3914 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
3915 .collect();
3916
3917 assert_eq!(product_kps.len(), 2);
3918
3919 let string_value_kps: Vec<_> = all_keypaths
3921 .iter()
3922 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
3923 .collect();
3924
3925 assert_eq!(string_value_kps.len(), 2);
3926
3927 let user_string_kps: Vec<_> = all_keypaths
3929 .iter()
3930 .filter(|akp| {
3931 akp.root_type_id() == TypeId::of::<User>()
3932 && akp.value_type_id() == TypeId::of::<String>()
3933 })
3934 .collect();
3935
3936 assert_eq!(user_string_kps.len(), 1);
3937 assert_eq!(
3938 user_string_kps[0].get_as::<User, String>(&user),
3939 Some(Some(&"Eve".to_string()))
3940 );
3941
3942 let product_f64_kps: Vec<_> = all_keypaths
3944 .iter()
3945 .filter(|akp| {
3946 akp.root_type_id() == TypeId::of::<Product>()
3947 && akp.value_type_id() == TypeId::of::<f64>()
3948 })
3949 .collect();
3950
3951 assert_eq!(product_f64_kps.len(), 1);
3952 assert_eq!(
3953 product_f64_kps[0].get_as::<Product, f64>(&product),
3954 Some(Some(&19.99))
3955 );
3956 }
3957
3958 #[test]
3959 fn test_akp_filter_by_arc_root_type() {
3960 use std::any::TypeId;
3961 use std::sync::Arc;
3962
3963 #[derive(Debug)]
3964 struct User {
3965 name: String,
3966 }
3967
3968 #[derive(Debug)]
3969 struct Product {
3970 title: String,
3971 }
3972
3973 let user = User {
3974 name: "Frank".to_string(),
3975 };
3976 let product = Product {
3977 title: "Laptop".to_string(),
3978 };
3979
3980 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3982 let product_title_kp = KpType::new(
3983 |p: &Product| Some(&p.title),
3984 |p: &mut Product| Some(&mut p.title),
3985 );
3986
3987 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
3989 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
3990
3991 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
3992
3993 let arc_user_kps: Vec<_> = all_keypaths
3995 .iter()
3996 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
3997 .collect();
3998
3999 assert_eq!(arc_user_kps.len(), 1);
4000
4001 let arc_user = Arc::new(user);
4003 assert_eq!(
4004 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4005 Some(Some(&"Frank".to_string()))
4006 );
4007
4008 let arc_product_kps: Vec<_> = all_keypaths
4010 .iter()
4011 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4012 .collect();
4013
4014 assert_eq!(arc_product_kps.len(), 1);
4015
4016 let arc_product = Arc::new(product);
4018 assert_eq!(
4019 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4020 Some(Some(&"Laptop".to_string()))
4021 );
4022 }
4023
4024 #[test]
4025 fn test_akp_filter_by_box_root_type() {
4026 use std::any::TypeId;
4027
4028 #[derive(Debug)]
4029 struct Config {
4030 setting: String,
4031 }
4032
4033 let config = Config {
4034 setting: "enabled".to_string(),
4035 };
4036
4037 let config_kp1 = KpType::new(
4039 |c: &Config| Some(&c.setting),
4040 |c: &mut Config| Some(&mut c.setting),
4041 );
4042 let config_kp2 = KpType::new(
4043 |c: &Config| Some(&c.setting),
4044 |c: &mut Config| Some(&mut c.setting),
4045 );
4046
4047 let regular_akp = AKp::new(config_kp1);
4049 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4050
4051 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4052
4053 let config_kps: Vec<_> = all_keypaths
4055 .iter()
4056 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4057 .collect();
4058
4059 assert_eq!(config_kps.len(), 1);
4060 assert_eq!(
4061 config_kps[0].get_as::<Config, String>(&config),
4062 Some(Some(&"enabled".to_string()))
4063 );
4064
4065 let box_config_kps: Vec<_> = all_keypaths
4067 .iter()
4068 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4069 .collect();
4070
4071 assert_eq!(box_config_kps.len(), 1);
4072
4073 let box_config = Box::new(Config {
4075 setting: "enabled".to_string(),
4076 });
4077 assert_eq!(
4078 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4079 Some(Some(&"enabled".to_string()))
4080 );
4081 }
4082
4083 #[test]
4084 fn test_mixed_collection_type_filtering() {
4085 use std::any::TypeId;
4086 use std::sync::Arc;
4087
4088 #[derive(Debug)]
4089 struct User {
4090 name: String,
4091 email: String,
4092 }
4093
4094 #[derive(Debug)]
4095 struct Product {
4096 title: String,
4097 sku: String,
4098 }
4099
4100 let user = User {
4101 name: "Grace".to_string(),
4102 email: "grace@example.com".to_string(),
4103 };
4104
4105 let product = Product {
4106 title: "Widget".to_string(),
4107 sku: "WID-001".to_string(),
4108 };
4109
4110 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4112 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4113 let user_email_kp1 =
4114 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4115 let user_email_kp2 =
4116 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4117 let product_title_kp = KpType::new(
4118 |p: &Product| Some(&p.title),
4119 |p: &mut Product| Some(&mut p.title),
4120 );
4121 let product_sku_kp = KpType::new(
4122 |p: &Product| Some(&p.sku),
4123 |p: &mut Product| Some(&mut p.sku),
4124 );
4125
4126 let all_keypaths: Vec<AKp> = vec![
4127 AKp::new(user_name_kp1),
4128 AKp::new(user_email_kp1),
4129 AKp::new(product_title_kp),
4130 AKp::new(product_sku_kp),
4131 AKp::new(user_name_kp2).for_arc::<User>(),
4132 AKp::new(user_email_kp2).for_box::<User>(),
4133 ];
4134
4135 let string_value_kps: Vec<_> = all_keypaths
4137 .iter()
4138 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4139 .collect();
4140
4141 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4145 .iter()
4146 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4147 .collect();
4148
4149 assert_eq!(user_root_kps.len(), 2);
4150
4151 let arc_user_kps: Vec<_> = all_keypaths
4153 .iter()
4154 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4155 .collect();
4156
4157 assert_eq!(arc_user_kps.len(), 1);
4158
4159 let box_user_kps: Vec<_> = all_keypaths
4161 .iter()
4162 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4163 .collect();
4164
4165 assert_eq!(box_user_kps.len(), 1);
4166
4167 let product_kps: Vec<_> = all_keypaths
4169 .iter()
4170 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4171 .collect();
4172
4173 assert_eq!(product_kps.len(), 2);
4174
4175 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4177 assert!(user_value.is_some());
4178 assert!(user_value.unwrap().is_some());
4179 }
4180
4181 #[test]
4186 fn test_kp_with_pin() {
4187 use std::pin::Pin;
4188
4189 #[derive(Debug)]
4193 struct SelfReferential {
4194 value: String,
4195 ptr_to_value: *const String, }
4197
4198 impl SelfReferential {
4199 fn new(s: String) -> Self {
4200 let mut sr = Self {
4201 value: s,
4202 ptr_to_value: std::ptr::null(),
4203 };
4204 sr.ptr_to_value = &sr.value as *const String;
4206 sr
4207 }
4208
4209 fn get_value(&self) -> &str {
4210 &self.value
4211 }
4212 }
4213
4214 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4216 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4217
4218 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4220 |p: &Pin<Box<SelfReferential>>| {
4221 Some(&p.as_ref().get_ref().value)
4223 },
4224 |p: &mut Pin<Box<SelfReferential>>| {
4225 unsafe {
4228 let sr = Pin::get_unchecked_mut(p.as_mut());
4229 Some(&mut sr.value)
4230 }
4231 },
4232 );
4233
4234 let result = kp.get(&pinned);
4236 assert_eq!(result, Some(&"pinned_data".to_string()));
4237
4238 assert_eq!(pinned.get_value(), "pinned_data");
4240 }
4241
4242 #[test]
4243 fn test_kp_with_pin_arc() {
4244 use std::pin::Pin;
4245 use std::sync::Arc;
4246
4247 struct AsyncState {
4248 status: String,
4249 data: Vec<i32>,
4250 }
4251
4252 let state = AsyncState {
4254 status: "ready".to_string(),
4255 data: vec![1, 2, 3, 4, 5],
4256 };
4257
4258 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4259
4260 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4262 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4263 |_: &mut Pin<Arc<AsyncState>>| {
4264 None::<&mut String>
4266 },
4267 );
4268
4269 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4271 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4272 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4273 );
4274
4275 let status = status_kp.get(&pinned_arc);
4276 assert_eq!(status, Some(&"ready".to_string()));
4277
4278 let data = data_kp.get(&pinned_arc);
4279 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4280 }
4281
4282 #[test]
4283 fn test_kp_with_maybe_uninit() {
4284 use std::mem::MaybeUninit;
4285
4286 struct Config {
4290 name: MaybeUninit<String>,
4291 value: MaybeUninit<i32>,
4292 initialized: bool,
4293 }
4294
4295 impl Config {
4296 fn new_uninit() -> Self {
4297 Self {
4298 name: MaybeUninit::uninit(),
4299 value: MaybeUninit::uninit(),
4300 initialized: false,
4301 }
4302 }
4303
4304 fn init(&mut self, name: String, value: i32) {
4305 self.name.write(name);
4306 self.value.write(value);
4307 self.initialized = true;
4308 }
4309
4310 fn get_name(&self) -> Option<&String> {
4311 if self.initialized {
4312 unsafe { Some(self.name.assume_init_ref()) }
4313 } else {
4314 None
4315 }
4316 }
4317
4318 fn get_value(&self) -> Option<&i32> {
4319 if self.initialized {
4320 unsafe { Some(self.value.assume_init_ref()) }
4321 } else {
4322 None
4323 }
4324 }
4325 }
4326
4327 let name_kp: KpType<Config, String> = Kp::new(
4329 |c: &Config| c.get_name(),
4330 |c: &mut Config| {
4331 if c.initialized {
4332 unsafe { Some(c.name.assume_init_mut()) }
4333 } else {
4334 None
4335 }
4336 },
4337 );
4338
4339 let value_kp: KpType<Config, i32> = Kp::new(
4340 |c: &Config| c.get_value(),
4341 |c: &mut Config| {
4342 if c.initialized {
4343 unsafe { Some(c.value.assume_init_mut()) }
4344 } else {
4345 None
4346 }
4347 },
4348 );
4349
4350 let uninit_config = Config::new_uninit();
4352 assert_eq!(name_kp.get(&uninit_config), None);
4353 assert_eq!(value_kp.get(&uninit_config), None);
4354
4355 let mut init_config = Config::new_uninit();
4357 init_config.init("test_config".to_string(), 42);
4358
4359 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4360 assert_eq!(value_kp.get(&init_config), Some(&42));
4361
4362 if let Some(val) = value_kp.get_mut(&mut init_config) {
4364 *val = 100;
4365 }
4366
4367 assert_eq!(value_kp.get(&init_config), Some(&100));
4368 }
4369
4370 #[test]
4371 fn test_kp_with_weak() {
4372 use std::sync::{Arc, Weak};
4373
4374 #[derive(Debug, Clone)]
4378 struct Node {
4379 value: i32,
4380 }
4381
4382 struct NodeWithParent {
4383 value: i32,
4384 parent: Option<Arc<Node>>, }
4386
4387 let parent = Arc::new(Node { value: 100 });
4388
4389 let child = NodeWithParent {
4390 value: 42,
4391 parent: Some(parent.clone()),
4392 };
4393
4394 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4396 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4397 |_: &mut NodeWithParent| None::<&mut i32>,
4398 );
4399
4400 let parent_val = parent_value_kp.get(&child);
4402 assert_eq!(parent_val, Some(&100));
4403 }
4404
4405 #[test]
4406 fn test_kp_with_rc_weak() {
4407 use std::rc::Rc;
4408
4409 struct TreeNode {
4412 value: String,
4413 parent: Option<Rc<TreeNode>>, }
4415
4416 let root = Rc::new(TreeNode {
4417 value: "root".to_string(),
4418 parent: None,
4419 });
4420
4421 let child1 = TreeNode {
4422 value: "child1".to_string(),
4423 parent: Some(root.clone()),
4424 };
4425
4426 let child2 = TreeNode {
4427 value: "child2".to_string(),
4428 parent: Some(root.clone()),
4429 };
4430
4431 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4433 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4434 |_: &mut TreeNode| None::<&mut String>,
4435 );
4436
4437 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4439 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4440
4441 assert_eq!(parent_name_kp.get(&root), None);
4443 }
4444
4445 #[test]
4446 fn test_kp_with_complex_weak_structure() {
4447 use std::sync::Arc;
4448
4449 struct Cache {
4452 data: String,
4453 backup: Option<Arc<Cache>>, }
4455
4456 let primary = Arc::new(Cache {
4457 data: "primary_data".to_string(),
4458 backup: None,
4459 });
4460
4461 let backup = Arc::new(Cache {
4462 data: "backup_data".to_string(),
4463 backup: Some(primary.clone()),
4464 });
4465
4466 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4468 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4469 |_: &mut Arc<Cache>| None::<&mut String>,
4470 );
4471
4472 let data = backup_data_kp.get(&backup);
4474 assert_eq!(data, Some(&"primary_data".to_string()));
4475
4476 let no_backup = backup_data_kp.get(&primary);
4478 assert_eq!(no_backup, None);
4479 }
4480
4481 #[test]
4482 fn test_kp_chain_with_pin_and_arc() {
4483 use std::pin::Pin;
4484 use std::sync::Arc;
4485
4486 struct Outer {
4489 inner: Arc<Inner>,
4490 }
4491
4492 struct Inner {
4493 value: String,
4494 }
4495
4496 let outer = Outer {
4497 inner: Arc::new(Inner {
4498 value: "nested_value".to_string(),
4499 }),
4500 };
4501
4502 let pinned_outer = Box::pin(outer);
4503
4504 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4506 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4507 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4508 );
4509
4510 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4512 |a: &Arc<Inner>| Some(&a.value),
4513 |_: &mut Arc<Inner>| None::<&mut String>,
4514 );
4515
4516 let chained = to_inner.then(to_value);
4518
4519 let result = chained.get(&pinned_outer);
4520 assert_eq!(result, Some(&"nested_value".to_string()));
4521 }
4522
4523 #[test]
4524 fn test_kp_with_maybe_uninit_array() {
4525 use std::mem::MaybeUninit;
4526
4527 struct Buffer {
4531 data: [MaybeUninit<u8>; 10],
4532 len: usize,
4533 }
4534
4535 impl Buffer {
4536 fn new() -> Self {
4537 Self {
4538 data: unsafe { MaybeUninit::uninit().assume_init() },
4539 len: 0,
4540 }
4541 }
4542
4543 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4544 if self.len >= self.data.len() {
4545 return Err("Buffer full");
4546 }
4547 self.data[self.len].write(byte);
4548 self.len += 1;
4549 Ok(())
4550 }
4551
4552 fn get(&self, idx: usize) -> Option<&u8> {
4553 if idx < self.len {
4554 unsafe { Some(self.data[idx].assume_init_ref()) }
4555 } else {
4556 None
4557 }
4558 }
4559
4560 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4561 if idx < self.len {
4562 unsafe { Some(self.data[idx].assume_init_mut()) }
4563 } else {
4564 None
4565 }
4566 }
4567 }
4568
4569 let len_kp: KpType<Buffer, usize> =
4571 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4572
4573 let mut buffer = Buffer::new();
4574
4575 assert_eq!(len_kp.get(&buffer), Some(&0));
4577
4578 buffer.push(1).unwrap();
4580 buffer.push(2).unwrap();
4581 buffer.push(3).unwrap();
4582
4583 assert_eq!(len_kp.get(&buffer), Some(&3));
4585
4586 assert_eq!(buffer.get(0), Some(&1));
4588 assert_eq!(buffer.get(1), Some(&2));
4589 assert_eq!(buffer.get(2), Some(&3));
4590 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4594 *elem = 20;
4595 }
4596 assert_eq!(buffer.get(1), Some(&20));
4597 }
4598
4599 #[test]
4600 fn test_kp_then_lock_deep_structs() {
4601 use std::sync::{Arc, Mutex};
4602
4603 #[derive(Clone)]
4604 struct Root {
4605 guard: Arc<Mutex<Level1>>,
4606 }
4607 #[derive(Clone)]
4608 struct Level1 {
4609 name: String,
4610 nested: Level2,
4611 }
4612 #[derive(Clone)]
4613 struct Level2 {
4614 count: i32,
4615 }
4616
4617 let root = Root {
4618 guard: Arc::new(Mutex::new(Level1 {
4619 name: "deep".to_string(),
4620 nested: Level2 { count: 42 },
4621 })),
4622 };
4623
4624 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4625 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4626
4627 let lock_kp = {
4628 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
4629 Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
4630 let next: KpType<Level1, Level1> =
4631 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4632 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4633 };
4634
4635 let chained = kp_to_guard.then_lock(lock_kp);
4636 let level1 = chained.get(&root);
4637 assert!(level1.is_some());
4638 assert_eq!(level1.unwrap().name, "deep");
4639 assert_eq!(level1.unwrap().nested.count, 42);
4640
4641 let mut_root = &mut root.clone();
4642 let mut_level1 = chained.get_mut(mut_root);
4643 assert!(mut_level1.is_some());
4644 mut_level1.unwrap().nested.count = 99;
4645 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4646 }
4647
4648 #[test]
4649 fn test_kp_then_lock_with_enum() {
4650 use std::sync::{Arc, Mutex};
4651
4652 #[derive(Clone)]
4653 enum Message {
4654 Request(LevelA),
4655 Response(i32),
4656 }
4657 #[derive(Clone)]
4658 struct LevelA {
4659 data: Arc<Mutex<i32>>,
4660 }
4661
4662 struct RootWithEnum {
4663 msg: Arc<Mutex<Message>>,
4664 }
4665
4666 let root = RootWithEnum {
4667 msg: Arc::new(Mutex::new(Message::Request(LevelA {
4668 data: Arc::new(Mutex::new(100)),
4669 }))),
4670 };
4671
4672 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
4673 Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
4674
4675 let lock_kp_msg = {
4676 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
4677 Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
4678 let next: KpType<Message, Message> =
4679 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4680 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4681 };
4682
4683 let chained = kp_msg.then_lock(lock_kp_msg);
4684 let msg = chained.get(&root);
4685 assert!(msg.is_some());
4686 match msg.unwrap() {
4687 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
4688 Message::Response(_) => panic!("expected Request"),
4689 }
4690 }
4691
4692 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4693 #[tokio::test]
4694 async fn test_kp_then_async_deep_chain() {
4695 use std::sync::Arc;
4696 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4697
4698 #[derive(Clone)]
4699 struct Root {
4700 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
4701 }
4702 #[derive(Clone)]
4703 struct Level1 {
4704 value: i32,
4705 }
4706
4707 let root = Root {
4708 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
4709 };
4710
4711 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
4712 |r: &Root| Some(&r.tokio_guard),
4713 |r: &mut Root| Some(&mut r.tokio_guard),
4714 );
4715
4716 let async_kp = {
4717 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
4718 Kp::new(
4719 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
4720 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
4721 );
4722 let next: KpType<Level1, Level1> =
4723 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4724 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4725 };
4726
4727 let chained = kp_to_guard.then_async(async_kp);
4728 let level1 = chained.get(&root).await;
4729 assert!(level1.is_some());
4730 assert_eq!(level1.unwrap().value, 7);
4731 }
4732
4733 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4736 #[tokio::test]
4737 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
4738 use std::sync::{Arc, Mutex};
4739 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4740 use crate::lock::{LockKp, ArcMutexAccess};
4741
4742 #[derive(Clone)]
4744 struct Root {
4745 sync_mutex: Arc<Mutex<Level1>>,
4746 }
4747 #[derive(Clone)]
4749 struct Level1 {
4750 inner: Level2,
4751 }
4752 #[derive(Clone)]
4754 struct Level2 {
4755 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
4756 }
4757 #[derive(Clone)]
4759 struct Level3 {
4760 leaf: i32,
4761 }
4762
4763 let mut root = Root {
4764 sync_mutex: Arc::new(Mutex::new(Level1 {
4765 inner: Level2 {
4766 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
4767 },
4768 })),
4769 };
4770
4771 let identity_l1: KpType<Level1, Level1> =
4773 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4774 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
4775 Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
4776 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
4777
4778 let kp_l1_inner: KpType<Level1, Level2> =
4780 Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
4781
4782 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
4784 |l: &Level2| Some(&l.tokio_mutex),
4785 |l: &mut Level2| Some(&mut l.tokio_mutex),
4786 );
4787
4788 let async_l3 = {
4790 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
4791 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
4792 let next: KpType<Level3, Level3> =
4793 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
4794 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4795 };
4796
4797 let kp_l3_leaf: KpType<Level3, i32> =
4799 Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
4800
4801 let step1 = lock_root_to_l1.then(kp_l1_inner);
4803 let step2 = step1.then(kp_l2_tokio);
4804 let step3 = step2.then_async(async_l3);
4805 let deep_chain = step3.then(kp_l3_leaf);
4806
4807 let leaf = deep_chain.get(&root).await;
4809 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
4810 assert_eq!(leaf, Some(&100));
4811
4812 let mut root_mut = root.clone();
4814 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
4815 assert!(leaf_mut.is_some());
4816 *leaf_mut.unwrap() = 99;
4817
4818 let leaf_after = deep_chain.get(&root_mut).await;
4820 assert_eq!(leaf_after, Some(&99));
4821 }
4822}