1use crate::Kp;
32use async_trait::async_trait;
33use std::sync::Arc;
34
35#[cfg(feature = "tokio")]
37pub use tokio::sync::{Mutex as TokioMutex, RwLock as TokioRwLock};
38
39#[async_trait]
57pub trait AsyncLockLike<Lock, Inner>: Send + Sync {
58 async fn lock_read(&self, lock: &Lock) -> Option<Inner>;
60
61 async fn lock_write(&self, lock: &mut Lock) -> Option<Inner>;
63}
64
65pub trait SyncKeyPathLike<Root, Value, MutRoot, MutValue> {
68 fn sync_get(&self, root: Root) -> Option<Value>;
69 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue>;
70}
71
72impl<R, V, Root, Value, MutRoot, MutValue, G, S> SyncKeyPathLike<Root, Value, MutRoot, MutValue>
73 for crate::Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
74where
75 Root: std::borrow::Borrow<R>,
76 Value: std::borrow::Borrow<V>,
77 MutRoot: std::borrow::BorrowMut<R>,
78 MutValue: std::borrow::BorrowMut<V>,
79 G: Fn(Root) -> Option<Value>,
80 S: Fn(MutRoot) -> Option<MutValue>,
81{
82 fn sync_get(&self, root: Root) -> Option<Value> {
83 self.get(root)
84 }
85 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue> {
86 self.get_mut(root)
87 }
88}
89
90impl<
91 R,
92 Lock,
93 Mid,
94 V,
95 Root,
96 LockValue,
97 MidValue,
98 Value,
99 MutRoot,
100 MutLock,
101 MutMid,
102 MutValue,
103 G1,
104 S1,
105 L,
106 G2,
107 S2,
108 >
109 SyncKeyPathLike<Root, Value, MutRoot, MutValue> for crate::lock::LockKp<
110 R,
111 Lock,
112 Mid,
113 V,
114 Root,
115 LockValue,
116 MidValue,
117 Value,
118 MutRoot,
119 MutLock,
120 MutMid,
121 MutValue,
122 G1,
123 S1,
124 L,
125 G2,
126 S2,
127 >
128where
129 Root: std::borrow::Borrow<R>,
130 LockValue: std::borrow::Borrow<Lock>,
131 MidValue: std::borrow::Borrow<Mid>,
132 Value: std::borrow::Borrow<V>,
133 MutRoot: std::borrow::BorrowMut<R>,
134 MutLock: std::borrow::BorrowMut<Lock>,
135 MutMid: std::borrow::BorrowMut<Mid>,
136 MutValue: std::borrow::BorrowMut<V>,
137 G1: Fn(Root) -> Option<LockValue>,
138 S1: Fn(MutRoot) -> Option<MutLock>,
139 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
140 G2: Fn(MidValue) -> Option<Value>,
141 S2: Fn(MutMid) -> Option<MutValue>,
142 V: Clone,
143{
144 #[inline]
145 fn sync_get(&self, root: Root) -> Option<Value> {
146 self.get(root)
147 }
148 #[inline]
149 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue> {
150 self.get_mut(root)
151 }
152}
153
154#[async_trait(?Send)]
165pub trait AsyncKeyPathLike<Root, MutRoot> {
166 type Value;
168 type MutValue;
170 async fn get(&self, root: Root) -> Option<Self::Value>;
172 async fn get_mut(&self, root: MutRoot) -> Option<Self::MutValue>;
174}
175
176#[derive(Clone)] pub struct AsyncLockKp<
201 R,
202 Lock,
203 Mid,
204 V,
205 Root,
206 LockValue,
207 MidValue,
208 Value,
209 MutRoot,
210 MutLock,
211 MutMid,
212 MutValue,
213 G1,
214 S1,
215 L,
216 G2,
217 S2,
218> where
219 Root: std::borrow::Borrow<R>,
220 LockValue: std::borrow::Borrow<Lock>,
221 MidValue: std::borrow::Borrow<Mid>,
222 Value: std::borrow::Borrow<V>,
223 MutRoot: std::borrow::BorrowMut<R>,
224 MutLock: std::borrow::BorrowMut<Lock>,
225 MutMid: std::borrow::BorrowMut<Mid>,
226 MutValue: std::borrow::BorrowMut<V>,
227 G1: Fn(Root) -> Option<LockValue> + Clone,
228 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
229 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
230 G2: Fn(MidValue) -> Option<Value> + Clone,
231 S2: Fn(MutMid) -> Option<MutValue> + Clone,
232{
233 pub prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
235
236 pub mid: L,
238
239 pub next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
241}
242
243impl<
244 R,
245 Lock,
246 Mid,
247 V,
248 Root,
249 LockValue,
250 MidValue,
251 Value,
252 MutRoot,
253 MutLock,
254 MutMid,
255 MutValue,
256 G1,
257 S1,
258 L,
259 G2,
260 S2,
261>
262 AsyncLockKp<
263 R,
264 Lock,
265 Mid,
266 V,
267 Root,
268 LockValue,
269 MidValue,
270 Value,
271 MutRoot,
272 MutLock,
273 MutMid,
274 MutValue,
275 G1,
276 S1,
277 L,
278 G2,
279 S2,
280 >
281where
282 Root: std::borrow::Borrow<R>,
283 LockValue: std::borrow::Borrow<Lock>,
284 MidValue: std::borrow::Borrow<Mid>,
285 Value: std::borrow::Borrow<V>,
286 MutRoot: std::borrow::BorrowMut<R>,
287 MutLock: std::borrow::BorrowMut<Lock>,
288 MutMid: std::borrow::BorrowMut<Mid>,
289 MutValue: std::borrow::BorrowMut<V>,
290 G1: Fn(Root) -> Option<LockValue> + Clone,
291 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
292 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
293 G2: Fn(MidValue) -> Option<Value> + Clone,
294 S2: Fn(MutMid) -> Option<MutValue> + Clone,
295{
296 pub fn new(
298 prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
299 mid: L,
300 next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
301 ) -> Self {
302 Self { prev, mid, next }
303 }
304
305 #[inline]
319 pub async fn get(&self, root: Root) -> Option<Value>
320 where
321 Lock: Clone,
322 {
323 let lock_value = (self.prev.get)(root)?;
326 let lock: &Lock = lock_value.borrow();
327 let lock_clone = lock.clone(); let mid_value = self.mid.lock_read(&lock_clone).await?;
331
332 (self.next.get)(mid_value)
334 }
335
336 #[inline]
338 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue>
339 where
340 Lock: Clone,
341 {
342 let mut lock_value = (self.prev.set)(root)?;
344 let lock: &mut Lock = lock_value.borrow_mut();
345 let mut lock_clone = lock.clone(); let mid_value = self.mid.lock_write(&mut lock_clone).await?;
349
350 (self.next.set)(mid_value)
352 }
353
354 pub async fn set<F>(&self, root: Root, updater: F) -> Result<(), String>
361 where
362 Lock: Clone,
363 F: FnOnce(&mut V),
364 {
365 let lock_value = (self.prev.get)(root).ok_or("Failed to get lock from root")?;
367 let lock: &Lock = lock_value.borrow();
368 let lock_clone = lock.clone(); let mut mid_value = self
372 .mid
373 .lock_read(&lock_clone)
374 .await
375 .ok_or("Failed to lock")?;
376
377 let mut mut_value = (self.next.set)(mid_value).ok_or("Failed to navigate to value")?;
379 let v: &mut V = mut_value.borrow_mut();
380
381 updater(v);
383
384 Ok(())
385 }
386
387 pub fn then<V2, Value2, MutValue2, G3, S3>(
403 self,
404 next_kp: crate::Kp<V, V2, Value, Value2, MutValue, MutValue2, G3, S3>,
405 ) -> AsyncLockKp<
406 R,
407 Lock,
408 Mid,
409 V2,
410 Root,
411 LockValue,
412 MidValue,
413 Value2,
414 MutRoot,
415 MutLock,
416 MutMid,
417 MutValue2,
418 G1,
419 S1,
420 L,
421 impl Fn(MidValue) -> Option<Value2> + Clone,
422 impl Fn(MutMid) -> Option<MutValue2> + Clone,
423 >
424 where
425 V: 'static,
426 V2: 'static,
427 Value: std::borrow::Borrow<V>,
428 Value2: std::borrow::Borrow<V2>,
429 MutValue: std::borrow::BorrowMut<V>,
430 MutValue2: std::borrow::BorrowMut<V2>,
431 G3: Fn(Value) -> Option<Value2> + Clone,
432 S3: Fn(MutValue) -> Option<MutValue2> + Clone,
433 {
434 let next_get = self.next.get;
435 let next_set = self.next.set;
436 let chained_kp = crate::Kp::new(
437 move |mid_value: MidValue| next_get(mid_value).and_then(|v| (next_kp.get)(v)),
438 move |mid_value: MutMid| next_set(mid_value).and_then(|v| (next_kp.set)(v)),
439 );
440 AsyncLockKp::new(self.prev, self.mid, chained_kp)
441 }
442
443 pub fn then_lock<
446 Lock2,
447 Mid2,
448 V2,
449 LockValue2,
450 MidValue2,
451 Value2,
452 MutLock2,
453 MutMid2,
454 MutValue2,
455 G2_1,
456 S2_1,
457 L2,
458 G2_2,
459 S2_2,
460 >(
461 self,
462 lock_kp: crate::lock::LockKp<
463 V,
464 Lock2,
465 Mid2,
466 V2,
467 Value,
468 LockValue2,
469 MidValue2,
470 Value2,
471 MutValue,
472 MutLock2,
473 MutMid2,
474 MutValue2,
475 G2_1,
476 S2_1,
477 L2,
478 G2_2,
479 S2_2,
480 >,
481 ) -> AsyncLockKpThenLockKp<
482 R,
483 V2,
484 Root,
485 Value2,
486 MutRoot,
487 MutValue2,
488 Self,
489 crate::lock::LockKp<
490 V,
491 Lock2,
492 Mid2,
493 V2,
494 Value,
495 LockValue2,
496 MidValue2,
497 Value2,
498 MutValue,
499 MutLock2,
500 MutMid2,
501 MutValue2,
502 G2_1,
503 S2_1,
504 L2,
505 G2_2,
506 S2_2,
507 >,
508 >
509 where
510 V: 'static,
511 V2: 'static,
512 Value: std::borrow::Borrow<V>,
513 Value2: std::borrow::Borrow<V2>,
514 MutValue: std::borrow::BorrowMut<V>,
515 MutValue2: std::borrow::BorrowMut<V2>,
516 LockValue2: std::borrow::Borrow<Lock2>,
517 MidValue2: std::borrow::Borrow<Mid2>,
518 MutLock2: std::borrow::BorrowMut<Lock2>,
519 MutMid2: std::borrow::BorrowMut<Mid2>,
520 G2_1: Fn(Value) -> Option<LockValue2>,
521 S2_1: Fn(MutValue) -> Option<MutLock2>,
522 L2: crate::lock::LockAccess<Lock2, MidValue2> + crate::lock::LockAccess<Lock2, MutMid2>,
523 G2_2: Fn(MidValue2) -> Option<Value2>,
524 S2_2: Fn(MutMid2) -> Option<MutValue2>,
525 {
526 AsyncLockKpThenLockKp {
527 first: self,
528 second: lock_kp,
529 _p: std::marker::PhantomData,
530 }
531 }
532
533 pub fn then_async<
549 Lock2,
550 Mid2,
551 V2,
552 LockValue2,
553 MidValue2,
554 Value2,
555 MutLock2,
556 MutMid2,
557 MutValue2,
558 G2_1,
559 S2_1,
560 L2,
561 G2_2,
562 S2_2,
563 >(
564 self,
565 other: AsyncLockKp<
566 V,
567 Lock2,
568 Mid2,
569 V2,
570 Value,
571 LockValue2,
572 MidValue2,
573 Value2,
574 MutValue,
575 MutLock2,
576 MutMid2,
577 MutValue2,
578 G2_1,
579 S2_1,
580 L2,
581 G2_2,
582 S2_2,
583 >,
584 ) -> ComposedAsyncLockKp<
585 R,
586 V2,
587 Root,
588 Value2,
589 MutRoot,
590 MutValue2,
591 Self,
592 AsyncLockKp<
593 V,
594 Lock2,
595 Mid2,
596 V2,
597 Value,
598 LockValue2,
599 MidValue2,
600 Value2,
601 MutValue,
602 MutLock2,
603 MutMid2,
604 MutValue2,
605 G2_1,
606 S2_1,
607 L2,
608 G2_2,
609 S2_2,
610 >,
611 >
612 where
613 Lock: Clone,
614 Lock2: Clone,
615 V: 'static,
616 V2: 'static,
617 Value: std::borrow::Borrow<V>,
618 LockValue2: std::borrow::Borrow<Lock2>,
619 MidValue2: std::borrow::Borrow<Mid2>,
620 Value2: std::borrow::Borrow<V2>,
621 MutValue: std::borrow::BorrowMut<V>,
622 MutLock2: std::borrow::BorrowMut<Lock2>,
623 MutMid2: std::borrow::BorrowMut<Mid2>,
624 MutValue2: std::borrow::BorrowMut<V2>,
625 G2_1: Fn(Value) -> Option<LockValue2> + Clone,
626 S2_1: Fn(MutValue) -> Option<MutLock2> + Clone,
627 L2: AsyncLockLike<Lock2, MidValue2> + AsyncLockLike<Lock2, MutMid2> + Clone,
628 G2_2: Fn(MidValue2) -> Option<Value2> + Clone,
629 S2_2: Fn(MutMid2) -> Option<MutValue2> + Clone,
630 {
631 ComposedAsyncLockKp {
632 first: self,
633 second: other,
634 _p: std::marker::PhantomData,
635 }
636 }
637}
638
639#[async_trait(?Send)]
641impl<
642 R,
643 Lock,
644 Mid,
645 V,
646 Root,
647 LockValue,
648 MidValue,
649 Value,
650 MutRoot,
651 MutLock,
652 MutMid,
653 MutValue,
654 G1,
655 S1,
656 L,
657 G2,
658 S2,
659> AsyncKeyPathLike<Root, MutRoot>
660 for AsyncLockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
661where
662 Root: std::borrow::Borrow<R>,
663 LockValue: std::borrow::Borrow<Lock>,
664 MidValue: std::borrow::Borrow<Mid>,
665 Value: std::borrow::Borrow<V>,
666 MutRoot: std::borrow::BorrowMut<R>,
667 MutLock: std::borrow::BorrowMut<Lock>,
668 MutMid: std::borrow::BorrowMut<Mid>,
669 MutValue: std::borrow::BorrowMut<V>,
670 G1: Fn(Root) -> Option<LockValue> + Clone,
671 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
672 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
673 G2: Fn(MidValue) -> Option<Value> + Clone,
674 S2: Fn(MutMid) -> Option<MutValue> + Clone,
675 Lock: Clone,
676{
677 type Value = Value;
678 type MutValue = MutValue;
679 async fn get(&self, root: Root) -> Option<Value> {
680 AsyncLockKp::get(self, root).await
681 }
682 async fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
683 AsyncLockKp::get_mut(self, root).await
684 }
685}
686
687#[derive(Clone)]
694pub struct ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
695 pub(crate) first: First,
696 pub(crate) second: Second,
697 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
698}
699
700impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
701 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
702where
703 First: AsyncKeyPathLike<Root, MutRoot>,
704 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
705{
706 pub async fn get(&self, root: Root) -> Option<Value2> {
708 let value = self.first.get(root).await?;
709 self.second.get(value).await
710 }
711
712 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
714 let mut_value = self.first.get_mut(root).await?;
715 self.second.get_mut(mut_value).await
716 }
717
718 pub fn then_async<
720 Lock3,
721 Mid3,
722 V3,
723 LockValue3,
724 MidValue3,
725 Value3,
726 MutLock3,
727 MutMid3,
728 MutValue3,
729 G3_1,
730 S3_1,
731 L3,
732 G3_2,
733 S3_2,
734 >(
735 self,
736 other: AsyncLockKp<
737 V2,
738 Lock3,
739 Mid3,
740 V3,
741 Value2,
742 LockValue3,
743 MidValue3,
744 Value3,
745 MutValue2,
746 MutLock3,
747 MutMid3,
748 MutValue3,
749 G3_1,
750 S3_1,
751 L3,
752 G3_2,
753 S3_2,
754 >,
755 ) -> ComposedAsyncLockKp<
756 R,
757 V3,
758 Root,
759 Value3,
760 MutRoot,
761 MutValue3,
762 Self,
763 AsyncLockKp<
764 V2,
765 Lock3,
766 Mid3,
767 V3,
768 Value2,
769 LockValue3,
770 MidValue3,
771 Value3,
772 MutValue2,
773 MutLock3,
774 MutMid3,
775 MutValue3,
776 G3_1,
777 S3_1,
778 L3,
779 G3_2,
780 S3_2,
781 >,
782 >
783 where
784 V2: 'static,
785 V3: 'static,
786 Value2: std::borrow::Borrow<V2>,
787 Value3: std::borrow::Borrow<V3>,
788 MutValue2: std::borrow::BorrowMut<V2>,
789 MutValue3: std::borrow::BorrowMut<V3>,
790 LockValue3: std::borrow::Borrow<Lock3>,
791 MidValue3: std::borrow::Borrow<Mid3>,
792 MutLock3: std::borrow::BorrowMut<Lock3>,
793 MutMid3: std::borrow::BorrowMut<Mid3>,
794 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
795 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
796 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
797 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
798 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
799 Lock3: Clone,
800 {
801 ComposedAsyncLockKp {
802 first: self,
803 second: other,
804 _p: std::marker::PhantomData,
805 }
806 }
807
808 pub fn then<V3, Value3, MutValue3, G3, S3>(
810 self,
811 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
812 ) -> AsyncKeyPathThenKp<R, V3, Root, Value3, MutRoot, MutValue3, Self, crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>>
813 where
814 V2: 'static,
815 V3: 'static,
816 Value2: std::borrow::Borrow<V2>,
817 Value3: std::borrow::Borrow<V3>,
818 MutValue2: std::borrow::BorrowMut<V2>,
819 MutValue3: std::borrow::BorrowMut<V3>,
820 G3: Fn(Value2) -> Option<Value3> + Clone,
821 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
822 {
823 AsyncKeyPathThenKp {
824 first: self,
825 second: next_kp,
826 _p: std::marker::PhantomData,
827 }
828 }
829
830 pub fn then_lock<
832 Lock3,
833 Mid3,
834 V3,
835 LockValue3,
836 MidValue3,
837 Value3,
838 MutLock3,
839 MutMid3,
840 MutValue3,
841 G3_1,
842 S3_1,
843 L3,
844 G3_2,
845 S3_2,
846 >(
847 self,
848 lock_kp: crate::lock::LockKp<V2, Lock3, Mid3, V3, Value2, LockValue3, MidValue3, Value3, MutValue2, MutLock3, MutMid3, MutValue3, G3_1, S3_1, L3, G3_2, S3_2>,
849 ) -> AsyncLockKpThenLockKp<R, V3, Root, Value3, MutRoot, MutValue3, Self, crate::lock::LockKp<V2, Lock3, Mid3, V3, Value2, LockValue3, MidValue3, Value3, MutValue2, MutLock3, MutMid3, MutValue3, G3_1, S3_1, L3, G3_2, S3_2>>
850 where
851 V2: 'static,
852 V3: 'static,
853 Value2: std::borrow::Borrow<V2>,
854 Value3: std::borrow::Borrow<V3>,
855 MutValue2: std::borrow::BorrowMut<V2>,
856 MutValue3: std::borrow::BorrowMut<V3>,
857 LockValue3: std::borrow::Borrow<Lock3>,
858 MidValue3: std::borrow::Borrow<Mid3>,
859 MutLock3: std::borrow::BorrowMut<Lock3>,
860 MutMid3: std::borrow::BorrowMut<Mid3>,
861 G3_1: Fn(Value2) -> Option<LockValue3>,
862 S3_1: Fn(MutValue2) -> Option<MutLock3>,
863 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
864 G3_2: Fn(MidValue3) -> Option<Value3>,
865 S3_2: Fn(MutMid3) -> Option<MutValue3>,
866 {
867 AsyncLockKpThenLockKp {
868 first: self,
869 second: lock_kp,
870 _p: std::marker::PhantomData,
871 }
872 }
873}
874
875#[derive(Clone)]
877pub struct KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second> {
878 pub(crate) first: First,
879 pub(crate) second: Second,
880 pub(crate) _p: std::marker::PhantomData<(R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2)>,
881}
882
883impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
884 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
885where
886 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
887 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
888{
889 #[inline]
891 pub async fn get(&self, root: Root) -> Option<Value2> {
892 let v = self.first.sync_get(root)?;
893 self.second.get(v).await
894 }
895 #[inline]
897 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
898 let mut_v = self.first.sync_get_mut(root)?;
899 self.second.get_mut(mut_v).await
900 }
901}
902
903#[async_trait(?Send)]
904impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
905 AsyncKeyPathLike<Root, MutRoot> for KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
906where
907 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
908 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
909{
910 type Value = Value2;
911 type MutValue = MutValue2;
912 async fn get(&self, root: Root) -> Option<Value2> {
913 let v = self.first.sync_get(root)?;
914 self.second.get(v).await
915 }
916 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
917 let mut_v = self.first.sync_get_mut(root)?;
918 self.second.get_mut(mut_v).await
919 }
920}
921
922impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
923 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
924where
925 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
926 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
927{
928 pub fn then<V3, Value3, MutValue3, G3, S3>(
930 self,
931 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
932 ) -> AsyncKeyPathThenKp<R, V3, Root, Value3, MutRoot, MutValue3, Self, crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>>
933 where
934 V3: 'static,
935 Value2: std::borrow::Borrow<V2>,
936 MutValue2: std::borrow::BorrowMut<V2>,
937 Value3: std::borrow::Borrow<V3>,
938 MutValue3: std::borrow::BorrowMut<V3>,
939 G3: Fn(Value2) -> Option<Value3> + Clone,
940 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
941 {
942 AsyncKeyPathThenKp {
943 first: self,
944 second: next_kp,
945 _p: std::marker::PhantomData,
946 }
947 }
948}
949
950#[derive(Clone)]
952pub struct AsyncKeyPathThenKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
953 pub(crate) first: First,
954 pub(crate) second: Second,
955 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
956}
957
958impl<R, V2, Root, Value2, MutRoot, MutValue2, First, RKp, G, S>
960 AsyncKeyPathThenKp<R, V2, Root, Value2, MutRoot, MutValue2, First, crate::Kp<RKp, V2, First::Value, Value2, First::MutValue, MutValue2, G, S>>
961where
962 First: AsyncKeyPathLike<Root, MutRoot>,
963 First::Value: std::borrow::Borrow<RKp>,
964 First::MutValue: std::borrow::BorrowMut<RKp>,
965 Value2: std::borrow::Borrow<V2>,
966 MutValue2: std::borrow::BorrowMut<V2>,
967 G: Fn(First::Value) -> Option<Value2>,
968 S: Fn(First::MutValue) -> Option<MutValue2>,
969{
970 #[inline]
972 pub async fn get(&self, root: Root) -> Option<Value2> {
973 let value = self.first.get(root).await?;
974 (self.second.get)(value)
975 }
976 #[inline]
978 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
979 let mut_value = self.first.get_mut(root).await?;
980 (self.second.set)(mut_value)
981 }
982}
983
984#[async_trait(?Send)]
985impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
986 AsyncKeyPathLike<Root, MutRoot> for ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
987where
988 First: AsyncKeyPathLike<Root, MutRoot>,
989 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
990{
991 type Value = Value2;
992 type MutValue = MutValue2;
993 async fn get(&self, root: Root) -> Option<Value2> {
994 ComposedAsyncLockKp::get(self, root).await
995 }
996 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
997 ComposedAsyncLockKp::get_mut(self, root).await
998 }
999}
1000
1001#[derive(Clone)]
1008pub struct AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1009 pub(crate) first: First,
1010 pub(crate) second: Second,
1011 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1012}
1013
1014impl<
1015 R,
1016 V2,
1017 Root,
1018 Value2,
1019 MutRoot,
1020 MutValue2,
1021 Lock,
1022 Mid,
1023 V,
1024 LockValue,
1025 MidValue,
1026 Value,
1027 MutLock,
1028 MutMid,
1029 MutValue,
1030 G1,
1031 S1,
1032 L,
1033 G2,
1034 S2,
1035 Lock2,
1036 Mid2,
1037 LockValue2,
1038 MidValue2,
1039 MutLock2,
1040 MutMid2,
1041 G2_1,
1042 S2_1,
1043 L2,
1044 G2_2,
1045 S2_2,
1046 >
1047 AsyncLockKpThenLockKp<
1048 R,
1049 V2,
1050 Root,
1051 Value2,
1052 MutRoot,
1053 MutValue2,
1054 AsyncLockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>,
1055 crate::lock::LockKp<V, Lock2, Mid2, V2, Value, LockValue2, MidValue2, Value2, MutValue, MutLock2, MutMid2, MutValue2, G2_1, S2_1, L2, G2_2, S2_2>,
1056 >
1057where
1058 Root: std::borrow::Borrow<R>,
1059 LockValue: std::borrow::Borrow<Lock>,
1060 MidValue: std::borrow::Borrow<Mid>,
1061 Value: std::borrow::Borrow<V>,
1062 MutRoot: std::borrow::BorrowMut<R>,
1063 MutLock: std::borrow::BorrowMut<Lock>,
1064 MutMid: std::borrow::BorrowMut<Mid>,
1065 MutValue: std::borrow::BorrowMut<V>,
1066 Value2: std::borrow::Borrow<V2>,
1067 MutValue2: std::borrow::BorrowMut<V2>,
1068 G1: Fn(Root) -> Option<LockValue> + Clone,
1069 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
1070 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
1071 G2: Fn(MidValue) -> Option<Value> + Clone,
1072 S2: Fn(MutMid) -> Option<MutValue> + Clone,
1073 LockValue2: std::borrow::Borrow<Lock2>,
1074 MidValue2: std::borrow::Borrow<Mid2>,
1075 MutLock2: std::borrow::BorrowMut<Lock2>,
1076 MutMid2: std::borrow::BorrowMut<Mid2>,
1077 G2_1: Fn(Value) -> Option<LockValue2>,
1078 S2_1: Fn(MutValue) -> Option<MutLock2>,
1079 L2: crate::lock::LockAccess<Lock2, MidValue2> + crate::lock::LockAccess<Lock2, MutMid2>,
1080 G2_2: Fn(MidValue2) -> Option<Value2>,
1081 S2_2: Fn(MutMid2) -> Option<MutValue2>,
1082 Lock: Clone,
1083 V: Clone,
1084 V2: Clone,
1085{
1086 pub async fn get(&self, root: Root) -> Option<Value2> {
1088 let value = self.first.get(root).await?;
1089 self.second.get(value)
1090 }
1091
1092 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1094 let mut_value = self.first.get_mut(root).await?;
1095 self.second.get_mut(mut_value)
1096 }
1097}
1098
1099impl<
1101 R,
1102 V2,
1103 Root,
1104 Value2,
1105 MutRoot,
1106 MutValue2,
1107 Lock3,
1108 Mid3,
1109 LockValue3,
1110 MidValue3,
1111 MutLock3,
1112 MutMid3,
1113 G3_1,
1114 S3_1,
1115 L3,
1116 G3_2,
1117 S3_2,
1118 First,
1119 Second,
1120 >
1121 AsyncLockKpThenLockKp<
1122 R,
1123 V2,
1124 Root,
1125 Value2,
1126 MutRoot,
1127 MutValue2,
1128 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>,
1129 crate::lock::LockKp<Value2, Lock3, Mid3, V2, Value2, LockValue3, MidValue3, Value2, MutValue2, MutLock3, MutMid3, MutValue2, G3_1, S3_1, L3, G3_2, S3_2>,
1130 >
1131where
1132 First: AsyncKeyPathLike<Root, MutRoot>,
1133 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1134 Value2: std::borrow::Borrow<V2>,
1135 MutValue2: std::borrow::BorrowMut<Value2> + std::borrow::BorrowMut<V2>,
1136 LockValue3: std::borrow::Borrow<Lock3>,
1137 MidValue3: std::borrow::Borrow<Mid3>,
1138 MutLock3: std::borrow::BorrowMut<Lock3>,
1139 MutMid3: std::borrow::BorrowMut<Mid3>,
1140 G3_1: Fn(Value2) -> Option<LockValue3>,
1141 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1142 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
1143 G3_2: Fn(MidValue3) -> Option<Value2>,
1144 S3_2: Fn(MutMid3) -> Option<MutValue2>,
1145 Value2: Clone,
1146 V2: Clone,
1147{
1148 pub async fn get(&self, root: Root) -> Option<Value2> {
1150 let value = self.first.get(root).await?;
1151 self.second.get(value)
1152 }
1153 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1155 let mut_value = self.first.get_mut(root).await?;
1156 self.second.get_mut(mut_value)
1157 }
1158}
1159
1160impl<
1162 R,
1163 V2,
1164 Root,
1165 Value2,
1166 MutRoot,
1167 MutValue2,
1168 Lock3,
1169 Mid3,
1170 LockValue3,
1171 MidValue3,
1172 MutLock3,
1173 MutMid3,
1174 G3_1,
1175 S3_1,
1176 L3,
1177 G3_2,
1178 S3_2,
1179 F,
1180 S,
1181 >
1182 AsyncLockKpThenLockKp<
1183 R,
1184 V2,
1185 Root,
1186 Value2,
1187 MutRoot,
1188 MutValue2,
1189 AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, F, S>,
1190 crate::lock::LockKp<Value2, Lock3, Mid3, V2, Value2, LockValue3, MidValue3, Value2, MutValue2, MutLock3, MutMid3, MutValue2, G3_1, S3_1, L3, G3_2, S3_2>,
1191 >
1192where
1193 F: AsyncKeyPathLike<Root, MutRoot, Value = Value2, MutValue = MutValue2>,
1194 S: SyncKeyPathLike<Value2, Value2, MutValue2, MutValue2>,
1195 Value2: std::borrow::Borrow<V2>,
1196 MutValue2: std::borrow::BorrowMut<Value2> + std::borrow::BorrowMut<V2>,
1197 LockValue3: std::borrow::Borrow<Lock3>,
1198 MidValue3: std::borrow::Borrow<Mid3>,
1199 MutLock3: std::borrow::BorrowMut<Lock3>,
1200 MutMid3: std::borrow::BorrowMut<Mid3>,
1201 G3_1: Fn(Value2) -> Option<LockValue3>,
1202 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1203 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
1204 G3_2: Fn(MidValue3) -> Option<Value2>,
1205 S3_2: Fn(MutMid3) -> Option<MutValue2>,
1206 Value2: Clone,
1207 V2: Clone,
1208{
1209 pub async fn get(&self, root: Root) -> Option<Value2> {
1211 let value = AsyncKeyPathLike::get(&self.first, root).await?;
1212 self.second.get(value)
1213 }
1214 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1216 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
1217 self.second.get_mut(mut_value)
1218 }
1219}
1220
1221#[async_trait(?Send)]
1223impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncKeyPathLike<Root, MutRoot>
1224 for AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1225where
1226 First: AsyncKeyPathLike<Root, MutRoot>,
1227 Second: SyncKeyPathLike<First::Value, Value2, First::MutValue, MutValue2>,
1228{
1229 type Value = Value2;
1230 type MutValue = MutValue2;
1231 async fn get(&self, root: Root) -> Option<Value2> {
1232 let value = AsyncKeyPathLike::get(&self.first, root).await?;
1233 SyncKeyPathLike::sync_get(&self.second, value)
1234 }
1235 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1236 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
1237 SyncKeyPathLike::sync_get_mut(&self.second, mut_value)
1238 }
1239}
1240
1241impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1243where
1244 First: AsyncKeyPathLike<Root, MutRoot>,
1245{
1246 pub fn then_async<
1249 Lock3,
1250 Mid3,
1251 V3,
1252 LockValue3,
1253 MidValue3,
1254 Value3,
1255 MutLock3,
1256 MutMid3,
1257 MutValue3,
1258 G3_1,
1259 S3_1,
1260 L3,
1261 G3_2,
1262 S3_2,
1263 >(
1264 self,
1265 other: AsyncLockKp<
1266 Value2,
1267 Lock3,
1268 Mid3,
1269 V3,
1270 Value2,
1271 LockValue3,
1272 MidValue3,
1273 Value3,
1274 MutValue2,
1275 MutLock3,
1276 MutMid3,
1277 MutValue3,
1278 G3_1,
1279 S3_1,
1280 L3,
1281 G3_2,
1282 S3_2,
1283 >,
1284 ) -> ComposedAsyncLockKp<
1285 Root,
1286 V3,
1287 Root,
1288 Value3,
1289 MutRoot,
1290 MutValue3,
1291 Self,
1292 AsyncLockKp<
1293 Value2,
1294 Lock3,
1295 Mid3,
1296 V3,
1297 Value2,
1298 LockValue3,
1299 MidValue3,
1300 Value3,
1301 MutValue2,
1302 MutLock3,
1303 MutMid3,
1304 MutValue3,
1305 G3_1,
1306 S3_1,
1307 L3,
1308 G3_2,
1309 S3_2,
1310 >,
1311 >
1312 where
1313 V2: 'static,
1314 V3: 'static,
1315 Value2: std::borrow::Borrow<V2>,
1316 Value3: std::borrow::Borrow<V3>,
1317 MutValue2: std::borrow::BorrowMut<V2> + std::borrow::BorrowMut<Value2>,
1318 MutValue3: std::borrow::BorrowMut<V3>,
1319 LockValue3: std::borrow::Borrow<Lock3>,
1320 MidValue3: std::borrow::Borrow<Mid3>,
1321 MutLock3: std::borrow::BorrowMut<Lock3>,
1322 MutMid3: std::borrow::BorrowMut<Mid3>,
1323 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
1324 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
1325 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
1326 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
1327 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
1328 Lock3: Clone,
1329 {
1330 ComposedAsyncLockKp {
1331 first: self,
1332 second: other,
1333 _p: std::marker::PhantomData,
1334 }
1335 }
1336
1337 pub fn then_lock<
1339 Lock3,
1340 Mid3,
1341 V3,
1342 LockValue3,
1343 MidValue3,
1344 Value3,
1345 MutLock3,
1346 MutMid3,
1347 MutValue3,
1348 G3_1,
1349 S3_1,
1350 L3,
1351 G3_2,
1352 S3_2,
1353 >(
1354 self,
1355 lock_kp: crate::lock::LockKp<Value2, Lock3, Mid3, V3, Value2, LockValue3, MidValue3, Value3, MutValue2, MutLock3, MutMid3, MutValue3, G3_1, S3_1, L3, G3_2, S3_2>,
1356 ) -> AsyncLockKpThenLockKp<R, V3, Root, Value3, MutRoot, MutValue3, Self, crate::lock::LockKp<Value2, Lock3, Mid3, V3, Value2, LockValue3, MidValue3, Value3, MutValue2, MutLock3, MutMid3, MutValue3, G3_1, S3_1, L3, G3_2, S3_2>>
1357 where
1358 V3: 'static,
1359 Value2: std::borrow::Borrow<V2>,
1360 Value3: std::borrow::Borrow<V3>,
1361 MutValue2: std::borrow::BorrowMut<Value2>,
1362 MutValue3: std::borrow::BorrowMut<V3>,
1363 LockValue3: std::borrow::Borrow<Lock3>,
1364 MidValue3: std::borrow::Borrow<Mid3>,
1365 MutLock3: std::borrow::BorrowMut<Lock3>,
1366 MutMid3: std::borrow::BorrowMut<Mid3>,
1367 G3_1: Fn(Value2) -> Option<LockValue3>,
1368 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1369 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
1370 G3_2: Fn(MidValue3) -> Option<Value3>,
1371 S3_2: Fn(MutMid3) -> Option<MutValue3>,
1372 {
1373 AsyncLockKpThenLockKp {
1374 first: self,
1375 second: lock_kp,
1376 _p: std::marker::PhantomData,
1377 }
1378 }
1379
1380 pub fn then<V3, Value3, MutValue3, G3, S3>(
1382 self,
1383 next_kp: crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1384 ) -> AsyncKeyPathThenKp<R, V3, Root, Value3, MutRoot, MutValue3, Self, crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>>
1385 where
1386 V3: 'static,
1387 Value2: std::borrow::Borrow<V2>,
1388 Value3: std::borrow::Borrow<V3>,
1389 MutValue2: std::borrow::BorrowMut<Value2>,
1390 MutValue3: std::borrow::BorrowMut<V3>,
1391 G3: Fn(Value2) -> Option<Value3> + Clone,
1392 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1393 {
1394 AsyncKeyPathThenKp {
1395 first: self,
1396 second: next_kp,
1397 _p: std::marker::PhantomData,
1398 }
1399 }
1400}
1401
1402#[cfg(feature = "tokio")]
1407#[derive(Clone)] pub struct TokioMutexAccess<T> {
1415 _phantom: std::marker::PhantomData<T>,
1416}
1417
1418#[cfg(feature = "tokio")]
1419impl<T> TokioMutexAccess<T> {
1420 pub fn new() -> Self {
1421 Self {
1422 _phantom: std::marker::PhantomData,
1423 }
1424 }
1425}
1426
1427#[cfg(feature = "tokio")]
1428impl<T> Default for TokioMutexAccess<T> {
1429 fn default() -> Self {
1430 Self::new()
1431 }
1432}
1433
1434#[cfg(feature = "tokio")]
1436#[async_trait]
1437impl<'a, T: 'static + Send + Sync> AsyncLockLike<Arc<tokio::sync::Mutex<T>>, &'a T>
1438 for TokioMutexAccess<T>
1439{
1440 #[inline]
1441 async fn lock_read(&self, lock: &Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
1442 let guard = lock.lock().await;
1444 let ptr = &*guard as *const T;
1445 unsafe { Some(&*ptr) }
1446 }
1447
1448 #[inline]
1449 async fn lock_write(&self, lock: &mut Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
1450 let guard = lock.lock().await;
1451 let ptr = &*guard as *const T;
1452 unsafe { Some(&*ptr) }
1453 }
1454}
1455
1456#[cfg(feature = "tokio")]
1458#[async_trait]
1459impl<'a, T: 'static + Send + Sync> AsyncLockLike<Arc<tokio::sync::Mutex<T>>, &'a mut T>
1460 for TokioMutexAccess<T>
1461{
1462 #[inline]
1463 async fn lock_read(&self, lock: &Arc<tokio::sync::Mutex<T>>) -> Option<&'a mut T> {
1464 let mut guard = lock.lock().await;
1466 let ptr = &mut *guard as *mut T;
1467 unsafe { Some(&mut *ptr) }
1468 }
1469
1470 #[inline]
1471 async fn lock_write(&self, lock: &mut Arc<tokio::sync::Mutex<T>>) -> Option<&'a mut T> {
1472 let mut guard = lock.lock().await;
1473 let ptr = &mut *guard as *mut T;
1474 unsafe { Some(&mut *ptr) }
1475 }
1476}
1477
1478#[cfg(feature = "tokio")]
1483pub struct TokioRwLockAccess<T> {
1491 _phantom: std::marker::PhantomData<T>,
1492}
1493
1494#[cfg(feature = "tokio")]
1495impl<T> TokioRwLockAccess<T> {
1496 pub fn new() -> Self {
1497 Self {
1498 _phantom: std::marker::PhantomData,
1499 }
1500 }
1501}
1502
1503#[cfg(feature = "tokio")]
1504impl<T> Default for TokioRwLockAccess<T> {
1505 fn default() -> Self {
1506 Self::new()
1507 }
1508}
1509
1510#[cfg(feature = "tokio")]
1511impl<T> Clone for TokioRwLockAccess<T> {
1512 fn clone(&self) -> Self {
1513 Self {
1514 _phantom: self._phantom,
1515 }
1516 }
1517}
1518
1519#[cfg(feature = "tokio")]
1521#[async_trait]
1522impl<'a, T: 'static + Send + Sync> AsyncLockLike<Arc<tokio::sync::RwLock<T>>, &'a T>
1523 for TokioRwLockAccess<T>
1524{
1525 async fn lock_read(&self, lock: &Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
1526 let guard = lock.read().await;
1528 let ptr = &*guard as *const T;
1529 unsafe { Some(&*ptr) }
1530 }
1531
1532 async fn lock_write(&self, lock: &mut Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
1533 let guard = lock.read().await;
1535 let ptr = &*guard as *const T;
1536 unsafe { Some(&*ptr) }
1537 }
1538}
1539
1540#[cfg(feature = "tokio")]
1542#[async_trait]
1543impl<'a, T: 'static + Send + Sync> AsyncLockLike<Arc<tokio::sync::RwLock<T>>, &'a mut T>
1544 for TokioRwLockAccess<T>
1545{
1546 async fn lock_read(&self, lock: &Arc<tokio::sync::RwLock<T>>) -> Option<&'a mut T> {
1547 let mut guard = lock.write().await;
1549 let ptr = &mut *guard as *mut T;
1550 unsafe { Some(&mut *ptr) }
1551 }
1552
1553 async fn lock_write(&self, lock: &mut Arc<tokio::sync::RwLock<T>>) -> Option<&'a mut T> {
1554 let mut guard = lock.write().await;
1556 let ptr = &mut *guard as *mut T;
1557 unsafe { Some(&mut *ptr) }
1558 }
1559}
1560
1561#[cfg(all(test, feature = "tokio"))]
1566mod tests {
1567 use super::*;
1568 use crate::KpType;
1569
1570 #[tokio::test]
1571 async fn test_async_lock_kp_tokio_mutex_basic() {
1572 use tokio::sync::Mutex;
1573
1574 #[derive(Clone)]
1575 struct Root {
1576 data: Arc<Mutex<String>>,
1577 }
1578
1579 let root = Root {
1580 data: Arc::new(Mutex::new("hello".to_string())),
1581 };
1582
1583 let lock_kp = {
1585 let prev: KpType<Root, Arc<Mutex<String>>> =
1586 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1587 let next: KpType<String, String> =
1588 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
1589 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1590 };
1591
1592 let value = lock_kp.get(&root).await;
1594 assert!(value.is_some());
1595 assert_eq!(value.unwrap(), &"hello".to_string());
1596 }
1597
1598 #[tokio::test]
1599 async fn test_async_lock_kp_tokio_rwlock_basic() {
1600 use tokio::sync::RwLock;
1601
1602 #[derive(Clone)]
1603 struct Root {
1604 data: Arc<RwLock<Vec<i32>>>,
1605 }
1606
1607 let root = Root {
1608 data: Arc::new(RwLock::new(vec![1, 2, 3, 4, 5])),
1609 };
1610
1611 let lock_kp = {
1613 let prev: KpType<Root, Arc<RwLock<Vec<i32>>>> =
1614 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1615 let next: KpType<Vec<i32>, Vec<i32>> =
1616 Kp::new(|v: &Vec<i32>| Some(v), |v: &mut Vec<i32>| Some(v));
1617 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
1618 };
1619
1620 let value = lock_kp.get(&root).await;
1622 assert!(value.is_some());
1623 assert_eq!(value.unwrap().len(), 5);
1624 }
1625
1626 #[tokio::test]
1627 async fn test_async_lock_kp_concurrent_reads() {
1628 use tokio::sync::RwLock;
1629
1630 #[derive(Clone)]
1631 struct Root {
1632 data: Arc<RwLock<i32>>,
1633 }
1634
1635 let root = Root {
1636 data: Arc::new(RwLock::new(42)),
1637 };
1638
1639 let lock_kp = {
1641 let prev: KpType<Root, Arc<RwLock<i32>>> =
1642 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1643 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
1644 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
1645 };
1646
1647 let mut handles = vec![];
1649 for _ in 0..10 {
1650 let root_clone = root.clone();
1651
1652 let lock_kp_for_task = {
1654 let prev: KpType<Root, Arc<RwLock<i32>>> =
1655 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1656 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
1657 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
1658 };
1659
1660 let handle = tokio::spawn(async move { lock_kp_for_task.get(&root_clone).await });
1661 handles.push(handle);
1662 }
1663
1664 for handle in handles {
1666 let result = handle.await.unwrap();
1667 assert_eq!(result, Some(&42));
1668 }
1669
1670 let value = lock_kp.get(&root).await;
1672 assert_eq!(value, Some(&42));
1673 }
1674
1675 #[tokio::test]
1676 async fn test_async_lock_kp_panic_on_clone_proof() {
1677 use tokio::sync::Mutex;
1678
1679 struct PanicOnClone {
1681 data: String,
1682 }
1683
1684 impl Clone for PanicOnClone {
1685 fn clone(&self) -> Self {
1686 panic!("❌ ASYNC DEEP CLONE DETECTED! PanicOnClone was cloned!");
1687 }
1688 }
1689
1690 #[derive(Clone)]
1691 struct Root {
1692 level1: Arc<Mutex<Level1>>,
1693 }
1694
1695 struct Level1 {
1696 panic_data: PanicOnClone,
1697 value: i32,
1698 }
1699
1700 impl Clone for Level1 {
1701 fn clone(&self) -> Self {
1702 panic!("❌ Level1 was deeply cloned in async context!");
1703 }
1704 }
1705
1706 let root = Root {
1708 level1: Arc::new(Mutex::new(Level1 {
1709 panic_data: PanicOnClone {
1710 data: "test".to_string(),
1711 },
1712 value: 123,
1713 })),
1714 };
1715
1716 let lock_kp = {
1718 let prev: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
1719 |r: &Root| Some(&r.level1),
1720 |r: &mut Root| Some(&mut r.level1),
1721 );
1722 let next: KpType<Level1, i32> = Kp::new(
1723 |l: &Level1| Some(&l.value),
1724 |l: &mut Level1| Some(&mut l.value),
1725 );
1726 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1727 };
1728
1729 let value = lock_kp.get(&root).await;
1731
1732 assert_eq!(value, Some(&123));
1734 }
1735
1736 #[tokio::test]
1737 async fn test_async_lock_kp_structure() {
1738 use tokio::sync::Mutex;
1739
1740 #[derive(Clone)]
1741 struct Root {
1742 data: Arc<Mutex<String>>,
1743 }
1744
1745 let lock_kp = {
1746 let prev: KpType<Root, Arc<Mutex<String>>> =
1747 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1748 let next: KpType<String, String> =
1749 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
1750 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1751 };
1752
1753 let _ = &lock_kp.prev;
1755 let _ = &lock_kp.mid;
1756 let _ = &lock_kp.next;
1757 }
1758
1759 #[tokio::test]
1760 async fn test_async_kp_then() {
1761 use tokio::sync::Mutex;
1762
1763 #[derive(Clone)]
1764 struct Root {
1765 data: Arc<Mutex<Inner>>,
1766 }
1767
1768 #[derive(Clone)]
1769 struct Inner {
1770 value: i32,
1771 }
1772
1773 let root = Root {
1774 data: Arc::new(Mutex::new(Inner { value: 42 })),
1775 };
1776
1777 let async_kp = {
1779 let prev: KpType<Root, Arc<Mutex<Inner>>> =
1780 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1781 let next: KpType<Inner, Inner> = Kp::new(|i: &Inner| Some(i), |i: &mut Inner| Some(i));
1782 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1783 };
1784
1785 let value_kp: KpType<Inner, i32> = Kp::new(
1787 |i: &Inner| Some(&i.value),
1788 |i: &mut Inner| Some(&mut i.value),
1789 );
1790
1791 let chained = async_kp.then(value_kp);
1792 let result = chained.get(&root).await;
1793 assert_eq!(result, Some(&42));
1794 }
1795
1796 #[tokio::test]
1797 async fn test_async_kp_later_then() {
1798 use tokio::sync::Mutex;
1799
1800 #[derive(Clone)]
1801 struct Root {
1802 lock1: Arc<Mutex<Container>>,
1803 }
1804
1805 #[derive(Clone)]
1806 struct Container {
1807 lock2: Arc<Mutex<i32>>,
1808 }
1809
1810 let root = Root {
1811 lock1: Arc::new(Mutex::new(Container {
1812 lock2: Arc::new(Mutex::new(999)),
1813 })),
1814 };
1815
1816 let async_kp1 = {
1818 let prev: KpType<Root, Arc<Mutex<Container>>> =
1819 Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
1820 let next: KpType<Container, Container> =
1821 Kp::new(|c: &Container| Some(c), |c: &mut Container| Some(c));
1822 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1823 };
1824
1825 let async_kp2 = {
1827 let prev: KpType<Container, Arc<Mutex<i32>>> = Kp::new(
1828 |c: &Container| Some(&c.lock2),
1829 |c: &mut Container| Some(&mut c.lock2),
1830 );
1831 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
1832 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1833 };
1834
1835 let chained = async_kp1.then_async(async_kp2);
1837 let result = chained.get(&root).await;
1838 assert_eq!(result, Some(&999));
1839 }
1840
1841 #[tokio::test]
1842 async fn test_async_kp_then_async_three_levels() {
1843 use tokio::sync::Mutex;
1844
1845 #[derive(Clone)]
1846 struct Root {
1847 a: Arc<Mutex<Level1>>,
1848 }
1849 #[derive(Clone)]
1850 struct Level1 {
1851 b: Arc<Mutex<Level2>>,
1852 }
1853 #[derive(Clone)]
1854 struct Level2 {
1855 c: Arc<Mutex<i32>>,
1856 }
1857
1858 let root = Root {
1859 a: Arc::new(Mutex::new(Level1 {
1860 b: Arc::new(Mutex::new(Level2 {
1861 c: Arc::new(Mutex::new(42)),
1862 })),
1863 })),
1864 };
1865
1866 let kp1 = {
1867 let prev: KpType<Root, Arc<Mutex<Level1>>> =
1868 Kp::new(|r: &Root| Some(&r.a), |r: &mut Root| Some(&mut r.a));
1869 let next: KpType<Level1, Level1> =
1870 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
1871 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1872 };
1873 let kp2 = {
1874 let prev: KpType<Level1, Arc<Mutex<Level2>>> =
1875 Kp::new(|l: &Level1| Some(&l.b), |l: &mut Level1| Some(&mut l.b));
1876 let next: KpType<Level2, Level2> =
1877 Kp::new(|l: &Level2| Some(l), |l: &mut Level2| Some(l));
1878 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1879 };
1880 let kp3 = {
1881 let prev: KpType<Level2, Arc<Mutex<i32>>> =
1882 Kp::new(|l: &Level2| Some(&l.c), |l: &mut Level2| Some(&mut l.c));
1883 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
1884 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1885 };
1886
1887 let chained = kp1.then_async(kp2).then_async(kp3);
1888 let result = chained.get(&root).await;
1889 assert_eq!(result, Some(&42));
1890 }
1891}