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
31
32
33#[cfg(feature = "pin_project")]
78pub mod pin;
79
80pub trait KeyPathValueTarget {
84 type Target: Sized;
85}
86impl<T> KeyPathValueTarget for &T {
87 type Target = T;
88}
89impl<T> KeyPathValueTarget for &mut T {
90 type Target = T;
91}
92
93pub type KpDynamic<R, V> = Kp<
94 R,
95 V,
96 &'static R,
97 &'static V,
98 &'static mut R,
99 &'static mut V,
100 Box<dyn for<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
101 Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
102>;
103
104pub type KpType<'a, R, V> = Kp<
105 R,
106 V,
107 &'a R,
108 &'a V,
109 &'a mut R,
110 &'a mut V,
111 for<'b> fn(&'b R) -> Option<&'b V>,
112 for<'b> fn(&'b mut R) -> Option<&'b mut V>,
113>;
114
115impl<'a, R, V> KpType<'a, R, V>
116where
117 'a: 'static,
118{
119 #[inline]
122 pub fn to_dynamic(self) -> KpDynamic<R, V> {
123 self.into()
124 }
125}
126
127impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V>
128where
129 'a: 'static,
130 R: 'static,
131 V: 'static,
132{
133 #[inline]
134 fn from(kp: KpType<'a, R, V>) -> Self {
135 let get_fn = kp.get;
136 let set_fn = kp.set;
137 Kp::new(
138 Box::new(move |t: &R| get_fn(t)),
139 Box::new(move |t: &mut R| set_fn(t)),
140 )
141 }
142}
143
144pub type KpComposed<R, V> = Kp<
180 R,
181 V,
182 &'static R,
183 &'static V,
184 &'static mut R,
185 &'static mut V,
186 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
187 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
188>;
189
190impl<R, V> Kp<
191 R,
192 V,
193 &'static R,
194 &'static V,
195 &'static mut R,
196 &'static mut V,
197 Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
198 Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
199> {
200 pub fn from_closures<G, S>(get: G, set: S) -> Self
203 where
204 G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
205 S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
206 {
207 Self::new(Box::new(get), Box::new(set))
208 }
209}
210
211pub struct AKp {
212 getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
213 root_type_id: TypeId,
214 value_type_id: TypeId,
215}
216
217impl AKp {
218 pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
220 where
221 R: Any + 'static,
222 V: Any + 'static,
223 {
224 let root_type_id = TypeId::of::<R>();
225 let value_type_id = TypeId::of::<V>();
226 let getter_fn = keypath.get;
227
228 Self {
229 getter: Rc::new(move |any: &dyn Any| {
230 if let Some(root) = any.downcast_ref::<R>() {
231 getter_fn(root).map(|value: &V| value as &dyn Any)
232 } else {
233 None
234 }
235 }),
236 root_type_id,
237 value_type_id,
238 }
239 }
240
241 pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
243 where
244 R: Any + 'static,
245 V: Any + 'static,
246 {
247 Self::new(keypath)
248 }
249
250 pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
252 (self.getter)(root)
253 }
254
255 pub fn root_type_id(&self) -> TypeId {
257 self.root_type_id
258 }
259
260 pub fn value_type_id(&self) -> TypeId {
262 self.value_type_id
263 }
264
265 pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
267 if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
268 {
269 Some(
270 self.get(root as &dyn Any)
271 .and_then(|any| any.downcast_ref::<Value>()),
272 )
273 } else {
274 None
275 }
276 }
277
278 pub fn kind_name(&self) -> String {
280 format!("{:?}", self.value_type_id)
281 }
282
283 pub fn root_kind_name(&self) -> String {
285 format!("{:?}", self.root_type_id)
286 }
287
288 pub fn for_arc<Root>(&self) -> AKp
290 where
291 Root: Any + 'static,
292 {
293 let value_type_id = self.value_type_id;
294 let getter = self.getter.clone();
295
296 AKp {
297 getter: Rc::new(move |any: &dyn Any| {
298 if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
299 getter(arc.as_ref() as &dyn Any)
300 } else {
301 None
302 }
303 }),
304 root_type_id: TypeId::of::<Arc<Root>>(),
305 value_type_id,
306 }
307 }
308
309 pub fn for_box<Root>(&self) -> AKp
311 where
312 Root: Any + 'static,
313 {
314 let value_type_id = self.value_type_id;
315 let getter = self.getter.clone();
316
317 AKp {
318 getter: Rc::new(move |any: &dyn Any| {
319 if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
320 getter(boxed.as_ref() as &dyn Any)
321 } else {
322 None
323 }
324 }),
325 root_type_id: TypeId::of::<Box<Root>>(),
326 value_type_id,
327 }
328 }
329
330 pub fn for_rc<Root>(&self) -> AKp
332 where
333 Root: Any + 'static,
334 {
335 let value_type_id = self.value_type_id;
336 let getter = self.getter.clone();
337
338 AKp {
339 getter: Rc::new(move |any: &dyn Any| {
340 if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
341 getter(rc.as_ref() as &dyn Any)
342 } else {
343 None
344 }
345 }),
346 root_type_id: TypeId::of::<Rc<Root>>(),
347 value_type_id,
348 }
349 }
350
351 pub fn for_option<Root>(&self) -> AKp
353 where
354 Root: Any + 'static,
355 {
356 let value_type_id = self.value_type_id;
357 let getter = self.getter.clone();
358
359 AKp {
360 getter: Rc::new(move |any: &dyn Any| {
361 if let Some(opt) = any.downcast_ref::<Option<Root>>() {
362 opt.as_ref().and_then(|root| getter(root as &dyn Any))
363 } else {
364 None
365 }
366 }),
367 root_type_id: TypeId::of::<Option<Root>>(),
368 value_type_id,
369 }
370 }
371
372 pub fn for_result<Root, E>(&self) -> AKp
374 where
375 Root: Any + 'static,
376 E: Any + 'static,
377 {
378 let value_type_id = self.value_type_id;
379 let getter = self.getter.clone();
380
381 AKp {
382 getter: Rc::new(move |any: &dyn Any| {
383 if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
384 result
385 .as_ref()
386 .ok()
387 .and_then(|root| getter(root as &dyn Any))
388 } else {
389 None
390 }
391 }),
392 root_type_id: TypeId::of::<Result<Root, E>>(),
393 value_type_id,
394 }
395 }
396
397 pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
410 where
411 Root: Any + 'static,
412 OrigValue: Any + 'static,
413 MappedValue: Any + 'static,
414 F: Fn(&OrigValue) -> MappedValue + 'static,
415 {
416 let orig_root_type_id = self.root_type_id;
417 let orig_value_type_id = self.value_type_id;
418 let getter = self.getter.clone();
419 let mapped_type_id = TypeId::of::<MappedValue>();
420
421 AKp {
422 getter: Rc::new(move |any_root: &dyn Any| {
423 if any_root.type_id() == orig_root_type_id {
425 getter(any_root).and_then(|any_value| {
426 if orig_value_type_id == TypeId::of::<OrigValue>() {
428 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
429 let mapped = mapper(orig_val);
430 Box::leak(Box::new(mapped)) as &dyn Any
432 })
433 } else {
434 None
435 }
436 })
437 } else {
438 None
439 }
440 }),
441 root_type_id: orig_root_type_id,
442 value_type_id: mapped_type_id,
443 }
444 }
445
446 pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
459 where
460 Root: Any + 'static,
461 Value: Any + 'static,
462 F: Fn(&Value) -> bool + 'static,
463 {
464 let orig_root_type_id = self.root_type_id;
465 let orig_value_type_id = self.value_type_id;
466 let getter = self.getter.clone();
467
468 AKp {
469 getter: Rc::new(move |any_root: &dyn Any| {
470 if any_root.type_id() == orig_root_type_id {
472 getter(any_root).filter(|any_value| {
473 if orig_value_type_id == TypeId::of::<Value>() {
475 any_value
476 .downcast_ref::<Value>()
477 .map(|val| predicate(val))
478 .unwrap_or(false)
479 } else {
480 false
481 }
482 })
483 } else {
484 None
485 }
486 }),
487 root_type_id: orig_root_type_id,
488 value_type_id: orig_value_type_id,
489 }
490 }
491}
492pub struct PKp<Root> {
493 getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
494 value_type_id: TypeId,
495 _phantom: std::marker::PhantomData<Root>,
496}
497
498impl<Root> PKp<Root>
499where
500 Root: 'static,
501{
502 pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
504 where
505 V: Any + 'static,
506 {
507 let value_type_id = TypeId::of::<V>();
508 let getter_fn = keypath.get;
509
510 Self {
511 getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
512 value_type_id,
513 _phantom: std::marker::PhantomData,
514 }
515 }
516
517 pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
519 where
520 V: Any + 'static,
521 {
522 Self::new(keypath)
523 }
524
525 pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
527 (self.getter)(root)
528 }
529
530 pub fn value_type_id(&self) -> TypeId {
532 self.value_type_id
533 }
534
535 pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
537 if self.value_type_id == TypeId::of::<Value>() {
538 self.get(root).and_then(|any| any.downcast_ref::<Value>())
539 } else {
540 None
541 }
542 }
543
544 pub fn kind_name(&self) -> String {
546 format!("{:?}", self.value_type_id)
547 }
548
549 pub fn for_arc(&self) -> PKp<Arc<Root>> {
551 let getter = self.getter.clone();
552 let value_type_id = self.value_type_id;
553
554 PKp {
555 getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
556 value_type_id,
557 _phantom: std::marker::PhantomData,
558 }
559 }
560
561 pub fn for_box(&self) -> PKp<Box<Root>> {
563 let getter = self.getter.clone();
564 let value_type_id = self.value_type_id;
565
566 PKp {
567 getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
568 value_type_id,
569 _phantom: std::marker::PhantomData,
570 }
571 }
572
573 pub fn for_rc(&self) -> PKp<Rc<Root>> {
575 let getter = self.getter.clone();
576 let value_type_id = self.value_type_id;
577
578 PKp {
579 getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
580 value_type_id,
581 _phantom: std::marker::PhantomData,
582 }
583 }
584
585 pub fn for_option(&self) -> PKp<Option<Root>> {
587 let getter = self.getter.clone();
588 let value_type_id = self.value_type_id;
589
590 PKp {
591 getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
592 value_type_id,
593 _phantom: std::marker::PhantomData,
594 }
595 }
596
597 pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
599 where
600 E: 'static,
601 {
602 let getter = self.getter.clone();
603 let value_type_id = self.value_type_id;
604
605 PKp {
606 getter: Rc::new(move |result: &Result<Root, E>| {
607 result.as_ref().ok().and_then(|root| getter(root))
608 }),
609 value_type_id,
610 _phantom: std::marker::PhantomData,
611 }
612 }
613
614 pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
628 where
629 OrigValue: Any + 'static,
630 MappedValue: Any + 'static,
631 F: Fn(&OrigValue) -> MappedValue + 'static,
632 {
633 let orig_type_id = self.value_type_id;
634 let getter = self.getter.clone();
635 let mapped_type_id = TypeId::of::<MappedValue>();
636
637 PKp {
638 getter: Rc::new(move |root: &Root| {
639 getter(root).and_then(|any_value| {
640 if orig_type_id == TypeId::of::<OrigValue>() {
642 any_value.downcast_ref::<OrigValue>().map(|orig_val| {
643 let mapped = mapper(orig_val);
644 Box::leak(Box::new(mapped)) as &dyn Any
647 })
648 } else {
649 None
650 }
651 })
652 }),
653 value_type_id: mapped_type_id,
654 _phantom: std::marker::PhantomData,
655 }
656 }
657
658 pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
672 where
673 Value: Any + 'static,
674 F: Fn(&Value) -> bool + 'static,
675 {
676 let orig_type_id = self.value_type_id;
677 let getter = self.getter.clone();
678
679 PKp {
680 getter: Rc::new(move |root: &Root| {
681 getter(root).filter(|any_value| {
682 if orig_type_id == TypeId::of::<Value>() {
684 any_value
685 .downcast_ref::<Value>()
686 .map(|val| predicate(val))
687 .unwrap_or(false)
688 } else {
689 false
690 }
691 })
692 }),
693 value_type_id: orig_type_id,
694 _phantom: std::marker::PhantomData,
695 }
696 }
697}
698
699#[derive(Clone)]
713pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
714where
715 Root: std::borrow::Borrow<R>,
716 MutRoot: std::borrow::BorrowMut<R>,
717 MutValue: std::borrow::BorrowMut<V>,
718 G: Fn(Root) -> Option<Value>,
719 S: Fn(MutRoot) -> Option<MutValue>,
720{
721 pub(crate) get: G,
723 pub(crate) set: S,
725 _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
726}
727
728unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Send for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
730where
731 Root: std::borrow::Borrow<R>,
732 MutRoot: std::borrow::BorrowMut<R>,
733 MutValue: std::borrow::BorrowMut<V>,
734 G: Fn(Root) -> Option<Value> + Send,
735 S: Fn(MutRoot) -> Option<MutValue> + Send,
736{
737}
738unsafe impl<R, V, Root, Value, MutRoot, MutValue, G, S> Sync for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
739where
740 Root: std::borrow::Borrow<R>,
741 MutRoot: std::borrow::BorrowMut<R>,
742 MutValue: std::borrow::BorrowMut<V>,
743 G: Fn(Root) -> Option<Value> + Sync,
744 S: Fn(MutRoot) -> Option<MutValue> + Sync,
745{
746}
747
748impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
749where
750 Root: std::borrow::Borrow<R>,
751 Value: std::borrow::Borrow<V>,
752 MutRoot: std::borrow::BorrowMut<R>,
753 MutValue: std::borrow::BorrowMut<V>,
754 G: Fn(Root) -> Option<Value>,
755 S: Fn(MutRoot) -> Option<MutValue>,
756{
757 pub fn new(get: G, set: S) -> Self {
758 Self {
759 get: get,
760 set: set,
761 _p: std::marker::PhantomData,
762 }
763 }
764
765 #[inline]
766 pub fn get(&self, root: Root) -> Option<Value> {
767 (self.get)(root)
768 }
769 #[inline]
770 pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
771 (self.set)(root)
772 }
773
774 pub fn then<SV, SubValue, MutSubValue, G2, S2>(
775 self,
776 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
777 ) -> Kp<
778 R,
779 SV,
780 Root,
781 SubValue,
782 MutRoot,
783 MutSubValue,
784 impl Fn(Root) -> Option<SubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
785 impl Fn(MutRoot) -> Option<MutSubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
786 >
787 where
788 SubValue: std::borrow::Borrow<SV>,
789 MutSubValue: std::borrow::BorrowMut<SV>,
790 G2: Fn(Value) -> Option<SubValue>,
791 S2: Fn(MutValue) -> Option<MutSubValue>,
792 V: 'static,
793 {
794 Kp::new(
795 move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
796 move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
797 )
798 }
799
800 pub fn then_lock<
802 Lock,
803 Mid,
804 V2,
805 LockValue,
806 MidValue,
807 Value2,
808 MutLock,
809 MutMid,
810 MutValue2,
811 G1,
812 S1,
813 L,
814 G2,
815 S2,
816 >(
817 self,
818 lock_kp: crate::lock::LockKp<
819 V,
820 Lock,
821 Mid,
822 V2,
823 Value,
824 LockValue,
825 MidValue,
826 Value2,
827 MutValue,
828 MutLock,
829 MutMid,
830 MutValue2,
831 G1,
832 S1,
833 L,
834 G2,
835 S2,
836 >,
837 ) -> 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>>
838 where
839 V: 'static + Clone,
840 V2: 'static,
841 Value: std::borrow::Borrow<V>,
842 Value2: std::borrow::Borrow<V2>,
843 MutValue: std::borrow::BorrowMut<V>,
844 MutValue2: std::borrow::BorrowMut<V2>,
845 LockValue: std::borrow::Borrow<Lock>,
846 MidValue: std::borrow::Borrow<Mid>,
847 MutLock: std::borrow::BorrowMut<Lock>,
848 MutMid: std::borrow::BorrowMut<Mid>,
849 G1: Fn(Value) -> Option<LockValue>,
850 S1: Fn(MutValue) -> Option<MutLock>,
851 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
852 G2: Fn(MidValue) -> Option<Value2>,
853 S2: Fn(MutMid) -> Option<MutValue2>,
854 {
855 crate::lock::KpThenLockKp {
856 first: self,
857 second: lock_kp,
858 _p: std::marker::PhantomData,
859 }
860 }
861
862 #[cfg(feature = "pin_project")]
865 pub fn then_pin_future<Struct, Output, L>(
866 self,
867 pin_fut: L,
868 ) -> crate::pin::KpThenPinFuture<
869 R,
870 Struct,
871 Output,
872 Root,
873 MutRoot,
874 Value,
875 MutValue,
876 Self,
877 L,
878 >
879 where
880 V: 'static,
881 Struct: Unpin + 'static,
882 Output: 'static,
883 Value: std::borrow::Borrow<Struct>,
884 MutValue: std::borrow::BorrowMut<Struct>,
885 L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
886 {
887 crate::pin::KpThenPinFuture {
888 first: self,
889 second: pin_fut,
890 _p: std::marker::PhantomData,
891 }
892 }
893
894 pub fn then_async<AsyncKp>(
897 self,
898 async_kp: AsyncKp,
899 ) -> crate::async_lock::KpThenAsyncKeyPath<
900 R,
901 V,
902 <AsyncKp::Value as KeyPathValueTarget>::Target,
903 Root,
904 Value,
905 AsyncKp::Value,
906 MutRoot,
907 MutValue,
908 AsyncKp::MutValue,
909 Self,
910 AsyncKp,
911 >
912 where
913 V: 'static,
914 Value: std::borrow::Borrow<V>,
915 MutValue: std::borrow::BorrowMut<V>,
916 AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
917 AsyncKp::Value: KeyPathValueTarget
918 + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
919 AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
920 <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
921 {
922 crate::async_lock::KpThenAsyncKeyPath {
923 first: self,
924 second: async_kp,
925 _p: std::marker::PhantomData,
926 }
927 }
928
929 pub fn map<MappedValue, F>(
942 &self,
943 mapper: F,
944 ) -> Kp<
945 R,
946 MappedValue,
947 Root,
948 MappedValue,
949 MutRoot,
950 MappedValue,
951 impl Fn(Root) -> Option<MappedValue>,
952 impl Fn(MutRoot) -> Option<MappedValue>,
953 >
954 where
955 F: Fn(&V) -> MappedValue + Copy + 'static,
958 V: 'static,
959 MappedValue: 'static,
960 {
961 Kp::new(
962 move |root: Root| {
963 (&self.get)(root).map(|value| {
964 let v: &V = value.borrow();
965 mapper(v)
966 })
967 },
968 move |root: MutRoot| {
969 (&self.set)(root).map(|value| {
970 let v: &V = value.borrow();
971 mapper(v)
972 })
973 },
974 )
975 }
976
977 pub fn filter<F>(
990 &self,
991 predicate: F,
992 ) -> Kp<
993 R,
994 V,
995 Root,
996 Value,
997 MutRoot,
998 MutValue,
999 impl Fn(Root) -> Option<Value>,
1000 impl Fn(MutRoot) -> Option<MutValue>,
1001 >
1002 where
1003 F: Fn(&V) -> bool + Copy + 'static,
1006 V: 'static,
1007 {
1008 Kp::new(
1009 move |root: Root| {
1010 (&self.get)(root).filter(|value| {
1011 let v: &V = value.borrow();
1012 predicate(v)
1013 })
1014 },
1015 move |root: MutRoot| {
1016 (&self.set)(root).filter(|value| {
1017 let v: &V = value.borrow();
1018 predicate(v)
1019 })
1020 },
1021 )
1022 }
1023
1024 pub fn filter_map<MappedValue, F>(
1037 &self,
1038 mapper: F,
1039 ) -> Kp<
1040 R,
1041 MappedValue,
1042 Root,
1043 MappedValue,
1044 MutRoot,
1045 MappedValue,
1046 impl Fn(Root) -> Option<MappedValue>,
1047 impl Fn(MutRoot) -> Option<MappedValue>,
1048 >
1049 where
1050 F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
1053 V: 'static,
1054 MappedValue: 'static,
1055 {
1056 Kp::new(
1057 move |root: Root| {
1058 (&self.get)(root).and_then(|value| {
1059 let v: &V = value.borrow();
1060 mapper(v)
1061 })
1062 },
1063 move |root: MutRoot| {
1064 (&self.set)(root).and_then(|value| {
1065 let v: &V = value.borrow();
1066 mapper(v)
1067 })
1068 },
1069 )
1070 }
1071
1072 pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
1084 where
1085 F: Fn(&V) -> I + 'static,
1088 V: 'static,
1089 I: IntoIterator<Item = Item>,
1090 Item: 'static,
1091 {
1092 move |root: Root| {
1093 (&self.get)(root)
1094 .map(|value| {
1095 let v: &V = value.borrow();
1096 mapper(v).into_iter().collect()
1097 })
1098 .unwrap_or_else(Vec::new)
1099 }
1100 }
1101
1102 pub fn inspect<F>(
1113 &self,
1114 inspector: F,
1115 ) -> Kp<
1116 R,
1117 V,
1118 Root,
1119 Value,
1120 MutRoot,
1121 MutValue,
1122 impl Fn(Root) -> Option<Value>,
1123 impl Fn(MutRoot) -> Option<MutValue>,
1124 >
1125 where
1126 F: Fn(&V) + Copy + 'static,
1129 V: 'static,
1130 {
1131 Kp::new(
1132 move |root: Root| {
1133 (&self.get)(root).map(|value| {
1134 let v: &V = value.borrow();
1135 inspector(v);
1136 value
1137 })
1138 },
1139 move |root: MutRoot| {
1140 (&self.set)(root).map(|value| {
1141 let v: &V = value.borrow();
1142 inspector(v);
1143 value
1144 })
1145 },
1146 )
1147 }
1148
1149 pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
1163 where
1164 F: Fn(Acc, &V) -> Acc + 'static,
1167 V: 'static,
1168 Acc: Copy + 'static,
1170 {
1171 move |root: Root| {
1172 (&self.get)(root)
1173 .map(|value| {
1174 let v: &V = value.borrow();
1175 folder(init, v)
1176 })
1177 .unwrap_or(init)
1178 }
1179 }
1180
1181 pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1193 where
1194 F: Fn(&V) -> bool + 'static,
1197 V: 'static,
1198 {
1199 move |root: Root| {
1200 (&self.get)(root)
1201 .map(|value| {
1202 let v: &V = value.borrow();
1203 predicate(v)
1204 })
1205 .unwrap_or(false)
1206 }
1207 }
1208
1209 pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1221 where
1222 F: Fn(&V) -> bool + 'static,
1225 V: 'static,
1226 {
1227 move |root: Root| {
1228 (&self.get)(root)
1229 .map(|value| {
1230 let v: &V = value.borrow();
1231 predicate(v)
1232 })
1233 .unwrap_or(true)
1234 }
1235 }
1236
1237 pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
1249 where
1250 F: Fn(&V) -> usize + 'static,
1253 V: 'static,
1254 {
1255 move |root: Root| {
1256 (&self.get)(root).map(|value| {
1257 let v: &V = value.borrow();
1258 counter(v)
1259 })
1260 }
1261 }
1262
1263 pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
1277 where
1278 F: Fn(&V) -> Option<Item> + 'static,
1281 V: 'static,
1282 Item: 'static,
1283 {
1284 move |root: Root| {
1285 (&self.get)(root).and_then(|value| {
1286 let v: &V = value.borrow();
1287 finder(v)
1288 })
1289 }
1290 }
1291
1292 pub fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output>
1303 where
1304 F: Fn(&V, usize) -> Output + 'static,
1307 V: 'static,
1308 Output: 'static,
1309 {
1310 move |root: Root| {
1311 (&self.get)(root).map(|value| {
1312 let v: &V = value.borrow();
1313 taker(v, n)
1314 })
1315 }
1316 }
1317
1318 pub fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output>
1329 where
1330 F: Fn(&V, usize) -> Output + 'static,
1333 V: 'static,
1334 Output: 'static,
1335 {
1336 move |root: Root| {
1337 (&self.get)(root).map(|value| {
1338 let v: &V = value.borrow();
1339 skipper(v, n)
1340 })
1341 }
1342 }
1343
1344 pub fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output>
1357 where
1358 F: Fn(&V) -> Output + 'static,
1361 V: 'static,
1362 Output: 'static,
1363 {
1364 move |root: Root| {
1365 (&self.get)(root).map(|value| {
1366 let v: &V = value.borrow();
1367 partitioner(v)
1368 })
1369 }
1370 }
1371
1372 pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
1384 where
1385 F: Fn(&V) -> Option<Item> + 'static,
1388 V: 'static,
1389 Item: 'static,
1390 {
1391 move |root: Root| {
1392 (&self.get)(root).and_then(|value| {
1393 let v: &V = value.borrow();
1394 min_fn(v)
1395 })
1396 }
1397 }
1398
1399 pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
1411 where
1412 F: Fn(&V) -> Option<Item> + 'static,
1415 V: 'static,
1416 Item: 'static,
1417 {
1418 move |root: Root| {
1419 (&self.get)(root).and_then(|value| {
1420 let v: &V = value.borrow();
1421 max_fn(v)
1422 })
1423 }
1424 }
1425
1426 pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
1438 where
1439 F: Fn(&V) -> Sum + 'static,
1442 V: 'static,
1443 Sum: 'static,
1444 {
1445 move |root: Root| {
1446 (&self.get)(root).map(|value| {
1447 let v: &V = value.borrow();
1448 sum_fn(v)
1449 })
1450 }
1451 }
1452
1453 pub fn chain<SV, SubValue, MutSubValue, G2, S2>(
1456 self,
1457 next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1458 ) -> Kp<
1459 R,
1460 SV,
1461 Root,
1462 SubValue,
1463 MutRoot,
1464 MutSubValue,
1465 impl Fn(Root) -> Option<SubValue>,
1466 impl Fn(MutRoot) -> Option<MutSubValue>,
1467 >
1468 where
1469 SubValue: std::borrow::Borrow<SV>,
1470 MutSubValue: std::borrow::BorrowMut<SV>,
1471 G2: Fn(Value) -> Option<SubValue>,
1472 S2: Fn(MutValue) -> Option<MutSubValue>,
1473 V: 'static,
1474 {
1475 self.then(next)
1476 }
1477
1478 pub fn for_arc<'b>(
1479 &self,
1480 ) -> Kp<
1481 std::sync::Arc<R>,
1482 V,
1483 std::sync::Arc<R>,
1484 Value,
1485 std::sync::Arc<R>,
1486 MutValue,
1487 impl Fn(std::sync::Arc<R>) -> Option<Value>,
1488 impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1489 >
1490 where
1491 R: 'b,
1492 V: 'b,
1493 Root: for<'a> From<&'a R>,
1494 MutRoot: for<'a> From<&'a mut R>,
1495 {
1496 Kp::new(
1497 move |arc_root: std::sync::Arc<R>| {
1498 let r_ref: &R = &*arc_root;
1499 (&self.get)(Root::from(r_ref))
1500 },
1501 move |mut arc_root: std::sync::Arc<R>| {
1502 std::sync::Arc::get_mut(&mut arc_root)
1504 .and_then(|r_mut| (&self.set)(MutRoot::from(r_mut)))
1505 },
1506 )
1507 }
1508
1509 pub fn for_box<'a>(
1510 &self,
1511 ) -> Kp<
1512 Box<R>,
1513 V,
1514 Box<R>,
1515 Value,
1516 Box<R>,
1517 MutValue,
1518 impl Fn(Box<R>) -> Option<Value>,
1519 impl Fn(Box<R>) -> Option<MutValue>,
1520 >
1521 where
1522 R: 'a,
1523 V: 'a,
1524 Root: for<'b> From<&'b R>,
1525 MutRoot: for<'b> From<&'b mut R>,
1526 {
1527 Kp::new(
1528 move |r: Box<R>| {
1529 let r_ref: &R = r.as_ref();
1530 (&self.get)(Root::from(r_ref))
1531 },
1532 move |mut r: Box<R>| {
1533 (self.set)(MutRoot::from(r.as_mut()))
1535 },
1536 )
1537 }
1538}
1539
1540pub fn zip_kps<'a, RootType, Value1, Value2>(
1554 kp1: &'a KpType<'a, RootType, Value1>,
1555 kp2: &'a KpType<'a, RootType, Value2>,
1556) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1557where
1558 RootType: 'a,
1559 Value1: 'a,
1560 Value2: 'a,
1561{
1562 move |root: &'a RootType| {
1563 let val1 = (kp1.get)(root)?;
1564 let val2 = (kp2.get)(root)?;
1565 Some((val1, val2))
1566 }
1567}
1568
1569impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1570where
1571 Root: std::borrow::Borrow<R>,
1572 MutRoot: std::borrow::BorrowMut<R>,
1573 G: Fn(Root) -> Option<Root>,
1574 S: Fn(MutRoot) -> Option<MutRoot>,
1575{
1576 pub fn identity_typed() -> Kp<
1577 R,
1578 R,
1579 Root,
1580 Root,
1581 MutRoot,
1582 MutRoot,
1583 fn(Root) -> Option<Root>,
1584 fn(MutRoot) -> Option<MutRoot>,
1585 > {
1586 Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1587 }
1588
1589 pub fn identity<'a>() -> KpType<'a, R, R> {
1590 KpType::new(|r| Some(r), |r| Some(r))
1591 }
1592}
1593
1594pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1603where
1604 Root: std::borrow::Borrow<Enum>,
1605 Value: std::borrow::Borrow<Variant>,
1606 MutRoot: std::borrow::BorrowMut<Enum>,
1607 MutValue: std::borrow::BorrowMut<Variant>,
1608 G: Fn(Root) -> Option<Value>,
1609 S: Fn(MutRoot) -> Option<MutValue>,
1610 E: Fn(Variant) -> Enum,
1611{
1612 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1613 embedder: E,
1614}
1615
1616unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1618 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1619where
1620 Root: std::borrow::Borrow<Enum>,
1621 Value: std::borrow::Borrow<Variant>,
1622 MutRoot: std::borrow::BorrowMut<Enum>,
1623 MutValue: std::borrow::BorrowMut<Variant>,
1624 G: Fn(Root) -> Option<Value> + Send,
1625 S: Fn(MutRoot) -> Option<MutValue> + Send,
1626 E: Fn(Variant) -> Enum + Send,
1627{
1628}
1629unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1630 for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1631where
1632 Root: std::borrow::Borrow<Enum>,
1633 Value: std::borrow::Borrow<Variant>,
1634 MutRoot: std::borrow::BorrowMut<Enum>,
1635 MutValue: std::borrow::BorrowMut<Variant>,
1636 G: Fn(Root) -> Option<Value> + Sync,
1637 S: Fn(MutRoot) -> Option<MutValue> + Sync,
1638 E: Fn(Variant) -> Enum + Sync,
1639{
1640}
1641
1642impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1643 EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1644where
1645 Root: std::borrow::Borrow<Enum>,
1646 Value: std::borrow::Borrow<Variant>,
1647 MutRoot: std::borrow::BorrowMut<Enum>,
1648 MutValue: std::borrow::BorrowMut<Variant>,
1649 G: Fn(Root) -> Option<Value>,
1650 S: Fn(MutRoot) -> Option<MutValue>,
1651 E: Fn(Variant) -> Enum,
1652{
1653 pub fn new(
1655 extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1656 embedder: E,
1657 ) -> Self {
1658 Self {
1659 extractor,
1660 embedder,
1661 }
1662 }
1663
1664 pub fn get(&self, enum_value: Root) -> Option<Value> {
1666 self.extractor.get(enum_value)
1667 }
1668
1669 pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1671 self.extractor.get_mut(enum_value)
1672 }
1673
1674 pub fn embed(&self, value: Variant) -> Enum {
1676 (self.embedder)(value)
1677 }
1678
1679 pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1681 &self.extractor
1682 }
1683
1684 pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1686 self.extractor
1687 }
1688
1689 pub fn map<MappedValue, F>(
1700 &self,
1701 mapper: F,
1702 ) -> EnumKp<
1703 Enum,
1704 MappedValue,
1705 Root,
1706 MappedValue,
1707 MutRoot,
1708 MappedValue,
1709 impl Fn(Root) -> Option<MappedValue>,
1710 impl Fn(MutRoot) -> Option<MappedValue>,
1711 impl Fn(MappedValue) -> Enum,
1712 >
1713 where
1714 F: Fn(&Variant) -> MappedValue + Copy + 'static,
1717 Variant: 'static,
1718 MappedValue: 'static,
1719 E: Fn(Variant) -> Enum + Copy + 'static,
1721 {
1722 let mapped_extractor = self.extractor.map(mapper);
1723
1724 let new_embedder = move |_value: MappedValue| -> Enum {
1728 panic!(
1729 "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1730 )
1731 };
1732
1733 EnumKp::new(mapped_extractor, new_embedder)
1734 }
1735
1736 pub fn filter<F>(
1748 &self,
1749 predicate: F,
1750 ) -> EnumKp<
1751 Enum,
1752 Variant,
1753 Root,
1754 Value,
1755 MutRoot,
1756 MutValue,
1757 impl Fn(Root) -> Option<Value>,
1758 impl Fn(MutRoot) -> Option<MutValue>,
1759 E,
1760 >
1761 where
1762 F: Fn(&Variant) -> bool + Copy + 'static,
1765 Variant: 'static,
1766 E: Copy,
1768 {
1769 let filtered_extractor = self.extractor.filter(predicate);
1770 EnumKp::new(filtered_extractor, self.embedder)
1771 }
1772}
1773
1774pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1776 Enum,
1777 Variant,
1778 &'a Enum,
1779 &'a Variant,
1780 &'a mut Enum,
1781 &'a mut Variant,
1782 for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1783 for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1784 fn(Variant) -> Enum,
1785>;
1786
1787pub fn enum_variant<'a, Enum, Variant>(
1805 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1806 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1807 embedder: fn(Variant) -> Enum,
1808) -> EnumKpType<'a, Enum, Variant> {
1809 EnumKp::new(Kp::new(getter, setter), embedder)
1810}
1811
1812pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1822 EnumKp::new(
1823 Kp::new(
1824 |r: &Result<T, E>| r.as_ref().ok(),
1825 |r: &mut Result<T, E>| r.as_mut().ok(),
1826 ),
1827 |t: T| Ok(t),
1828 )
1829}
1830
1831pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1841 EnumKp::new(
1842 Kp::new(
1843 |r: &Result<T, E>| r.as_ref().err(),
1844 |r: &mut Result<T, E>| r.as_mut().err(),
1845 ),
1846 |e: E| Err(e),
1847 )
1848}
1849
1850pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1860 EnumKp::new(
1861 Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1862 |t: T| Some(t),
1863 )
1864}
1865
1866pub fn variant_of<'a, Enum, Variant>(
1884 getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1885 setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1886 embedder: fn(Variant) -> Enum,
1887) -> EnumKpType<'a, Enum, Variant> {
1888 enum_variant(getter, setter, embedder)
1889}
1890
1891pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1904 Kp::new(
1905 |b: &Box<T>| Some(b.as_ref()),
1906 |b: &mut Box<T>| Some(b.as_mut()),
1907 )
1908}
1909
1910pub fn kp_arc<'a, T>() -> Kp<
1921 Arc<T>,
1922 T,
1923 &'a Arc<T>,
1924 &'a T,
1925 &'a mut Arc<T>,
1926 &'a mut T,
1927 for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
1928 for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
1929> {
1930 Kp::new(
1931 |arc: &Arc<T>| Some(arc.as_ref()),
1932 |arc: &mut Arc<T>| Arc::get_mut(arc),
1933 )
1934}
1935
1936pub fn kp_rc<'a, T>() -> Kp<
1947 std::rc::Rc<T>,
1948 T,
1949 &'a std::rc::Rc<T>,
1950 &'a T,
1951 &'a mut std::rc::Rc<T>,
1952 &'a mut T,
1953 for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
1954 for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
1955> {
1956 Kp::new(
1957 |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
1958 |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
1959 )
1960}
1961
1962use std::any::{Any, TypeId};
1965use std::rc::Rc;
1966
1967#[cfg(test)]
1982mod tests {
1983 use super::*;
1984 use std::collections::HashMap;
1985
1986 #[derive(Debug)]
1987 struct TestKP {
1988 a: String,
1989 b: String,
1990 c: std::sync::Arc<String>,
1991 d: std::sync::Mutex<String>,
1992 e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
1993 f: Option<TestKP2>,
1994 g: HashMap<i32, TestKP2>,
1995 }
1996
1997 impl TestKP {
1998 fn new() -> Self {
1999 Self {
2000 a: String::from("a"),
2001 b: String::from("b"),
2002 c: std::sync::Arc::new(String::from("c")),
2003 d: std::sync::Mutex::new(String::from("d")),
2004 e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
2005 f: Some(TestKP2 {
2006 a: String::from("a3"),
2007 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2008 }),
2009 g: HashMap::new(),
2010 }
2011 }
2012
2013 fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
2014 KpComposed::from_closures(
2015 move |r: &TestKP| r.g.get(&index),
2016 move |r: &mut TestKP| r.g.get_mut(&index),
2017 )
2018 }
2019
2020 fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
2023 TestKP2,
2024 String,
2025 Root,
2026 Value,
2027 MutRoot,
2028 MutValue,
2029 impl Fn(Root) -> Option<Value>,
2030 impl Fn(MutRoot) -> Option<MutValue>,
2031 >
2032 where
2033 Root: std::borrow::Borrow<TestKP2>,
2034 MutRoot: std::borrow::BorrowMut<TestKP2>,
2035 Value: std::borrow::Borrow<String> + From<String>,
2036 MutValue: std::borrow::BorrowMut<String> + From<String>,
2037 {
2038 Kp::new(
2039 |r: Root| Some(Value::from(r.borrow().a.clone())),
2040 |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
2041 )
2042 }
2043
2044 fn c<'a>() -> KpType<'a, TestKP, String> {
2047 KpType::new(
2048 |r: &TestKP| Some(r.c.as_ref()),
2049 |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
2050 Some(arc_str) => Some(arc_str),
2051 None => None,
2052 },
2053 )
2054 }
2055
2056 fn a<'a>() -> KpType<'a, TestKP, String> {
2057 KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
2058 }
2059
2060 fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
2061 KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
2062 }
2063
2064 fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
2065 KpType::identity()
2066 }
2067 }
2068
2069 #[derive(Debug)]
2070 struct TestKP2 {
2071 a: String,
2072 b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
2073 }
2074
2075 impl TestKP2 {
2076 fn new() -> Self {
2077 TestKP2 {
2078 a: String::from("a2"),
2079 b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
2080 }
2081 }
2082
2083 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2084 TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2091 fn(MutRoot) -> Option<MutRoot>,
2092 >
2093 where
2094 Root: std::borrow::Borrow<TestKP2>,
2095 MutRoot: std::borrow::BorrowMut<TestKP2>,
2096 G: Fn(Root) -> Option<Root>,
2097 S: Fn(MutRoot) -> Option<MutRoot>,
2098 {
2099 Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2100 }
2101
2102 fn a<'a>() -> KpType<'a, TestKP2, String> {
2103 KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
2104 }
2105
2106 fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
2107 KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
2108 }
2109
2110 fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
2115 KpType::identity()
2116 }
2117 }
2118
2119 #[derive(Debug)]
2120 struct TestKP3 {
2121 a: String,
2122 b: std::sync::Arc<std::sync::Mutex<String>>,
2123 }
2124
2125 impl TestKP3 {
2126 fn new() -> Self {
2127 TestKP3 {
2128 a: String::from("a2"),
2129 b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
2130 }
2131 }
2132
2133 fn identity_typed<Root, MutRoot, G, S>() -> Kp<
2134 TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>,
2141 fn(MutRoot) -> Option<MutRoot>,
2142 >
2143 where
2144 Root: std::borrow::Borrow<TestKP3>,
2145 MutRoot: std::borrow::BorrowMut<TestKP3>,
2146 G: Fn(Root) -> Option<Root>,
2147 S: Fn(MutRoot) -> Option<MutRoot>,
2148 {
2149 Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
2150 }
2151
2152 fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
2153 KpType::identity()
2154 }
2155 }
2156
2157 impl TestKP3 {}
2158
2159 impl TestKP {}
2160 #[test]
2161 fn test_a() {
2162 let instance2 = TestKP2::new();
2163 let mut instance = TestKP::new();
2164 let kp = TestKP::identity();
2165 let kp_a = TestKP::a();
2166 let wres = TestKP::f().then(TestKP2::a()).get_mut(&mut instance).unwrap();
2168 *wres = String::from("a3 changed successfully");
2169 let res = TestKP::f().then(TestKP2::a()).get(&instance);
2170 println!("{:?}", res);
2171 let res = TestKP::f().then(TestKP2::identity()).get(&instance);
2172 println!("{:?}", res);
2173 let res = kp.get(&instance);
2174 println!("{:?}", res);
2175
2176 let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2177 println!("{:?}", new_kp_from_hashmap.get(&instance));
2178 }
2179
2180 #[test]
2216 fn test_enum_kp_result_ok() {
2217 let ok_result: Result<String, i32> = Ok("success".to_string());
2218 let mut err_result: Result<String, i32> = Err(42);
2219
2220 let ok_kp = enum_ok();
2221
2222 assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2224 assert_eq!(ok_kp.get(&err_result), None);
2225
2226 let embedded = ok_kp.embed("embedded".to_string());
2228 assert_eq!(embedded, Ok("embedded".to_string()));
2229
2230 if let Some(val) = ok_kp.get_mut(&mut err_result) {
2232 *val = "modified".to_string();
2233 }
2234 assert_eq!(err_result, Err(42)); let mut ok_result2 = Ok("original".to_string());
2237 if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2238 *val = "modified".to_string();
2239 }
2240 assert_eq!(ok_result2, Ok("modified".to_string()));
2241 }
2242
2243 #[test]
2244 fn test_enum_kp_result_err() {
2245 let ok_result: Result<String, i32> = Ok("success".to_string());
2246 let mut err_result: Result<String, i32> = Err(42);
2247
2248 let err_kp = enum_err();
2249
2250 assert_eq!(err_kp.get(&err_result), Some(&42));
2252 assert_eq!(err_kp.get(&ok_result), None);
2253
2254 let embedded = err_kp.embed(99);
2256 assert_eq!(embedded, Err(99));
2257
2258 if let Some(val) = err_kp.get_mut(&mut err_result) {
2260 *val = 100;
2261 }
2262 assert_eq!(err_result, Err(100));
2263 }
2264
2265 #[test]
2266 fn test_enum_kp_option_some() {
2267 let some_opt = Some("value".to_string());
2268 let mut none_opt: Option<String> = None;
2269
2270 let some_kp = enum_some();
2271
2272 assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2274 assert_eq!(some_kp.get(&none_opt), None);
2275
2276 let embedded = some_kp.embed("embedded".to_string());
2278 assert_eq!(embedded, Some("embedded".to_string()));
2279
2280 let mut some_opt2 = Some("original".to_string());
2282 if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2283 *val = "modified".to_string();
2284 }
2285 assert_eq!(some_opt2, Some("modified".to_string()));
2286 }
2287
2288 #[test]
2289 fn test_enum_kp_custom_enum() {
2290 #[derive(Debug, PartialEq)]
2291 enum MyEnum {
2292 A(String),
2293 B(i32),
2294 C,
2295 }
2296
2297 let mut enum_a = MyEnum::A("hello".to_string());
2298 let enum_b = MyEnum::B(42);
2299 let enum_c = MyEnum::C;
2300
2301 let kp_a = enum_variant(
2303 |e: &MyEnum| match e {
2304 MyEnum::A(s) => Some(s),
2305 _ => None,
2306 },
2307 |e: &mut MyEnum| match e {
2308 MyEnum::A(s) => Some(s),
2309 _ => None,
2310 },
2311 |s: String| MyEnum::A(s),
2312 );
2313
2314 assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2316 assert_eq!(kp_a.get(&enum_b), None);
2317 assert_eq!(kp_a.get(&enum_c), None);
2318
2319 let embedded = kp_a.embed("world".to_string());
2321 assert_eq!(embedded, MyEnum::A("world".to_string()));
2322
2323 if let Some(val) = kp_a.get_mut(&mut enum_a) {
2325 *val = "modified".to_string();
2326 }
2327 assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2328 }
2329
2330 #[test]
2331 fn test_container_kp_box() {
2332 let boxed = Box::new("value".to_string());
2333 let mut boxed_mut = Box::new("original".to_string());
2334
2335 let box_kp = kp_box();
2336
2337 assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2339
2340 if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2342 *val = "modified".to_string();
2343 }
2344 assert_eq!(*boxed_mut, "modified".to_string());
2345 }
2346
2347 #[test]
2348 fn test_container_kp_arc() {
2349 let arc = Arc::new("value".to_string());
2350 let mut arc_mut = Arc::new("original".to_string());
2351
2352 let arc_kp = kp_arc();
2353
2354 assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2356
2357 if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2359 *val = "modified".to_string();
2360 }
2361 assert_eq!(*arc_mut, "modified".to_string());
2362
2363 let arc_shared = Arc::new("shared".to_string());
2365 let arc_shared2 = Arc::clone(&arc_shared);
2366 let mut arc_shared_mut = arc_shared;
2367 assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2368 }
2369
2370 #[test]
2371 fn test_enum_kp_composition() {
2372 #[derive(Debug, PartialEq)]
2374 struct Inner {
2375 value: String,
2376 }
2377
2378 let result: Result<Inner, i32> = Ok(Inner {
2379 value: "nested".to_string(),
2380 });
2381
2382 let inner_kp = KpType::new(
2384 |i: &Inner| Some(&i.value),
2385 |i: &mut Inner| Some(&mut i.value),
2386 );
2387
2388 let ok_kp = enum_ok::<Inner, i32>();
2390 let ok_kp_base = ok_kp.into_kp();
2391 let composed = ok_kp_base.then(inner_kp);
2392
2393 assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2394 }
2395
2396 #[test]
2397 fn test_pkp_basic() {
2398 #[derive(Debug)]
2399 struct User {
2400 name: String,
2401 age: i32,
2402 }
2403
2404 let user = User {
2405 name: "Alice".to_string(),
2406 age: 30,
2407 };
2408
2409 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2411 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2412
2413 let name_pkp = PKp::new(name_kp);
2415 let age_pkp = PKp::new(age_kp);
2416
2417 assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2419 assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2420
2421 assert_eq!(name_pkp.get_as::<i32>(&user), None);
2423 assert_eq!(age_pkp.get_as::<String>(&user), None);
2424
2425 assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2427 assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2428 }
2429
2430 #[test]
2431 fn test_pkp_collection() {
2432 #[derive(Debug)]
2433 struct User {
2434 name: String,
2435 age: i32,
2436 }
2437
2438 let user = User {
2439 name: "Bob".to_string(),
2440 age: 25,
2441 };
2442
2443 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2445 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2446
2447 let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2448
2449 let name_value = keypaths[0].get_as::<String>(&user);
2451 let age_value = keypaths[1].get_as::<i32>(&user);
2452
2453 assert_eq!(name_value, Some(&"Bob".to_string()));
2454 assert_eq!(age_value, Some(&25));
2455 }
2456
2457 #[test]
2458 fn test_pkp_for_arc() {
2459 #[derive(Debug)]
2460 struct User {
2461 name: String,
2462 }
2463
2464 let user = Arc::new(User {
2465 name: "Charlie".to_string(),
2466 });
2467
2468 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2469 let name_pkp = PKp::new(name_kp);
2470
2471 let arc_pkp = name_pkp.for_arc();
2473
2474 assert_eq!(
2475 arc_pkp.get_as::<String>(&user),
2476 Some(&"Charlie".to_string())
2477 );
2478 }
2479
2480 #[test]
2481 fn test_pkp_for_option() {
2482 #[derive(Debug)]
2483 struct User {
2484 name: String,
2485 }
2486
2487 let some_user = Some(User {
2488 name: "Diana".to_string(),
2489 });
2490 let none_user: Option<User> = None;
2491
2492 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2493 let name_pkp = PKp::new(name_kp);
2494
2495 let opt_pkp = name_pkp.for_option();
2497
2498 assert_eq!(
2499 opt_pkp.get_as::<String>(&some_user),
2500 Some(&"Diana".to_string())
2501 );
2502 assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2503 }
2504
2505 #[test]
2506 fn test_akp_basic() {
2507 #[derive(Debug)]
2508 struct User {
2509 name: String,
2510 age: i32,
2511 }
2512
2513 #[derive(Debug)]
2514 struct Product {
2515 title: String,
2516 price: f64,
2517 }
2518
2519 let user = User {
2520 name: "Eve".to_string(),
2521 age: 28,
2522 };
2523
2524 let product = Product {
2525 title: "Book".to_string(),
2526 price: 19.99,
2527 };
2528
2529 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2531 let user_name_akp = AKp::new(user_name_kp);
2532
2533 let product_title_kp = KpType::new(
2534 |p: &Product| Some(&p.title),
2535 |p: &mut Product| Some(&mut p.title),
2536 );
2537 let product_title_akp = AKp::new(product_title_kp);
2538
2539 assert_eq!(
2541 user_name_akp.get_as::<User, String>(&user),
2542 Some(Some(&"Eve".to_string()))
2543 );
2544 assert_eq!(
2545 product_title_akp.get_as::<Product, String>(&product),
2546 Some(Some(&"Book".to_string()))
2547 );
2548
2549 assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2551 assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2552
2553 assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2555 assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2556 assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2557 assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2558 }
2559
2560 #[test]
2561 fn test_akp_heterogeneous_collection() {
2562 #[derive(Debug)]
2563 struct User {
2564 name: String,
2565 }
2566
2567 #[derive(Debug)]
2568 struct Product {
2569 title: String,
2570 }
2571
2572 let user = User {
2573 name: "Frank".to_string(),
2574 };
2575 let product = Product {
2576 title: "Laptop".to_string(),
2577 };
2578
2579 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2581 let product_title_kp = KpType::new(
2582 |p: &Product| Some(&p.title),
2583 |p: &mut Product| Some(&mut p.title),
2584 );
2585
2586 let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2587
2588 let user_any: &dyn Any = &user;
2590 let product_any: &dyn Any = &product;
2591
2592 let user_value = keypaths[0].get(user_any);
2593 let product_value = keypaths[1].get(product_any);
2594
2595 assert!(user_value.is_some());
2596 assert!(product_value.is_some());
2597
2598 assert_eq!(
2600 user_value.and_then(|v| v.downcast_ref::<String>()),
2601 Some(&"Frank".to_string())
2602 );
2603 assert_eq!(
2604 product_value.and_then(|v| v.downcast_ref::<String>()),
2605 Some(&"Laptop".to_string())
2606 );
2607 }
2608
2609 #[test]
2610 fn test_akp_for_option() {
2611 #[derive(Debug)]
2612 struct User {
2613 name: String,
2614 }
2615
2616 let some_user = Some(User {
2617 name: "Grace".to_string(),
2618 });
2619 let none_user: Option<User> = None;
2620
2621 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2622 let name_akp = AKp::new(name_kp);
2623
2624 let opt_akp = name_akp.for_option::<User>();
2626
2627 assert_eq!(
2628 opt_akp.get_as::<Option<User>, String>(&some_user),
2629 Some(Some(&"Grace".to_string()))
2630 );
2631 assert_eq!(
2632 opt_akp.get_as::<Option<User>, String>(&none_user),
2633 Some(None)
2634 );
2635 }
2636
2637 #[test]
2638 fn test_akp_for_result() {
2639 #[derive(Debug)]
2640 struct User {
2641 name: String,
2642 }
2643
2644 let ok_user: Result<User, String> = Ok(User {
2645 name: "Henry".to_string(),
2646 });
2647 let err_user: Result<User, String> = Err("Not found".to_string());
2648
2649 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2650 let name_akp = AKp::new(name_kp);
2651
2652 let result_akp = name_akp.for_result::<User, String>();
2654
2655 assert_eq!(
2656 result_akp.get_as::<Result<User, String>, String>(&ok_user),
2657 Some(Some(&"Henry".to_string()))
2658 );
2659 assert_eq!(
2660 result_akp.get_as::<Result<User, String>, String>(&err_user),
2661 Some(None)
2662 );
2663 }
2664
2665 #[test]
2668 fn test_kp_map() {
2669 #[derive(Debug)]
2670 struct User {
2671 name: String,
2672 age: i32,
2673 }
2674
2675 let user = User {
2676 name: "Alice".to_string(),
2677 age: 30,
2678 };
2679
2680 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2682 let len_kp = name_kp.map(|name: &String| name.len());
2683
2684 assert_eq!(len_kp.get(&user), Some(5));
2685
2686 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2688 let double_age_kp = age_kp.map(|age: &i32| age * 2);
2689
2690 assert_eq!(double_age_kp.get(&user), Some(60));
2691
2692 let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2694 assert_eq!(is_adult_kp.get(&user), Some(true));
2695 }
2696
2697 #[test]
2698 fn test_kp_filter() {
2699 #[derive(Debug)]
2700 struct User {
2701 name: String,
2702 age: i32,
2703 }
2704
2705 let adult = User {
2706 name: "Alice".to_string(),
2707 age: 30,
2708 };
2709
2710 let minor = User {
2711 name: "Bob".to_string(),
2712 age: 15,
2713 };
2714
2715 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2716 let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2717
2718 assert_eq!(adult_age_kp.get(&adult), Some(&30));
2719 assert_eq!(adult_age_kp.get(&minor), None);
2720
2721 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2723 let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2724
2725 assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2726 assert_eq!(short_name_kp.get(&adult), None);
2727 }
2728
2729 #[test]
2730 fn test_kp_map_and_filter() {
2731 #[derive(Debug)]
2732 struct User {
2733 scores: Vec<i32>,
2734 }
2735
2736 let user = User {
2737 scores: vec![85, 92, 78, 95],
2738 };
2739
2740 let scores_kp = KpType::new(
2741 |u: &User| Some(&u.scores),
2742 |u: &mut User| Some(&mut u.scores),
2743 );
2744
2745 let avg_kp =
2747 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2748
2749 let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2751
2752 assert_eq!(high_avg_kp.get(&user), Some(87)); }
2754
2755 #[test]
2756 fn test_enum_kp_map() {
2757 let ok_result: Result<String, i32> = Ok("hello".to_string());
2758 let err_result: Result<String, i32> = Err(42);
2759
2760 let ok_kp = enum_ok::<String, i32>();
2761 let len_kp = ok_kp.map(|s: &String| s.len());
2762
2763 assert_eq!(len_kp.get(&ok_result), Some(5));
2764 assert_eq!(len_kp.get(&err_result), None);
2765
2766 let some_opt = Some(vec![1, 2, 3, 4, 5]);
2768 let none_opt: Option<Vec<i32>> = None;
2769
2770 let some_kp = enum_some::<Vec<i32>>();
2771 let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2772
2773 assert_eq!(count_kp.get(&some_opt), Some(5));
2774 assert_eq!(count_kp.get(&none_opt), None);
2775 }
2776
2777 #[test]
2778 fn test_enum_kp_filter() {
2779 let ok_result1: Result<i32, String> = Ok(42);
2780 let ok_result2: Result<i32, String> = Ok(-5);
2781 let err_result: Result<i32, String> = Err("error".to_string());
2782
2783 let ok_kp = enum_ok::<i32, String>();
2784 let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2785
2786 assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2787 assert_eq!(positive_kp.get(&ok_result2), None); assert_eq!(positive_kp.get(&err_result), None); let long_str = Some("hello world".to_string());
2792 let short_str = Some("hi".to_string());
2793
2794 let some_kp = enum_some::<String>();
2795 let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2796
2797 assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2798 assert_eq!(long_kp.get(&short_str), None);
2799 }
2800
2801 #[test]
2802 fn test_pkp_filter() {
2803 #[derive(Debug)]
2804 struct User {
2805 name: String,
2806 age: i32,
2807 }
2808
2809 let adult = User {
2810 name: "Alice".to_string(),
2811 age: 30,
2812 };
2813
2814 let minor = User {
2815 name: "Bob".to_string(),
2816 age: 15,
2817 };
2818
2819 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2820 let age_pkp = PKp::new(age_kp);
2821
2822 let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2824
2825 assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2826 assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2827
2828 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2830 let name_pkp = PKp::new(name_kp);
2831 let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2832
2833 assert_eq!(
2834 short_name_pkp.get_as::<String>(&minor),
2835 Some(&"Bob".to_string())
2836 );
2837 assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2838 }
2839
2840 #[test]
2841 fn test_akp_filter() {
2842 #[derive(Debug)]
2843 struct User {
2844 age: i32,
2845 }
2846
2847 #[derive(Debug)]
2848 struct Product {
2849 price: f64,
2850 }
2851
2852 let adult = User { age: 30 };
2853 let minor = User { age: 15 };
2854 let expensive = Product { price: 99.99 };
2855 let cheap = Product { price: 5.0 };
2856
2857 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2859 let age_akp = AKp::new(age_kp);
2860 let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2861
2862 assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2863 assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2864
2865 let price_kp = KpType::new(
2867 |p: &Product| Some(&p.price),
2868 |p: &mut Product| Some(&mut p.price),
2869 );
2870 let price_akp = AKp::new(price_kp);
2871 let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2872
2873 assert_eq!(
2874 expensive_akp.get_as::<Product, f64>(&expensive),
2875 Some(Some(&99.99))
2876 );
2877 assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2878 }
2879
2880 #[test]
2883 fn test_kp_filter_map() {
2884 #[derive(Debug)]
2885 struct User {
2886 middle_name: Option<String>,
2887 }
2888
2889 let user_with = User {
2890 middle_name: Some("Marie".to_string()),
2891 };
2892 let user_without = User { middle_name: None };
2893
2894 let middle_kp = KpType::new(
2895 |u: &User| Some(&u.middle_name),
2896 |u: &mut User| Some(&mut u.middle_name),
2897 );
2898
2899 let first_char_kp = middle_kp
2900 .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
2901
2902 assert_eq!(first_char_kp.get(&user_with), Some('M'));
2903 assert_eq!(first_char_kp.get(&user_without), None);
2904 }
2905
2906 #[test]
2907 fn test_kp_inspect() {
2908 #[derive(Debug)]
2909 struct User {
2910 name: String,
2911 }
2912
2913 let user = User {
2914 name: "Alice".to_string(),
2915 };
2916
2917 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2921
2922 let result = name_kp.get(&user);
2925 assert_eq!(result, Some(&"Alice".to_string()));
2926
2927 }
2930
2931 #[test]
2932 fn test_kp_fold_value() {
2933 #[derive(Debug)]
2934 struct User {
2935 scores: Vec<i32>,
2936 }
2937
2938 let user = User {
2939 scores: vec![85, 92, 78, 95],
2940 };
2941
2942 let scores_kp = KpType::new(
2943 |u: &User| Some(&u.scores),
2944 |u: &mut User| Some(&mut u.scores),
2945 );
2946
2947 let sum_fn =
2949 scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
2950
2951 assert_eq!(sum_fn(&user), 350);
2952 }
2953
2954 #[test]
2955 fn test_kp_any_all() {
2956 #[derive(Debug)]
2957 struct User {
2958 scores: Vec<i32>,
2959 }
2960
2961 let user_high = User {
2962 scores: vec![85, 92, 88],
2963 };
2964 let user_mixed = User {
2965 scores: vec![65, 92, 78],
2966 };
2967
2968 let scores_kp = KpType::new(
2969 |u: &User| Some(&u.scores),
2970 |u: &mut User| Some(&mut u.scores),
2971 );
2972
2973 let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
2975 assert!(has_high_fn(&user_high));
2976 assert!(has_high_fn(&user_mixed));
2977
2978 let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
2980 assert!(all_passing_fn(&user_high));
2981 assert!(!all_passing_fn(&user_mixed));
2982 }
2983
2984 #[test]
2985 fn test_kp_count_items() {
2986 #[derive(Debug)]
2987 struct User {
2988 tags: Vec<String>,
2989 }
2990
2991 let user = User {
2992 tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
2993 };
2994
2995 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2996 let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
2997
2998 assert_eq!(count_fn(&user), Some(3));
2999 }
3000
3001 #[test]
3002 fn test_kp_find_in() {
3003 #[derive(Debug)]
3004 struct User {
3005 scores: Vec<i32>,
3006 }
3007
3008 let user = User {
3009 scores: vec![85, 92, 78, 95, 88],
3010 };
3011
3012 let scores_kp = KpType::new(
3013 |u: &User| Some(&u.scores),
3014 |u: &mut User| Some(&mut u.scores),
3015 );
3016
3017 let first_high_fn =
3019 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
3020
3021 assert_eq!(first_high_fn(&user), Some(92));
3022
3023 let perfect_fn =
3025 scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
3026
3027 assert_eq!(perfect_fn(&user), None);
3028 }
3029
3030 #[test]
3031 fn test_kp_take_skip() {
3032 #[derive(Debug)]
3033 struct User {
3034 tags: Vec<String>,
3035 }
3036
3037 let user = User {
3038 tags: vec![
3039 "a".to_string(),
3040 "b".to_string(),
3041 "c".to_string(),
3042 "d".to_string(),
3043 ],
3044 };
3045
3046 let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
3047
3048 let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
3050 tags.iter().take(n).cloned().collect::<Vec<_>>()
3051 });
3052
3053 let taken = take_fn(&user).unwrap();
3054 assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
3055
3056 let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
3058 tags.iter().skip(n).cloned().collect::<Vec<_>>()
3059 });
3060
3061 let skipped = skip_fn(&user).unwrap();
3062 assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
3063 }
3064
3065 #[test]
3066 fn test_kp_partition() {
3067 #[derive(Debug)]
3068 struct User {
3069 scores: Vec<i32>,
3070 }
3071
3072 let user = User {
3073 scores: vec![85, 92, 65, 95, 72, 58],
3074 };
3075
3076 let scores_kp = KpType::new(
3077 |u: &User| Some(&u.scores),
3078 |u: &mut User| Some(&mut u.scores),
3079 );
3080
3081 let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
3082 scores.iter().copied().partition(|&s| s >= 70)
3083 });
3084
3085 let (passing, failing) = partition_fn(&user).unwrap();
3086 assert_eq!(passing, vec![85, 92, 95, 72]);
3087 assert_eq!(failing, vec![65, 58]);
3088 }
3089
3090 #[test]
3091 fn test_kp_min_max() {
3092 #[derive(Debug)]
3093 struct User {
3094 scores: Vec<i32>,
3095 }
3096
3097 let user = User {
3098 scores: vec![85, 92, 78, 95, 88],
3099 };
3100
3101 let scores_kp = KpType::new(
3102 |u: &User| Some(&u.scores),
3103 |u: &mut User| Some(&mut u.scores),
3104 );
3105
3106 let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
3108 assert_eq!(min_fn(&user), Some(78));
3109
3110 let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
3112 assert_eq!(max_fn(&user), Some(95));
3113 }
3114
3115 #[test]
3116 fn test_kp_sum() {
3117 #[derive(Debug)]
3118 struct User {
3119 scores: Vec<i32>,
3120 }
3121
3122 let user = User {
3123 scores: vec![85, 92, 78],
3124 };
3125
3126 let scores_kp = KpType::new(
3127 |u: &User| Some(&u.scores),
3128 |u: &mut User| Some(&mut u.scores),
3129 );
3130
3131 let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
3132 assert_eq!(sum_fn(&user), Some(255));
3133
3134 let avg_fn =
3136 scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
3137 assert_eq!(avg_fn.get(&user), Some(85));
3138 }
3139
3140 #[test]
3141 fn test_kp_chain() {
3142 #[derive(Debug)]
3143 struct User {
3144 profile: Profile,
3145 }
3146
3147 #[derive(Debug)]
3148 struct Profile {
3149 settings: Settings,
3150 }
3151
3152 #[derive(Debug)]
3153 struct Settings {
3154 theme: String,
3155 }
3156
3157 let user = User {
3158 profile: Profile {
3159 settings: Settings {
3160 theme: "dark".to_string(),
3161 },
3162 },
3163 };
3164
3165 let profile_kp = KpType::new(
3166 |u: &User| Some(&u.profile),
3167 |u: &mut User| Some(&mut u.profile),
3168 );
3169 let settings_kp = KpType::new(
3170 |p: &Profile| Some(&p.settings),
3171 |p: &mut Profile| Some(&mut p.settings),
3172 );
3173 let theme_kp = KpType::new(
3174 |s: &Settings| Some(&s.theme),
3175 |s: &mut Settings| Some(&mut s.theme),
3176 );
3177
3178 let profile_settings = profile_kp.chain(settings_kp);
3180 let theme_path = profile_settings.chain(theme_kp);
3181 assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3182 }
3183
3184 #[test]
3185 fn test_kp_zip() {
3186 #[derive(Debug)]
3187 struct User {
3188 name: String,
3189 age: i32,
3190 }
3191
3192 let user = User {
3193 name: "Alice".to_string(),
3194 age: 30,
3195 };
3196
3197 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3198 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3199
3200 let zipped_fn = zip_kps(&name_kp, &age_kp);
3201 let result = zipped_fn(&user);
3202
3203 assert_eq!(result, Some((&"Alice".to_string(), &30)));
3204 }
3205
3206 #[test]
3207 fn test_kp_complex_pipeline() {
3208 #[derive(Debug)]
3209 struct User {
3210 transactions: Vec<Transaction>,
3211 }
3212
3213 #[derive(Debug)]
3214 struct Transaction {
3215 amount: f64,
3216 category: String,
3217 }
3218
3219 let user = User {
3220 transactions: vec![
3221 Transaction {
3222 amount: 50.0,
3223 category: "food".to_string(),
3224 },
3225 Transaction {
3226 amount: 100.0,
3227 category: "transport".to_string(),
3228 },
3229 Transaction {
3230 amount: 25.0,
3231 category: "food".to_string(),
3232 },
3233 Transaction {
3234 amount: 200.0,
3235 category: "shopping".to_string(),
3236 },
3237 ],
3238 };
3239
3240 let txns_kp = KpType::new(
3241 |u: &User| Some(&u.transactions),
3242 |u: &mut User| Some(&mut u.transactions),
3243 );
3244
3245 let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3247 txns.iter()
3248 .filter(|t| t.category == "food")
3249 .map(|t| t.amount)
3250 .sum::<f64>()
3251 });
3252
3253 assert_eq!(food_total.get(&user), Some(75.0));
3254
3255 let has_large =
3257 txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3258
3259 assert!(has_large(&user));
3260
3261 let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3263 assert_eq!(count(&user), Some(4));
3264 }
3265
3266 #[test]
3270 fn test_no_clone_required_for_root() {
3271 use std::sync::Arc;
3272 use std::sync::atomic::{AtomicUsize, Ordering};
3273
3274 struct NonCloneableRoot {
3277 data: Arc<AtomicUsize>,
3278 cached_value: usize,
3279 }
3280
3281 impl NonCloneableRoot {
3282 fn new() -> Self {
3283 Self {
3284 data: Arc::new(AtomicUsize::new(42)),
3285 cached_value: 42,
3286 }
3287 }
3288
3289 fn increment(&mut self) {
3290 self.data.fetch_add(1, Ordering::SeqCst);
3291 self.cached_value = self.data.load(Ordering::SeqCst);
3292 }
3293
3294 fn get_value(&self) -> &usize {
3295 &self.cached_value
3296 }
3297
3298 fn get_value_mut(&mut self) -> &mut usize {
3299 &mut self.cached_value
3300 }
3301 }
3302
3303 let mut root = NonCloneableRoot::new();
3304
3305 let data_kp = KpType::new(
3307 |r: &NonCloneableRoot| Some(r.get_value()),
3308 |r: &mut NonCloneableRoot| {
3309 r.increment();
3310 Some(r.get_value_mut())
3311 },
3312 );
3313
3314 assert_eq!(data_kp.get(&root), Some(&42));
3316
3317 {
3318 let doubled = data_kp.map(|val: &usize| val * 2);
3320 assert_eq!(doubled.get(&root), Some(84));
3321
3322 let filtered = data_kp.filter(|val: &usize| *val > 0);
3324 assert_eq!(filtered.get(&root), Some(&42));
3325 } let value_ref = data_kp.get_mut(&mut root);
3329 assert!(value_ref.is_some());
3330 }
3331
3332 #[test]
3333 fn test_no_clone_required_for_value() {
3334 use std::sync::Arc;
3335 use std::sync::atomic::{AtomicUsize, Ordering};
3336
3337 struct NonCloneableValue {
3339 counter: Arc<AtomicUsize>,
3340 }
3341
3342 impl NonCloneableValue {
3343 fn new(val: usize) -> Self {
3344 Self {
3345 counter: Arc::new(AtomicUsize::new(val)),
3346 }
3347 }
3348
3349 fn get(&self) -> usize {
3350 self.counter.load(Ordering::SeqCst)
3351 }
3352 }
3353
3354 struct Root {
3355 value: NonCloneableValue,
3356 }
3357
3358 let root = Root {
3359 value: NonCloneableValue::new(100),
3360 };
3361
3362 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3364
3365 let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3367 assert_eq!(counter_kp.get(&root), Some(100));
3368
3369 let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3371 assert!(filtered.get(&root).is_some());
3372 }
3373
3374 #[test]
3375 fn test_static_does_not_leak_memory() {
3376 use std::sync::Arc;
3377 use std::sync::atomic::{AtomicUsize, Ordering};
3378
3379 static CREATED: AtomicUsize = AtomicUsize::new(0);
3381 static DROPPED: AtomicUsize = AtomicUsize::new(0);
3382
3383 struct Tracked {
3384 id: usize,
3385 }
3386
3387 impl Tracked {
3388 fn new() -> Self {
3389 let id = CREATED.fetch_add(1, Ordering::SeqCst);
3390 Self { id }
3391 }
3392 }
3393
3394 impl Drop for Tracked {
3395 fn drop(&mut self) {
3396 DROPPED.fetch_add(1, Ordering::SeqCst);
3397 }
3398 }
3399
3400 struct Root {
3401 data: Tracked,
3402 }
3403
3404 CREATED.store(0, Ordering::SeqCst);
3406 DROPPED.store(0, Ordering::SeqCst);
3407
3408 {
3409 let root = Root {
3410 data: Tracked::new(),
3411 };
3412
3413 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3414
3415 let mapped1 = data_kp.map(|t: &Tracked| t.id);
3417 let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3418 let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3419
3420 assert_eq!(mapped1.get(&root), Some(0));
3421 assert_eq!(mapped2.get(&root), Some(1));
3422 assert_eq!(mapped3.get(&root), Some(2));
3423
3424 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3426 assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3427 }
3428
3429 assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3431 assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3432
3433 }
3435
3436 #[test]
3437 fn test_references_not_cloned() {
3438 use std::sync::Arc;
3439
3440 struct ExpensiveData {
3442 large_vec: Vec<u8>,
3443 }
3444
3445 impl ExpensiveData {
3446 fn new(size: usize) -> Self {
3447 Self {
3448 large_vec: vec![0u8; size],
3449 }
3450 }
3451
3452 fn size(&self) -> usize {
3453 self.large_vec.len()
3454 }
3455 }
3456
3457 struct Root {
3458 expensive: ExpensiveData,
3459 }
3460
3461 let root = Root {
3462 expensive: ExpensiveData::new(1_000_000), };
3464
3465 let expensive_kp = KpType::new(
3466 |r: &Root| Some(&r.expensive),
3467 |r: &mut Root| Some(&mut r.expensive),
3468 );
3469
3470 let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3472 assert_eq!(size_kp.get(&root), Some(1_000_000));
3473
3474 let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3476 assert!(large_filter.get(&root).is_some());
3477
3478 }
3480
3481 #[test]
3482 fn test_hof_with_arc_no_extra_clones() {
3483 use std::sync::Arc;
3484
3485 #[derive(Debug)]
3486 struct SharedData {
3487 value: String,
3488 }
3489
3490 struct Root {
3491 shared: Arc<SharedData>,
3492 }
3493
3494 let shared = Arc::new(SharedData {
3495 value: "shared".to_string(),
3496 });
3497
3498 assert_eq!(Arc::strong_count(&shared), 1);
3500
3501 {
3502 let root = Root {
3503 shared: Arc::clone(&shared),
3504 };
3505
3506 assert_eq!(Arc::strong_count(&shared), 2);
3508
3509 let shared_kp = KpType::new(
3510 |r: &Root| Some(&r.shared),
3511 |r: &mut Root| Some(&mut r.shared),
3512 );
3513
3514 let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3516
3517 assert_eq!(value_kp.get(&root), Some(6));
3519 assert_eq!(Arc::strong_count(&shared), 2); let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3523 assert!(filtered.get(&root).is_some());
3524 assert_eq!(Arc::strong_count(&shared), 2); } assert_eq!(Arc::strong_count(&shared), 1); }
3529
3530 #[test]
3531 fn test_closure_captures_not_root_values() {
3532 use std::sync::Arc;
3533 use std::sync::atomic::{AtomicUsize, Ordering};
3534
3535 let call_count = Arc::new(AtomicUsize::new(0));
3537 let call_count_clone = Arc::clone(&call_count);
3538
3539 struct Root {
3540 value: i32,
3541 }
3542
3543 let root = Root { value: 42 };
3544
3545 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3546
3547 let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3550 call_count_clone.fetch_add(1, Ordering::SeqCst);
3551 v * 2
3552 });
3553
3554 assert_eq!(doubled(&root), 84);
3556 assert_eq!(doubled(&root), 84);
3557 assert_eq!(doubled(&root), 84);
3558
3559 assert_eq!(call_count.load(Ordering::SeqCst), 3);
3561
3562 }
3564
3565 #[test]
3566 fn test_static_with_borrowed_data() {
3567 struct Root {
3571 data: String,
3572 }
3573
3574 {
3575 let root = Root {
3576 data: "temporary".to_string(),
3577 };
3578
3579 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3580
3581 let len_kp = data_kp.map(|s: &String| s.len());
3583 assert_eq!(len_kp.get(&root), Some(9));
3584
3585 } }
3590
3591 #[test]
3592 fn test_multiple_hof_operations_no_accumulation() {
3593 use std::sync::Arc;
3594 use std::sync::atomic::{AtomicUsize, Ordering};
3595
3596 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3597
3598 struct Tracked {
3599 id: usize,
3600 }
3601
3602 impl Drop for Tracked {
3603 fn drop(&mut self) {
3604 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3605 }
3606 }
3607
3608 struct Root {
3609 values: Vec<Tracked>,
3610 }
3611
3612 DROP_COUNT.store(0, Ordering::SeqCst);
3613
3614 {
3615 let root = Root {
3616 values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3617 };
3618
3619 let values_kp = KpType::new(
3620 |r: &Root| Some(&r.values),
3621 |r: &mut Root| Some(&mut r.values),
3622 );
3623
3624 let count = values_kp.count_items(|v| v.len());
3626 let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3627 let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3628 let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3629
3630 assert_eq!(count(&root), Some(3));
3631 assert_eq!(sum(&root), Some(6));
3632 assert!(has_2(&root));
3633 assert!(all_positive(&root));
3634
3635 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3637 }
3638
3639 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3641 }
3642
3643 #[test]
3644 fn test_copy_bound_only_for_function_not_data() {
3645 #[derive(Debug)]
3649 struct NonCopyData {
3650 value: String,
3651 }
3652
3653 struct Root {
3654 data: NonCopyData,
3655 }
3656
3657 let root = Root {
3658 data: NonCopyData {
3659 value: "test".to_string(),
3660 },
3661 };
3662
3663 let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3664
3665 let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3668 assert_eq!(len_kp.get(&root), Some(4));
3669
3670 let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3672 assert!(filtered.get(&root).is_some());
3673 }
3674
3675 #[test]
3676 fn test_no_memory_leak_with_cyclic_references() {
3677 use std::sync::atomic::{AtomicUsize, Ordering};
3678 use std::sync::{Arc, Weak};
3679
3680 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3681
3682 struct Node {
3683 id: usize,
3684 parent: Option<Weak<Node>>,
3685 }
3686
3687 impl Drop for Node {
3688 fn drop(&mut self) {
3689 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3690 }
3691 }
3692
3693 struct Root {
3694 node: Arc<Node>,
3695 }
3696
3697 DROP_COUNT.store(0, Ordering::SeqCst);
3698
3699 {
3700 let root = Root {
3701 node: Arc::new(Node {
3702 id: 1,
3703 parent: None,
3704 }),
3705 };
3706
3707 let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3708
3709 let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3711 assert_eq!(id_kp.get(&root), Some(1));
3712
3713 assert_eq!(Arc::strong_count(&root.node), 1);
3715
3716 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3718 }
3719
3720 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3722 }
3723
3724 #[test]
3725 fn test_hof_operations_are_zero_cost_abstractions() {
3726 struct Root {
3730 value: i32,
3731 }
3732
3733 let root = Root { value: 10 };
3734
3735 let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3736
3737 let direct_result = value_kp.get(&root).map(|v| v * 2);
3739 assert_eq!(direct_result, Some(20));
3740
3741 let mapped_kp = value_kp.map(|v: &i32| v * 2);
3743 let hof_result = mapped_kp.get(&root);
3744 assert_eq!(hof_result, Some(20));
3745
3746 assert_eq!(direct_result, hof_result);
3748 }
3749
3750 #[test]
3751 fn test_complex_closure_captures_allowed() {
3752 use std::sync::Arc;
3753
3754 struct Root {
3756 scores: Vec<i32>,
3757 }
3758
3759 let root = Root {
3760 scores: vec![85, 92, 78, 95, 88],
3761 };
3762
3763 let scores_kp = KpType::new(
3764 |r: &Root| Some(&r.scores),
3765 |r: &mut Root| Some(&mut r.scores),
3766 );
3767
3768 let threshold = 90;
3770 let multiplier = Arc::new(2);
3771
3772 let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3774 let high: i32 = scores
3775 .iter()
3776 .filter(|&&s| s >= threshold)
3777 .map(|&s| s * *multiplier)
3778 .sum();
3779 acc + high
3780 });
3781
3782 assert_eq!(high_scores_doubled(&root), 374);
3784 }
3785
3786 #[test]
3790 fn test_pkp_filter_by_value_type() {
3791 use std::any::TypeId;
3792
3793 #[derive(Debug)]
3794 struct User {
3795 name: String,
3796 age: i32,
3797 score: f64,
3798 active: bool,
3799 }
3800
3801 let user = User {
3802 name: "Alice".to_string(),
3803 age: 30,
3804 score: 95.5,
3805 active: true,
3806 };
3807
3808 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3810 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3811 let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3812 let active_kp = KpType::new(
3813 |u: &User| Some(&u.active),
3814 |u: &mut User| Some(&mut u.active),
3815 );
3816
3817 let all_keypaths: Vec<PKp<User>> = vec![
3819 PKp::new(name_kp),
3820 PKp::new(age_kp),
3821 PKp::new(score_kp),
3822 PKp::new(active_kp),
3823 ];
3824
3825 let string_kps: Vec<_> = all_keypaths
3827 .iter()
3828 .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3829 .collect();
3830
3831 assert_eq!(string_kps.len(), 1);
3832 assert_eq!(
3833 string_kps[0].get_as::<String>(&user),
3834 Some(&"Alice".to_string())
3835 );
3836
3837 let i32_kps: Vec<_> = all_keypaths
3839 .iter()
3840 .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3841 .collect();
3842
3843 assert_eq!(i32_kps.len(), 1);
3844 assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3845
3846 let f64_kps: Vec<_> = all_keypaths
3848 .iter()
3849 .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3850 .collect();
3851
3852 assert_eq!(f64_kps.len(), 1);
3853 assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3854
3855 let bool_kps: Vec<_> = all_keypaths
3857 .iter()
3858 .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3859 .collect();
3860
3861 assert_eq!(bool_kps.len(), 1);
3862 assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3863 }
3864
3865 #[test]
3866 fn test_pkp_filter_by_struct_type() {
3867 use std::any::TypeId;
3868
3869 #[derive(Debug, PartialEq)]
3870 struct Address {
3871 street: String,
3872 city: String,
3873 }
3874
3875 #[derive(Debug)]
3876 struct User {
3877 name: String,
3878 age: i32,
3879 address: Address,
3880 }
3881
3882 let user = User {
3883 name: "Bob".to_string(),
3884 age: 25,
3885 address: Address {
3886 street: "123 Main St".to_string(),
3887 city: "NYC".to_string(),
3888 },
3889 };
3890
3891 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3893 let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3894 let address_kp = KpType::new(
3895 |u: &User| Some(&u.address),
3896 |u: &mut User| Some(&mut u.address),
3897 );
3898
3899 let all_keypaths: Vec<PKp<User>> =
3900 vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
3901
3902 let struct_kps: Vec<_> = all_keypaths
3904 .iter()
3905 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
3906 .collect();
3907
3908 assert_eq!(struct_kps.len(), 1);
3909 assert_eq!(
3910 struct_kps[0].get_as::<Address>(&user),
3911 Some(&Address {
3912 street: "123 Main St".to_string(),
3913 city: "NYC".to_string(),
3914 })
3915 );
3916
3917 let primitive_kps: Vec<_> = all_keypaths
3919 .iter()
3920 .filter(|pkp| {
3921 pkp.value_type_id() == TypeId::of::<String>()
3922 || pkp.value_type_id() == TypeId::of::<i32>()
3923 })
3924 .collect();
3925
3926 assert_eq!(primitive_kps.len(), 2);
3927 }
3928
3929 #[test]
3930 fn test_pkp_filter_by_arc_type() {
3931 use std::any::TypeId;
3932 use std::sync::Arc;
3933
3934 #[derive(Debug)]
3935 struct User {
3936 name: String,
3937 shared_data: Arc<String>,
3938 shared_number: Arc<i32>,
3939 }
3940
3941 let user = User {
3942 name: "Charlie".to_string(),
3943 shared_data: Arc::new("shared".to_string()),
3944 shared_number: Arc::new(42),
3945 };
3946
3947 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3949 let shared_data_kp = KpType::new(
3950 |u: &User| Some(&u.shared_data),
3951 |u: &mut User| Some(&mut u.shared_data),
3952 );
3953 let shared_number_kp = KpType::new(
3954 |u: &User| Some(&u.shared_number),
3955 |u: &mut User| Some(&mut u.shared_number),
3956 );
3957
3958 let all_keypaths: Vec<PKp<User>> = vec![
3959 PKp::new(name_kp),
3960 PKp::new(shared_data_kp),
3961 PKp::new(shared_number_kp),
3962 ];
3963
3964 let arc_string_kps: Vec<_> = all_keypaths
3966 .iter()
3967 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
3968 .collect();
3969
3970 assert_eq!(arc_string_kps.len(), 1);
3971 assert_eq!(
3972 arc_string_kps[0]
3973 .get_as::<Arc<String>>(&user)
3974 .map(|arc| arc.as_str()),
3975 Some("shared")
3976 );
3977
3978 let arc_i32_kps: Vec<_> = all_keypaths
3980 .iter()
3981 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
3982 .collect();
3983
3984 assert_eq!(arc_i32_kps.len(), 1);
3985 assert_eq!(
3986 arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
3987 Some(42)
3988 );
3989
3990 let all_arc_kps: Vec<_> = all_keypaths
3992 .iter()
3993 .filter(|pkp| {
3994 pkp.value_type_id() == TypeId::of::<Arc<String>>()
3995 || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
3996 })
3997 .collect();
3998
3999 assert_eq!(all_arc_kps.len(), 2);
4000 }
4001
4002 #[test]
4003 fn test_pkp_filter_by_box_type() {
4004 use std::any::TypeId;
4005
4006 #[derive(Debug)]
4007 struct User {
4008 name: String,
4009 boxed_value: Box<i32>,
4010 boxed_string: Box<String>,
4011 }
4012
4013 let user = User {
4014 name: "Diana".to_string(),
4015 boxed_value: Box::new(100),
4016 boxed_string: Box::new("boxed".to_string()),
4017 };
4018
4019 let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4021 let boxed_value_kp = KpType::new(
4022 |u: &User| Some(&u.boxed_value),
4023 |u: &mut User| Some(&mut u.boxed_value),
4024 );
4025 let boxed_string_kp = KpType::new(
4026 |u: &User| Some(&u.boxed_string),
4027 |u: &mut User| Some(&mut u.boxed_string),
4028 );
4029
4030 let all_keypaths: Vec<PKp<User>> = vec![
4031 PKp::new(name_kp),
4032 PKp::new(boxed_value_kp),
4033 PKp::new(boxed_string_kp),
4034 ];
4035
4036 let box_i32_kps: Vec<_> = all_keypaths
4038 .iter()
4039 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
4040 .collect();
4041
4042 assert_eq!(box_i32_kps.len(), 1);
4043 assert_eq!(
4044 box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
4045 Some(100)
4046 );
4047
4048 let box_string_kps: Vec<_> = all_keypaths
4050 .iter()
4051 .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
4052 .collect();
4053
4054 assert_eq!(box_string_kps.len(), 1);
4055 assert_eq!(
4056 box_string_kps[0]
4057 .get_as::<Box<String>>(&user)
4058 .map(|b| b.as_str()),
4059 Some("boxed")
4060 );
4061 }
4062
4063 #[test]
4064 fn test_akp_filter_by_root_and_value_type() {
4065 use std::any::TypeId;
4066
4067 #[derive(Debug)]
4068 struct User {
4069 name: String,
4070 age: i32,
4071 }
4072
4073 #[derive(Debug)]
4074 struct Product {
4075 title: String,
4076 price: f64,
4077 }
4078
4079 let user = User {
4080 name: "Eve".to_string(),
4081 age: 28,
4082 };
4083
4084 let product = Product {
4085 title: "Book".to_string(),
4086 price: 19.99,
4087 };
4088
4089 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4091 let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
4092 let product_title_kp = KpType::new(
4093 |p: &Product| Some(&p.title),
4094 |p: &mut Product| Some(&mut p.title),
4095 );
4096 let product_price_kp = KpType::new(
4097 |p: &Product| Some(&p.price),
4098 |p: &mut Product| Some(&mut p.price),
4099 );
4100
4101 let all_keypaths: Vec<AKp> = vec![
4102 AKp::new(user_name_kp),
4103 AKp::new(user_age_kp),
4104 AKp::new(product_title_kp),
4105 AKp::new(product_price_kp),
4106 ];
4107
4108 let user_kps: Vec<_> = all_keypaths
4110 .iter()
4111 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4112 .collect();
4113
4114 assert_eq!(user_kps.len(), 2);
4115
4116 let product_kps: Vec<_> = all_keypaths
4118 .iter()
4119 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4120 .collect();
4121
4122 assert_eq!(product_kps.len(), 2);
4123
4124 let string_value_kps: Vec<_> = all_keypaths
4126 .iter()
4127 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4128 .collect();
4129
4130 assert_eq!(string_value_kps.len(), 2);
4131
4132 let user_string_kps: Vec<_> = all_keypaths
4134 .iter()
4135 .filter(|akp| {
4136 akp.root_type_id() == TypeId::of::<User>()
4137 && akp.value_type_id() == TypeId::of::<String>()
4138 })
4139 .collect();
4140
4141 assert_eq!(user_string_kps.len(), 1);
4142 assert_eq!(
4143 user_string_kps[0].get_as::<User, String>(&user),
4144 Some(Some(&"Eve".to_string()))
4145 );
4146
4147 let product_f64_kps: Vec<_> = all_keypaths
4149 .iter()
4150 .filter(|akp| {
4151 akp.root_type_id() == TypeId::of::<Product>()
4152 && akp.value_type_id() == TypeId::of::<f64>()
4153 })
4154 .collect();
4155
4156 assert_eq!(product_f64_kps.len(), 1);
4157 assert_eq!(
4158 product_f64_kps[0].get_as::<Product, f64>(&product),
4159 Some(Some(&19.99))
4160 );
4161 }
4162
4163 #[test]
4164 fn test_akp_filter_by_arc_root_type() {
4165 use std::any::TypeId;
4166 use std::sync::Arc;
4167
4168 #[derive(Debug)]
4169 struct User {
4170 name: String,
4171 }
4172
4173 #[derive(Debug)]
4174 struct Product {
4175 title: String,
4176 }
4177
4178 let user = User {
4179 name: "Frank".to_string(),
4180 };
4181 let product = Product {
4182 title: "Laptop".to_string(),
4183 };
4184
4185 let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4187 let product_title_kp = KpType::new(
4188 |p: &Product| Some(&p.title),
4189 |p: &mut Product| Some(&mut p.title),
4190 );
4191
4192 let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4194 let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4195
4196 let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4197
4198 let arc_user_kps: Vec<_> = all_keypaths
4200 .iter()
4201 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4202 .collect();
4203
4204 assert_eq!(arc_user_kps.len(), 1);
4205
4206 let arc_user = Arc::new(user);
4208 assert_eq!(
4209 arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4210 Some(Some(&"Frank".to_string()))
4211 );
4212
4213 let arc_product_kps: Vec<_> = all_keypaths
4215 .iter()
4216 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4217 .collect();
4218
4219 assert_eq!(arc_product_kps.len(), 1);
4220
4221 let arc_product = Arc::new(product);
4223 assert_eq!(
4224 arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4225 Some(Some(&"Laptop".to_string()))
4226 );
4227 }
4228
4229 #[test]
4230 fn test_akp_filter_by_box_root_type() {
4231 use std::any::TypeId;
4232
4233 #[derive(Debug)]
4234 struct Config {
4235 setting: String,
4236 }
4237
4238 let config = Config {
4239 setting: "enabled".to_string(),
4240 };
4241
4242 let config_kp1 = KpType::new(
4244 |c: &Config| Some(&c.setting),
4245 |c: &mut Config| Some(&mut c.setting),
4246 );
4247 let config_kp2 = KpType::new(
4248 |c: &Config| Some(&c.setting),
4249 |c: &mut Config| Some(&mut c.setting),
4250 );
4251
4252 let regular_akp = AKp::new(config_kp1);
4254 let box_akp = AKp::new(config_kp2).for_box::<Config>();
4255
4256 let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4257
4258 let config_kps: Vec<_> = all_keypaths
4260 .iter()
4261 .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4262 .collect();
4263
4264 assert_eq!(config_kps.len(), 1);
4265 assert_eq!(
4266 config_kps[0].get_as::<Config, String>(&config),
4267 Some(Some(&"enabled".to_string()))
4268 );
4269
4270 let box_config_kps: Vec<_> = all_keypaths
4272 .iter()
4273 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4274 .collect();
4275
4276 assert_eq!(box_config_kps.len(), 1);
4277
4278 let box_config = Box::new(Config {
4280 setting: "enabled".to_string(),
4281 });
4282 assert_eq!(
4283 box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4284 Some(Some(&"enabled".to_string()))
4285 );
4286 }
4287
4288 #[test]
4289 fn test_mixed_collection_type_filtering() {
4290 use std::any::TypeId;
4291 use std::sync::Arc;
4292
4293 #[derive(Debug)]
4294 struct User {
4295 name: String,
4296 email: String,
4297 }
4298
4299 #[derive(Debug)]
4300 struct Product {
4301 title: String,
4302 sku: String,
4303 }
4304
4305 let user = User {
4306 name: "Grace".to_string(),
4307 email: "grace@example.com".to_string(),
4308 };
4309
4310 let product = Product {
4311 title: "Widget".to_string(),
4312 sku: "WID-001".to_string(),
4313 };
4314
4315 let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4317 let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4318 let user_email_kp1 =
4319 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4320 let user_email_kp2 =
4321 KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4322 let product_title_kp = KpType::new(
4323 |p: &Product| Some(&p.title),
4324 |p: &mut Product| Some(&mut p.title),
4325 );
4326 let product_sku_kp = KpType::new(
4327 |p: &Product| Some(&p.sku),
4328 |p: &mut Product| Some(&mut p.sku),
4329 );
4330
4331 let all_keypaths: Vec<AKp> = vec![
4332 AKp::new(user_name_kp1),
4333 AKp::new(user_email_kp1),
4334 AKp::new(product_title_kp),
4335 AKp::new(product_sku_kp),
4336 AKp::new(user_name_kp2).for_arc::<User>(),
4337 AKp::new(user_email_kp2).for_box::<User>(),
4338 ];
4339
4340 let string_value_kps: Vec<_> = all_keypaths
4342 .iter()
4343 .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4344 .collect();
4345
4346 assert_eq!(string_value_kps.len(), 6); let user_root_kps: Vec<_> = all_keypaths
4350 .iter()
4351 .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4352 .collect();
4353
4354 assert_eq!(user_root_kps.len(), 2);
4355
4356 let arc_user_kps: Vec<_> = all_keypaths
4358 .iter()
4359 .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4360 .collect();
4361
4362 assert_eq!(arc_user_kps.len(), 1);
4363
4364 let box_user_kps: Vec<_> = all_keypaths
4366 .iter()
4367 .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4368 .collect();
4369
4370 assert_eq!(box_user_kps.len(), 1);
4371
4372 let product_kps: Vec<_> = all_keypaths
4374 .iter()
4375 .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4376 .collect();
4377
4378 assert_eq!(product_kps.len(), 2);
4379
4380 let user_value = user_root_kps[0].get_as::<User, String>(&user);
4382 assert!(user_value.is_some());
4383 assert!(user_value.unwrap().is_some());
4384 }
4385
4386 #[test]
4391 fn test_kp_with_pin() {
4392 use std::pin::Pin;
4393
4394 #[derive(Debug)]
4398 struct SelfReferential {
4399 value: String,
4400 ptr_to_value: *const String, }
4402
4403 impl SelfReferential {
4404 fn new(s: String) -> Self {
4405 let mut sr = Self {
4406 value: s,
4407 ptr_to_value: std::ptr::null(),
4408 };
4409 sr.ptr_to_value = &sr.value as *const String;
4411 sr
4412 }
4413
4414 fn get_value(&self) -> &str {
4415 &self.value
4416 }
4417 }
4418
4419 let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4421 let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4422
4423 let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4425 |p: &Pin<Box<SelfReferential>>| {
4426 Some(&p.as_ref().get_ref().value)
4428 },
4429 |p: &mut Pin<Box<SelfReferential>>| {
4430 unsafe {
4433 let sr = Pin::get_unchecked_mut(p.as_mut());
4434 Some(&mut sr.value)
4435 }
4436 },
4437 );
4438
4439 let result = kp.get(&pinned);
4441 assert_eq!(result, Some(&"pinned_data".to_string()));
4442
4443 assert_eq!(pinned.get_value(), "pinned_data");
4445 }
4446
4447 #[test]
4448 fn test_kp_with_pin_arc() {
4449 use std::pin::Pin;
4450 use std::sync::Arc;
4451
4452 struct AsyncState {
4453 status: String,
4454 data: Vec<i32>,
4455 }
4456
4457 let state = AsyncState {
4459 status: "ready".to_string(),
4460 data: vec![1, 2, 3, 4, 5],
4461 };
4462
4463 let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4464
4465 let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4467 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4468 |_: &mut Pin<Arc<AsyncState>>| {
4469 None::<&mut String>
4471 },
4472 );
4473
4474 let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4476 |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4477 |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4478 );
4479
4480 let status = status_kp.get(&pinned_arc);
4481 assert_eq!(status, Some(&"ready".to_string()));
4482
4483 let data = data_kp.get(&pinned_arc);
4484 assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4485 }
4486
4487 #[test]
4488 fn test_kp_with_maybe_uninit() {
4489 use std::mem::MaybeUninit;
4490
4491 struct Config {
4495 name: MaybeUninit<String>,
4496 value: MaybeUninit<i32>,
4497 initialized: bool,
4498 }
4499
4500 impl Config {
4501 fn new_uninit() -> Self {
4502 Self {
4503 name: MaybeUninit::uninit(),
4504 value: MaybeUninit::uninit(),
4505 initialized: false,
4506 }
4507 }
4508
4509 fn init(&mut self, name: String, value: i32) {
4510 self.name.write(name);
4511 self.value.write(value);
4512 self.initialized = true;
4513 }
4514
4515 fn get_name(&self) -> Option<&String> {
4516 if self.initialized {
4517 unsafe { Some(self.name.assume_init_ref()) }
4518 } else {
4519 None
4520 }
4521 }
4522
4523 fn get_value(&self) -> Option<&i32> {
4524 if self.initialized {
4525 unsafe { Some(self.value.assume_init_ref()) }
4526 } else {
4527 None
4528 }
4529 }
4530 }
4531
4532 let name_kp: KpType<Config, String> = Kp::new(
4534 |c: &Config| c.get_name(),
4535 |c: &mut Config| {
4536 if c.initialized {
4537 unsafe { Some(c.name.assume_init_mut()) }
4538 } else {
4539 None
4540 }
4541 },
4542 );
4543
4544 let value_kp: KpType<Config, i32> = Kp::new(
4545 |c: &Config| c.get_value(),
4546 |c: &mut Config| {
4547 if c.initialized {
4548 unsafe { Some(c.value.assume_init_mut()) }
4549 } else {
4550 None
4551 }
4552 },
4553 );
4554
4555 let uninit_config = Config::new_uninit();
4557 assert_eq!(name_kp.get(&uninit_config), None);
4558 assert_eq!(value_kp.get(&uninit_config), None);
4559
4560 let mut init_config = Config::new_uninit();
4562 init_config.init("test_config".to_string(), 42);
4563
4564 assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4565 assert_eq!(value_kp.get(&init_config), Some(&42));
4566
4567 if let Some(val) = value_kp.get_mut(&mut init_config) {
4569 *val = 100;
4570 }
4571
4572 assert_eq!(value_kp.get(&init_config), Some(&100));
4573 }
4574
4575 #[test]
4576 fn test_kp_with_weak() {
4577 use std::sync::{Arc, Weak};
4578
4579 #[derive(Debug, Clone)]
4583 struct Node {
4584 value: i32,
4585 }
4586
4587 struct NodeWithParent {
4588 value: i32,
4589 parent: Option<Arc<Node>>, }
4591
4592 let parent = Arc::new(Node { value: 100 });
4593
4594 let child = NodeWithParent {
4595 value: 42,
4596 parent: Some(parent.clone()),
4597 };
4598
4599 let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4601 |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4602 |_: &mut NodeWithParent| None::<&mut i32>,
4603 );
4604
4605 let parent_val = parent_value_kp.get(&child);
4607 assert_eq!(parent_val, Some(&100));
4608 }
4609
4610 #[test]
4611 fn test_kp_with_rc_weak() {
4612 use std::rc::Rc;
4613
4614 struct TreeNode {
4617 value: String,
4618 parent: Option<Rc<TreeNode>>, }
4620
4621 let root = Rc::new(TreeNode {
4622 value: "root".to_string(),
4623 parent: None,
4624 });
4625
4626 let child1 = TreeNode {
4627 value: "child1".to_string(),
4628 parent: Some(root.clone()),
4629 };
4630
4631 let child2 = TreeNode {
4632 value: "child2".to_string(),
4633 parent: Some(root.clone()),
4634 };
4635
4636 let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4638 |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4639 |_: &mut TreeNode| None::<&mut String>,
4640 );
4641
4642 assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4644 assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4645
4646 assert_eq!(parent_name_kp.get(&root), None);
4648 }
4649
4650 #[test]
4651 fn test_kp_with_complex_weak_structure() {
4652 use std::sync::Arc;
4653
4654 struct Cache {
4657 data: String,
4658 backup: Option<Arc<Cache>>, }
4660
4661 let primary = Arc::new(Cache {
4662 data: "primary_data".to_string(),
4663 backup: None,
4664 });
4665
4666 let backup = Arc::new(Cache {
4667 data: "backup_data".to_string(),
4668 backup: Some(primary.clone()),
4669 });
4670
4671 let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4673 |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4674 |_: &mut Arc<Cache>| None::<&mut String>,
4675 );
4676
4677 let data = backup_data_kp.get(&backup);
4679 assert_eq!(data, Some(&"primary_data".to_string()));
4680
4681 let no_backup = backup_data_kp.get(&primary);
4683 assert_eq!(no_backup, None);
4684 }
4685
4686 #[test]
4687 fn test_kp_chain_with_pin_and_arc() {
4688 use std::pin::Pin;
4689 use std::sync::Arc;
4690
4691 struct Outer {
4694 inner: Arc<Inner>,
4695 }
4696
4697 struct Inner {
4698 value: String,
4699 }
4700
4701 let outer = Outer {
4702 inner: Arc::new(Inner {
4703 value: "nested_value".to_string(),
4704 }),
4705 };
4706
4707 let pinned_outer = Box::pin(outer);
4708
4709 let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4711 |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4712 |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4713 );
4714
4715 let to_value: KpType<Arc<Inner>, String> = Kp::new(
4717 |a: &Arc<Inner>| Some(&a.value),
4718 |_: &mut Arc<Inner>| None::<&mut String>,
4719 );
4720
4721 let chained = to_inner.then(to_value);
4723
4724 let result = chained.get(&pinned_outer);
4725 assert_eq!(result, Some(&"nested_value".to_string()));
4726 }
4727
4728 #[test]
4729 fn test_kp_with_maybe_uninit_array() {
4730 use std::mem::MaybeUninit;
4731
4732 struct Buffer {
4736 data: [MaybeUninit<u8>; 10],
4737 len: usize,
4738 }
4739
4740 impl Buffer {
4741 fn new() -> Self {
4742 Self {
4743 data: unsafe { MaybeUninit::uninit().assume_init() },
4744 len: 0,
4745 }
4746 }
4747
4748 fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4749 if self.len >= self.data.len() {
4750 return Err("Buffer full");
4751 }
4752 self.data[self.len].write(byte);
4753 self.len += 1;
4754 Ok(())
4755 }
4756
4757 fn get(&self, idx: usize) -> Option<&u8> {
4758 if idx < self.len {
4759 unsafe { Some(self.data[idx].assume_init_ref()) }
4760 } else {
4761 None
4762 }
4763 }
4764
4765 fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4766 if idx < self.len {
4767 unsafe { Some(self.data[idx].assume_init_mut()) }
4768 } else {
4769 None
4770 }
4771 }
4772 }
4773
4774 let len_kp: KpType<Buffer, usize> =
4776 Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4777
4778 let mut buffer = Buffer::new();
4779
4780 assert_eq!(len_kp.get(&buffer), Some(&0));
4782
4783 buffer.push(1).unwrap();
4785 buffer.push(2).unwrap();
4786 buffer.push(3).unwrap();
4787
4788 assert_eq!(len_kp.get(&buffer), Some(&3));
4790
4791 assert_eq!(buffer.get(0), Some(&1));
4793 assert_eq!(buffer.get(1), Some(&2));
4794 assert_eq!(buffer.get(2), Some(&3));
4795 assert_eq!(buffer.get(10), None); if let Some(elem) = buffer.get_mut(1) {
4799 *elem = 20;
4800 }
4801 assert_eq!(buffer.get(1), Some(&20));
4802 }
4803
4804 #[test]
4805 fn test_kp_then_lock_deep_structs() {
4806 use std::sync::{Arc, Mutex};
4807
4808 #[derive(Clone)]
4809 struct Root {
4810 guard: Arc<Mutex<Level1>>,
4811 }
4812 #[derive(Clone)]
4813 struct Level1 {
4814 name: String,
4815 nested: Level2,
4816 }
4817 #[derive(Clone)]
4818 struct Level2 {
4819 count: i32,
4820 }
4821
4822 let root = Root {
4823 guard: Arc::new(Mutex::new(Level1 {
4824 name: "deep".to_string(),
4825 nested: Level2 { count: 42 },
4826 })),
4827 };
4828
4829 let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4830 Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4831
4832 let lock_kp = {
4833 let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
4834 Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
4835 let next: KpType<Level1, Level1> =
4836 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4837 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4838 };
4839
4840 let chained = kp_to_guard.then_lock(lock_kp);
4841 let level1 = chained.get(&root);
4842 assert!(level1.is_some());
4843 assert_eq!(level1.unwrap().name, "deep");
4844 assert_eq!(level1.unwrap().nested.count, 42);
4845
4846 let mut_root = &mut root.clone();
4847 let mut_level1 = chained.get_mut(mut_root);
4848 assert!(mut_level1.is_some());
4849 mut_level1.unwrap().nested.count = 99;
4850 assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4851 }
4852
4853 #[test]
4854 fn test_kp_then_lock_with_enum() {
4855 use std::sync::{Arc, Mutex};
4856
4857 #[derive(Clone)]
4858 enum Message {
4859 Request(LevelA),
4860 Response(i32),
4861 }
4862 #[derive(Clone)]
4863 struct LevelA {
4864 data: Arc<Mutex<i32>>,
4865 }
4866
4867 struct RootWithEnum {
4868 msg: Arc<Mutex<Message>>,
4869 }
4870
4871 let root = RootWithEnum {
4872 msg: Arc::new(Mutex::new(Message::Request(LevelA {
4873 data: Arc::new(Mutex::new(100)),
4874 }))),
4875 };
4876
4877 let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
4878 Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
4879
4880 let lock_kp_msg = {
4881 let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
4882 Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
4883 let next: KpType<Message, Message> =
4884 Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4885 crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4886 };
4887
4888 let chained = kp_msg.then_lock(lock_kp_msg);
4889 let msg = chained.get(&root);
4890 assert!(msg.is_some());
4891 match msg.unwrap() {
4892 Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
4893 Message::Response(_) => panic!("expected Request"),
4894 }
4895 }
4896
4897 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4898 #[tokio::test]
4899 async fn test_kp_then_async_deep_chain() {
4900 use std::sync::Arc;
4901 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4902
4903 #[derive(Clone)]
4904 struct Root {
4905 tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
4906 }
4907 #[derive(Clone)]
4908 struct Level1 {
4909 value: i32,
4910 }
4911
4912 let root = Root {
4913 tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
4914 };
4915
4916 let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
4917 |r: &Root| Some(&r.tokio_guard),
4918 |r: &mut Root| Some(&mut r.tokio_guard),
4919 );
4920
4921 let async_kp = {
4922 let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
4923 Kp::new(
4924 |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
4925 |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
4926 );
4927 let next: KpType<Level1, Level1> =
4928 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4929 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4930 };
4931
4932 let chained = kp_to_guard.then_async(async_kp);
4933 let level1 = chained.get(&root).await;
4934 assert!(level1.is_some());
4935 assert_eq!(level1.unwrap().value, 7);
4936 }
4937
4938 #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4941 #[tokio::test]
4942 async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
4943 use std::sync::{Arc, Mutex};
4944 use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4945 use crate::lock::{LockKp, ArcMutexAccess};
4946
4947 #[derive(Clone)]
4949 struct Root {
4950 sync_mutex: Arc<Mutex<Level1>>,
4951 }
4952 #[derive(Clone)]
4954 struct Level1 {
4955 inner: Level2,
4956 }
4957 #[derive(Clone)]
4959 struct Level2 {
4960 tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
4961 }
4962 #[derive(Clone)]
4964 struct Level3 {
4965 leaf: i32,
4966 }
4967
4968 let mut root = Root {
4969 sync_mutex: Arc::new(Mutex::new(Level1 {
4970 inner: Level2 {
4971 tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
4972 },
4973 })),
4974 };
4975
4976 let identity_l1: KpType<Level1, Level1> =
4978 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4979 let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
4980 Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
4981 let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
4982
4983 let kp_l1_inner: KpType<Level1, Level2> =
4985 Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
4986
4987 let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
4989 |l: &Level2| Some(&l.tokio_mutex),
4990 |l: &mut Level2| Some(&mut l.tokio_mutex),
4991 );
4992
4993 let async_l3 = {
4995 let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
4996 Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
4997 let next: KpType<Level3, Level3> =
4998 Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
4999 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
5000 };
5001
5002 let kp_l3_leaf: KpType<Level3, i32> =
5004 Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
5005
5006 let step1 = lock_root_to_l1.then(kp_l1_inner);
5008 let step2 = step1.then(kp_l2_tokio);
5009 let step3 = step2.then_async(async_l3);
5010 let deep_chain = step3.then(kp_l3_leaf);
5011
5012 let leaf = deep_chain.get(&root).await;
5014 deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
5015 assert_eq!(leaf, Some(&100));
5016
5017 let mut root_mut = root.clone();
5019 let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
5020 assert!(leaf_mut.is_some());
5021 *leaf_mut.unwrap() = 99;
5022
5023 let leaf_after = deep_chain.get(&root_mut).await;
5025 assert_eq!(leaf_after, Some(&99));
5026 }
5027}