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>;
99
100 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue>;
131}
132
133impl<R, V, Root, Value, MutRoot, MutValue, G, S> SyncKeyPathLike<Root, Value, MutRoot, MutValue>
134 for crate::Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
135where
136 Root: std::borrow::Borrow<R>,
137 Value: std::borrow::Borrow<V>,
138 MutRoot: std::borrow::BorrowMut<R>,
139 MutValue: std::borrow::BorrowMut<V>,
140 G: Fn(Root) -> Option<Value>,
141 S: Fn(MutRoot) -> Option<MutValue>,
142{
143 fn sync_get(&self, root: Root) -> Option<Value> {
144 self.get(root)
145 }
146 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue> {
147 self.get_mut(root)
148 }
149}
150
151impl<
152 R,
153 Lock,
154 Mid,
155 V,
156 Root,
157 LockValue,
158 MidValue,
159 Value,
160 MutRoot,
161 MutLock,
162 MutMid,
163 MutValue,
164 G1,
165 S1,
166 L,
167 G2,
168 S2,
169 >
170 SyncKeyPathLike<Root, Value, MutRoot, MutValue> for crate::lock::LockKp<
171 R,
172 Lock,
173 Mid,
174 V,
175 Root,
176 LockValue,
177 MidValue,
178 Value,
179 MutRoot,
180 MutLock,
181 MutMid,
182 MutValue,
183 G1,
184 S1,
185 L,
186 G2,
187 S2,
188 >
189where
190 Root: std::borrow::Borrow<R>,
191 LockValue: std::borrow::Borrow<Lock>,
192 MidValue: std::borrow::Borrow<Mid>,
193 Value: std::borrow::Borrow<V>,
194 MutRoot: std::borrow::BorrowMut<R>,
195 MutLock: std::borrow::BorrowMut<Lock>,
196 MutMid: std::borrow::BorrowMut<Mid>,
197 MutValue: std::borrow::BorrowMut<V>,
198 G1: Fn(Root) -> Option<LockValue>,
199 S1: Fn(MutRoot) -> Option<MutLock>,
200 L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
201 G2: Fn(MidValue) -> Option<Value>,
202 S2: Fn(MutMid) -> Option<MutValue>,
203 V: Clone,
204{
205 #[inline]
206 fn sync_get(&self, root: Root) -> Option<Value> {
207 self.get(root)
208 }
209 #[inline]
210 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue> {
211 self.get_mut(root)
212 }
213}
214
215#[async_trait(?Send)]
226pub trait AsyncKeyPathLike<Root, MutRoot> {
227 type Value;
229 type MutValue;
231 async fn get(&self, root: Root) -> Option<Self::Value>;
233 async fn get_mut(&self, root: MutRoot) -> Option<Self::MutValue>;
235}
236
237#[derive(Clone)] pub struct AsyncLockKp<
262 R,
263 Lock,
264 Mid,
265 V,
266 Root,
267 LockValue,
268 MidValue,
269 Value,
270 MutRoot,
271 MutLock,
272 MutMid,
273 MutValue,
274 G1,
275 S1,
276 L,
277 G2,
278 S2,
279> where
280 Root: std::borrow::Borrow<R>,
281 LockValue: std::borrow::Borrow<Lock>,
282 MidValue: std::borrow::Borrow<Mid>,
283 Value: std::borrow::Borrow<V>,
284 MutRoot: std::borrow::BorrowMut<R>,
285 MutLock: std::borrow::BorrowMut<Lock>,
286 MutMid: std::borrow::BorrowMut<Mid>,
287 MutValue: std::borrow::BorrowMut<V>,
288 G1: Fn(Root) -> Option<LockValue> + Clone,
289 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
290 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
291 G2: Fn(MidValue) -> Option<Value> + Clone,
292 S2: Fn(MutMid) -> Option<MutValue> + Clone,
293{
294 pub(crate) prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
296
297 pub(crate) mid: L,
299
300 pub(crate) next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
302}
303
304impl<
305 R,
306 Lock,
307 Mid,
308 V,
309 Root,
310 LockValue,
311 MidValue,
312 Value,
313 MutRoot,
314 MutLock,
315 MutMid,
316 MutValue,
317 G1,
318 S1,
319 L,
320 G2,
321 S2,
322>
323 AsyncLockKp<
324 R,
325 Lock,
326 Mid,
327 V,
328 Root,
329 LockValue,
330 MidValue,
331 Value,
332 MutRoot,
333 MutLock,
334 MutMid,
335 MutValue,
336 G1,
337 S1,
338 L,
339 G2,
340 S2,
341 >
342where
343 Root: std::borrow::Borrow<R>,
344 LockValue: std::borrow::Borrow<Lock>,
345 MidValue: std::borrow::Borrow<Mid>,
346 Value: std::borrow::Borrow<V>,
347 MutRoot: std::borrow::BorrowMut<R>,
348 MutLock: std::borrow::BorrowMut<Lock>,
349 MutMid: std::borrow::BorrowMut<Mid>,
350 MutValue: std::borrow::BorrowMut<V>,
351 G1: Fn(Root) -> Option<LockValue> + Clone,
352 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
353 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
354 G2: Fn(MidValue) -> Option<Value> + Clone,
355 S2: Fn(MutMid) -> Option<MutValue> + Clone,
356{
357 pub fn new(
359 prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
360 mid: L,
361 next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
362 ) -> Self {
363 Self { prev, mid, next }
364 }
365
366 #[inline]
380 pub async fn get(&self, root: Root) -> Option<Value>
381 where
382 Lock: Clone,
383 {
384 let lock_value = (self.prev.get)(root)?;
387 let lock: &Lock = lock_value.borrow();
388 let lock_clone = lock.clone(); let mid_value = self.mid.lock_read(&lock_clone).await?;
392
393 (self.next.get)(mid_value)
395 }
396
397 #[inline]
399 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue>
400 where
401 Lock: Clone,
402 {
403 let mut lock_value = (self.prev.set)(root)?;
405 let lock: &mut Lock = lock_value.borrow_mut();
406 let mut lock_clone = lock.clone(); let mid_value = self.mid.lock_write(&mut lock_clone).await?;
410
411 (self.next.set)(mid_value)
413 }
414
415 pub async fn set<F>(&self, root: Root, updater: F) -> Result<(), String>
422 where
423 Lock: Clone,
424 F: FnOnce(&mut V),
425 {
426 let lock_value = (self.prev.get)(root).ok_or("Failed to get lock from root")?;
428 let lock: &Lock = lock_value.borrow();
429 let lock_clone = lock.clone(); let mut mid_value = self
433 .mid
434 .lock_read(&lock_clone)
435 .await
436 .ok_or("Failed to lock")?;
437
438 let mut mut_value = (self.next.set)(mid_value).ok_or("Failed to navigate to value")?;
440 let v: &mut V = mut_value.borrow_mut();
441
442 updater(v);
444
445 Ok(())
446 }
447
448 pub fn then<V2, Value2, MutValue2, G3, S3>(
464 self,
465 next_kp: crate::Kp<V, V2, Value, Value2, MutValue, MutValue2, G3, S3>,
466 ) -> AsyncLockKp<
467 R,
468 Lock,
469 Mid,
470 V2,
471 Root,
472 LockValue,
473 MidValue,
474 Value2,
475 MutRoot,
476 MutLock,
477 MutMid,
478 MutValue2,
479 G1,
480 S1,
481 L,
482 impl Fn(MidValue) -> Option<Value2> + Clone + use<G1, G2, G3, L, Lock, LockValue, Mid, MidValue, MutLock, MutMid, MutRoot, MutValue, MutValue2, R, Root, S1, S2, S3, Value, Value2, V, V2>,
483 impl Fn(MutMid) -> Option<MutValue2> + Clone + use<G1, G2, G3, L, Lock, LockValue, Mid, MidValue, MutLock, MutMid, MutRoot, MutValue, MutValue2, R, Root, S1, S2, S3, Value, Value2, V, V2>,
484 >
485 where
486 V: 'static,
487 V2: 'static,
488 Value: std::borrow::Borrow<V>,
489 Value2: std::borrow::Borrow<V2>,
490 MutValue: std::borrow::BorrowMut<V>,
491 MutValue2: std::borrow::BorrowMut<V2>,
492 G3: Fn(Value) -> Option<Value2> + Clone,
493 S3: Fn(MutValue) -> Option<MutValue2> + Clone,
494 {
495 let next_get = self.next.get;
496 let next_set = self.next.set;
497 let chained_kp = crate::Kp::new(
498 move |mid_value: MidValue| next_get(mid_value).and_then(|v| (next_kp.get)(v)),
499 move |mid_value: MutMid| next_set(mid_value).and_then(|v| (next_kp.set)(v)),
500 );
501 AsyncLockKp::new(self.prev, self.mid, chained_kp)
502 }
503
504 pub fn then_lock<
507 Lock2,
508 Mid2,
509 V2,
510 LockValue2,
511 MidValue2,
512 Value2,
513 MutLock2,
514 MutMid2,
515 MutValue2,
516 G2_1,
517 S2_1,
518 L2,
519 G2_2,
520 S2_2,
521 >(
522 self,
523 lock_kp: crate::lock::LockKp<
524 V,
525 Lock2,
526 Mid2,
527 V2,
528 Value,
529 LockValue2,
530 MidValue2,
531 Value2,
532 MutValue,
533 MutLock2,
534 MutMid2,
535 MutValue2,
536 G2_1,
537 S2_1,
538 L2,
539 G2_2,
540 S2_2,
541 >,
542 ) -> AsyncLockKpThenLockKp<
543 R,
544 V2,
545 Root,
546 Value2,
547 MutRoot,
548 MutValue2,
549 Self,
550 crate::lock::LockKp<
551 V,
552 Lock2,
553 Mid2,
554 V2,
555 Value,
556 LockValue2,
557 MidValue2,
558 Value2,
559 MutValue,
560 MutLock2,
561 MutMid2,
562 MutValue2,
563 G2_1,
564 S2_1,
565 L2,
566 G2_2,
567 S2_2,
568 >,
569 >
570 where
571 V: 'static,
572 V2: 'static,
573 Value: std::borrow::Borrow<V>,
574 Value2: std::borrow::Borrow<V2>,
575 MutValue: std::borrow::BorrowMut<V>,
576 MutValue2: std::borrow::BorrowMut<V2>,
577 LockValue2: std::borrow::Borrow<Lock2>,
578 MidValue2: std::borrow::Borrow<Mid2>,
579 MutLock2: std::borrow::BorrowMut<Lock2>,
580 MutMid2: std::borrow::BorrowMut<Mid2>,
581 G2_1: Fn(Value) -> Option<LockValue2>,
582 S2_1: Fn(MutValue) -> Option<MutLock2>,
583 L2: crate::lock::LockAccess<Lock2, MidValue2> + crate::lock::LockAccess<Lock2, MutMid2>,
584 G2_2: Fn(MidValue2) -> Option<Value2>,
585 S2_2: Fn(MutMid2) -> Option<MutValue2>,
586 {
587 AsyncLockKpThenLockKp {
588 first: self,
589 second: lock_kp,
590 _p: std::marker::PhantomData,
591 }
592 }
593
594 pub fn then_async<
610 Lock2,
611 Mid2,
612 V2,
613 LockValue2,
614 MidValue2,
615 Value2,
616 MutLock2,
617 MutMid2,
618 MutValue2,
619 G2_1,
620 S2_1,
621 L2,
622 G2_2,
623 S2_2,
624 >(
625 self,
626 other: AsyncLockKp<
627 V,
628 Lock2,
629 Mid2,
630 V2,
631 Value,
632 LockValue2,
633 MidValue2,
634 Value2,
635 MutValue,
636 MutLock2,
637 MutMid2,
638 MutValue2,
639 G2_1,
640 S2_1,
641 L2,
642 G2_2,
643 S2_2,
644 >,
645 ) -> ComposedAsyncLockKp<
646 R,
647 V2,
648 Root,
649 Value2,
650 MutRoot,
651 MutValue2,
652 Self,
653 AsyncLockKp<
654 V,
655 Lock2,
656 Mid2,
657 V2,
658 Value,
659 LockValue2,
660 MidValue2,
661 Value2,
662 MutValue,
663 MutLock2,
664 MutMid2,
665 MutValue2,
666 G2_1,
667 S2_1,
668 L2,
669 G2_2,
670 S2_2,
671 >,
672 >
673 where
674 Lock: Clone,
675 Lock2: Clone,
676 V: 'static,
677 V2: 'static,
678 Value: std::borrow::Borrow<V>,
679 LockValue2: std::borrow::Borrow<Lock2>,
680 MidValue2: std::borrow::Borrow<Mid2>,
681 Value2: std::borrow::Borrow<V2>,
682 MutValue: std::borrow::BorrowMut<V>,
683 MutLock2: std::borrow::BorrowMut<Lock2>,
684 MutMid2: std::borrow::BorrowMut<Mid2>,
685 MutValue2: std::borrow::BorrowMut<V2>,
686 G2_1: Fn(Value) -> Option<LockValue2> + Clone,
687 S2_1: Fn(MutValue) -> Option<MutLock2> + Clone,
688 L2: AsyncLockLike<Lock2, MidValue2> + AsyncLockLike<Lock2, MutMid2> + Clone,
689 G2_2: Fn(MidValue2) -> Option<Value2> + Clone,
690 S2_2: Fn(MutMid2) -> Option<MutValue2> + Clone,
691 {
692 ComposedAsyncLockKp {
693 first: self,
694 second: other,
695 _p: std::marker::PhantomData,
696 }
697 }
698}
699
700#[async_trait(?Send)]
702impl<
703 R,
704 Lock,
705 Mid,
706 V,
707 Root,
708 LockValue,
709 MidValue,
710 Value,
711 MutRoot,
712 MutLock,
713 MutMid,
714 MutValue,
715 G1,
716 S1,
717 L,
718 G2,
719 S2,
720> AsyncKeyPathLike<Root, MutRoot>
721 for AsyncLockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
722where
723 Root: std::borrow::Borrow<R>,
724 LockValue: std::borrow::Borrow<Lock>,
725 MidValue: std::borrow::Borrow<Mid>,
726 Value: std::borrow::Borrow<V>,
727 MutRoot: std::borrow::BorrowMut<R>,
728 MutLock: std::borrow::BorrowMut<Lock>,
729 MutMid: std::borrow::BorrowMut<Mid>,
730 MutValue: std::borrow::BorrowMut<V>,
731 G1: Fn(Root) -> Option<LockValue> + Clone,
732 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
733 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
734 G2: Fn(MidValue) -> Option<Value> + Clone,
735 S2: Fn(MutMid) -> Option<MutValue> + Clone,
736 Lock: Clone,
737{
738 type Value = Value;
739 type MutValue = MutValue;
740 async fn get(&self, root: Root) -> Option<Value> {
741 AsyncLockKp::get(self, root).await
742 }
743 async fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
744 AsyncLockKp::get_mut(self, root).await
745 }
746}
747
748#[derive(Clone)]
755pub struct ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
756 pub(crate) first: First,
757 pub(crate) second: Second,
758 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
759}
760
761impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
762 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
763where
764 First: AsyncKeyPathLike<Root, MutRoot>,
765 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
766{
767 pub async fn get(&self, root: Root) -> Option<Value2> {
769 let value = self.first.get(root).await?;
770 self.second.get(value).await
771 }
772
773 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
775 let mut_value = self.first.get_mut(root).await?;
776 self.second.get_mut(mut_value).await
777 }
778
779 pub fn then_async<
781 Lock3,
782 Mid3,
783 V3,
784 LockValue3,
785 MidValue3,
786 Value3,
787 MutLock3,
788 MutMid3,
789 MutValue3,
790 G3_1,
791 S3_1,
792 L3,
793 G3_2,
794 S3_2,
795 >(
796 self,
797 other: AsyncLockKp<
798 V2,
799 Lock3,
800 Mid3,
801 V3,
802 Value2,
803 LockValue3,
804 MidValue3,
805 Value3,
806 MutValue2,
807 MutLock3,
808 MutMid3,
809 MutValue3,
810 G3_1,
811 S3_1,
812 L3,
813 G3_2,
814 S3_2,
815 >,
816 ) -> ComposedAsyncLockKp<
817 R,
818 V3,
819 Root,
820 Value3,
821 MutRoot,
822 MutValue3,
823 Self,
824 AsyncLockKp<
825 V2,
826 Lock3,
827 Mid3,
828 V3,
829 Value2,
830 LockValue3,
831 MidValue3,
832 Value3,
833 MutValue2,
834 MutLock3,
835 MutMid3,
836 MutValue3,
837 G3_1,
838 S3_1,
839 L3,
840 G3_2,
841 S3_2,
842 >,
843 >
844 where
845 V2: 'static,
846 V3: 'static,
847 Value2: std::borrow::Borrow<V2>,
848 Value3: std::borrow::Borrow<V3>,
849 MutValue2: std::borrow::BorrowMut<V2>,
850 MutValue3: std::borrow::BorrowMut<V3>,
851 LockValue3: std::borrow::Borrow<Lock3>,
852 MidValue3: std::borrow::Borrow<Mid3>,
853 MutLock3: std::borrow::BorrowMut<Lock3>,
854 MutMid3: std::borrow::BorrowMut<Mid3>,
855 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
856 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
857 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
858 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
859 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
860 Lock3: Clone,
861 {
862 ComposedAsyncLockKp {
863 first: self,
864 second: other,
865 _p: std::marker::PhantomData,
866 }
867 }
868
869 pub fn then<V3, Value3, MutValue3, G3, S3>(
871 self,
872 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
873 ) -> AsyncKeyPathThenKp<R, V3, Root, Value3, MutRoot, MutValue3, Self, crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>>
874 where
875 V2: 'static,
876 V3: 'static,
877 Value2: std::borrow::Borrow<V2>,
878 Value3: std::borrow::Borrow<V3>,
879 MutValue2: std::borrow::BorrowMut<V2>,
880 MutValue3: std::borrow::BorrowMut<V3>,
881 G3: Fn(Value2) -> Option<Value3> + Clone,
882 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
883 {
884 AsyncKeyPathThenKp {
885 first: self,
886 second: next_kp,
887 _p: std::marker::PhantomData,
888 }
889 }
890
891 pub fn then_lock<
893 Lock3,
894 Mid3,
895 V3,
896 LockValue3,
897 MidValue3,
898 Value3,
899 MutLock3,
900 MutMid3,
901 MutValue3,
902 G3_1,
903 S3_1,
904 L3,
905 G3_2,
906 S3_2,
907 >(
908 self,
909 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>,
910 ) -> 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>>
911 where
912 V2: 'static,
913 V3: 'static,
914 Value2: std::borrow::Borrow<V2>,
915 Value3: std::borrow::Borrow<V3>,
916 MutValue2: std::borrow::BorrowMut<V2>,
917 MutValue3: std::borrow::BorrowMut<V3>,
918 LockValue3: std::borrow::Borrow<Lock3>,
919 MidValue3: std::borrow::Borrow<Mid3>,
920 MutLock3: std::borrow::BorrowMut<Lock3>,
921 MutMid3: std::borrow::BorrowMut<Mid3>,
922 G3_1: Fn(Value2) -> Option<LockValue3>,
923 S3_1: Fn(MutValue2) -> Option<MutLock3>,
924 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
925 G3_2: Fn(MidValue3) -> Option<Value3>,
926 S3_2: Fn(MutMid3) -> Option<MutValue3>,
927 {
928 AsyncLockKpThenLockKp {
929 first: self,
930 second: lock_kp,
931 _p: std::marker::PhantomData,
932 }
933 }
934}
935
936#[derive(Clone)]
938pub struct KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second> {
939 pub(crate) first: First,
940 pub(crate) second: Second,
941 pub(crate) _p: std::marker::PhantomData<(R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2)>,
942}
943
944impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
945 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
946where
947 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
948 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
949{
950 #[inline]
952 pub async fn get(&self, root: Root) -> Option<Value2> {
953 let v = self.first.sync_get(root)?;
954 self.second.get(v).await
955 }
956 #[inline]
958 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
959 let mut_v = self.first.sync_get_mut(root)?;
960 self.second.get_mut(mut_v).await
961 }
962}
963
964#[async_trait(?Send)]
965impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
966 AsyncKeyPathLike<Root, MutRoot> for KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
967where
968 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
969 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
970{
971 type Value = Value2;
972 type MutValue = MutValue2;
973 async fn get(&self, root: Root) -> Option<Value2> {
974 let v = self.first.sync_get(root)?;
975 self.second.get(v).await
976 }
977 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
978 let mut_v = self.first.sync_get_mut(root)?;
979 self.second.get_mut(mut_v).await
980 }
981}
982
983impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
984 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
985where
986 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
987 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
988{
989 pub fn then<V3, Value3, MutValue3, G3, S3>(
991 self,
992 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
993 ) -> AsyncKeyPathThenKp<R, V3, Root, Value3, MutRoot, MutValue3, Self, crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>>
994 where
995 V3: 'static,
996 Value2: std::borrow::Borrow<V2>,
997 MutValue2: std::borrow::BorrowMut<V2>,
998 Value3: std::borrow::Borrow<V3>,
999 MutValue3: std::borrow::BorrowMut<V3>,
1000 G3: Fn(Value2) -> Option<Value3> + Clone,
1001 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1002 {
1003 AsyncKeyPathThenKp {
1004 first: self,
1005 second: next_kp,
1006 _p: std::marker::PhantomData,
1007 }
1008 }
1009}
1010
1011#[derive(Clone)]
1013pub struct AsyncKeyPathThenKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1014 pub(crate) first: First,
1015 pub(crate) second: Second,
1016 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1017}
1018
1019impl<R, V2, Root, Value2, MutRoot, MutValue2, First, RKp, G, S>
1021 AsyncKeyPathThenKp<R, V2, Root, Value2, MutRoot, MutValue2, First, crate::Kp<RKp, V2, First::Value, Value2, First::MutValue, MutValue2, G, S>>
1022where
1023 First: AsyncKeyPathLike<Root, MutRoot>,
1024 First::Value: std::borrow::Borrow<RKp>,
1025 First::MutValue: std::borrow::BorrowMut<RKp>,
1026 Value2: std::borrow::Borrow<V2>,
1027 MutValue2: std::borrow::BorrowMut<V2>,
1028 G: Fn(First::Value) -> Option<Value2>,
1029 S: Fn(First::MutValue) -> Option<MutValue2>,
1030{
1031 #[inline]
1033 pub async fn get(&self, root: Root) -> Option<Value2> {
1034 let value = self.first.get(root).await?;
1035 (self.second.get)(value)
1036 }
1037 #[inline]
1039 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1040 let mut_value = self.first.get_mut(root).await?;
1041 (self.second.set)(mut_value)
1042 }
1043}
1044
1045#[async_trait(?Send)]
1046impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1047 AsyncKeyPathLike<Root, MutRoot> for ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1048where
1049 First: AsyncKeyPathLike<Root, MutRoot>,
1050 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1051{
1052 type Value = Value2;
1053 type MutValue = MutValue2;
1054 async fn get(&self, root: Root) -> Option<Value2> {
1055 ComposedAsyncLockKp::get(self, root).await
1056 }
1057 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1058 ComposedAsyncLockKp::get_mut(self, root).await
1059 }
1060}
1061
1062#[derive(Clone)]
1069pub struct AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1070 pub(crate) first: First,
1071 pub(crate) second: Second,
1072 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1073}
1074
1075impl<
1076 R,
1077 V2,
1078 Root,
1079 Value2,
1080 MutRoot,
1081 MutValue2,
1082 Lock,
1083 Mid,
1084 V,
1085 LockValue,
1086 MidValue,
1087 Value,
1088 MutLock,
1089 MutMid,
1090 MutValue,
1091 G1,
1092 S1,
1093 L,
1094 G2,
1095 S2,
1096 Lock2,
1097 Mid2,
1098 LockValue2,
1099 MidValue2,
1100 MutLock2,
1101 MutMid2,
1102 G2_1,
1103 S2_1,
1104 L2,
1105 G2_2,
1106 S2_2,
1107 >
1108 AsyncLockKpThenLockKp<
1109 R,
1110 V2,
1111 Root,
1112 Value2,
1113 MutRoot,
1114 MutValue2,
1115 AsyncLockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>,
1116 crate::lock::LockKp<V, Lock2, Mid2, V2, Value, LockValue2, MidValue2, Value2, MutValue, MutLock2, MutMid2, MutValue2, G2_1, S2_1, L2, G2_2, S2_2>,
1117 >
1118where
1119 Root: std::borrow::Borrow<R>,
1120 LockValue: std::borrow::Borrow<Lock>,
1121 MidValue: std::borrow::Borrow<Mid>,
1122 Value: std::borrow::Borrow<V>,
1123 MutRoot: std::borrow::BorrowMut<R>,
1124 MutLock: std::borrow::BorrowMut<Lock>,
1125 MutMid: std::borrow::BorrowMut<Mid>,
1126 MutValue: std::borrow::BorrowMut<V>,
1127 Value2: std::borrow::Borrow<V2>,
1128 MutValue2: std::borrow::BorrowMut<V2>,
1129 G1: Fn(Root) -> Option<LockValue> + Clone,
1130 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
1131 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
1132 G2: Fn(MidValue) -> Option<Value> + Clone,
1133 S2: Fn(MutMid) -> Option<MutValue> + Clone,
1134 LockValue2: std::borrow::Borrow<Lock2>,
1135 MidValue2: std::borrow::Borrow<Mid2>,
1136 MutLock2: std::borrow::BorrowMut<Lock2>,
1137 MutMid2: std::borrow::BorrowMut<Mid2>,
1138 G2_1: Fn(Value) -> Option<LockValue2>,
1139 S2_1: Fn(MutValue) -> Option<MutLock2>,
1140 L2: crate::lock::LockAccess<Lock2, MidValue2> + crate::lock::LockAccess<Lock2, MutMid2>,
1141 G2_2: Fn(MidValue2) -> Option<Value2>,
1142 S2_2: Fn(MutMid2) -> Option<MutValue2>,
1143 Lock: Clone,
1144 V: Clone,
1145 V2: Clone,
1146{
1147 pub async fn get(&self, root: Root) -> Option<Value2> {
1149 let value = self.first.get(root).await?;
1150 self.second.get(value)
1151 }
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 First,
1180 Second,
1181 >
1182 AsyncLockKpThenLockKp<
1183 R,
1184 V2,
1185 Root,
1186 Value2,
1187 MutRoot,
1188 MutValue2,
1189 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>,
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 First: AsyncKeyPathLike<Root, MutRoot>,
1194 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = 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 = self.first.get(root).await?;
1212 self.second.get(value)
1213 }
1214 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1216 let mut_value = self.first.get_mut(root).await?;
1217 self.second.get_mut(mut_value)
1218 }
1219}
1220
1221impl<
1223 R,
1224 V2,
1225 Root,
1226 Value2,
1227 MutRoot,
1228 MutValue2,
1229 Lock3,
1230 Mid3,
1231 LockValue3,
1232 MidValue3,
1233 MutLock3,
1234 MutMid3,
1235 G3_1,
1236 S3_1,
1237 L3,
1238 G3_2,
1239 S3_2,
1240 F,
1241 S,
1242 >
1243 AsyncLockKpThenLockKp<
1244 R,
1245 V2,
1246 Root,
1247 Value2,
1248 MutRoot,
1249 MutValue2,
1250 AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, F, S>,
1251 crate::lock::LockKp<Value2, Lock3, Mid3, V2, Value2, LockValue3, MidValue3, Value2, MutValue2, MutLock3, MutMid3, MutValue2, G3_1, S3_1, L3, G3_2, S3_2>,
1252 >
1253where
1254 F: AsyncKeyPathLike<Root, MutRoot, Value = Value2, MutValue = MutValue2>,
1255 S: SyncKeyPathLike<Value2, Value2, MutValue2, MutValue2>,
1256 Value2: std::borrow::Borrow<V2>,
1257 MutValue2: std::borrow::BorrowMut<Value2> + std::borrow::BorrowMut<V2>,
1258 LockValue3: std::borrow::Borrow<Lock3>,
1259 MidValue3: std::borrow::Borrow<Mid3>,
1260 MutLock3: std::borrow::BorrowMut<Lock3>,
1261 MutMid3: std::borrow::BorrowMut<Mid3>,
1262 G3_1: Fn(Value2) -> Option<LockValue3>,
1263 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1264 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
1265 G3_2: Fn(MidValue3) -> Option<Value2>,
1266 S3_2: Fn(MutMid3) -> Option<MutValue2>,
1267 Value2: Clone,
1268 V2: Clone,
1269{
1270 pub async fn get(&self, root: Root) -> Option<Value2> {
1272 let value = AsyncKeyPathLike::get(&self.first, root).await?;
1273 self.second.get(value)
1274 }
1275 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1277 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
1278 self.second.get_mut(mut_value)
1279 }
1280}
1281
1282#[async_trait(?Send)]
1284impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncKeyPathLike<Root, MutRoot>
1285 for AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1286where
1287 First: AsyncKeyPathLike<Root, MutRoot>,
1288 Second: SyncKeyPathLike<First::Value, Value2, First::MutValue, MutValue2>,
1289{
1290 type Value = Value2;
1291 type MutValue = MutValue2;
1292 async fn get(&self, root: Root) -> Option<Value2> {
1293 let value = AsyncKeyPathLike::get(&self.first, root).await?;
1294 SyncKeyPathLike::sync_get(&self.second, value)
1295 }
1296 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1297 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
1298 SyncKeyPathLike::sync_get_mut(&self.second, mut_value)
1299 }
1300}
1301
1302impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1304where
1305 First: AsyncKeyPathLike<Root, MutRoot>,
1306{
1307 pub fn then_async<
1310 Lock3,
1311 Mid3,
1312 V3,
1313 LockValue3,
1314 MidValue3,
1315 Value3,
1316 MutLock3,
1317 MutMid3,
1318 MutValue3,
1319 G3_1,
1320 S3_1,
1321 L3,
1322 G3_2,
1323 S3_2,
1324 >(
1325 self,
1326 other: AsyncLockKp<
1327 Value2,
1328 Lock3,
1329 Mid3,
1330 V3,
1331 Value2,
1332 LockValue3,
1333 MidValue3,
1334 Value3,
1335 MutValue2,
1336 MutLock3,
1337 MutMid3,
1338 MutValue3,
1339 G3_1,
1340 S3_1,
1341 L3,
1342 G3_2,
1343 S3_2,
1344 >,
1345 ) -> ComposedAsyncLockKp<
1346 Root,
1347 V3,
1348 Root,
1349 Value3,
1350 MutRoot,
1351 MutValue3,
1352 Self,
1353 AsyncLockKp<
1354 Value2,
1355 Lock3,
1356 Mid3,
1357 V3,
1358 Value2,
1359 LockValue3,
1360 MidValue3,
1361 Value3,
1362 MutValue2,
1363 MutLock3,
1364 MutMid3,
1365 MutValue3,
1366 G3_1,
1367 S3_1,
1368 L3,
1369 G3_2,
1370 S3_2,
1371 >,
1372 >
1373 where
1374 V2: 'static,
1375 V3: 'static,
1376 Value2: std::borrow::Borrow<V2>,
1377 Value3: std::borrow::Borrow<V3>,
1378 MutValue2: std::borrow::BorrowMut<V2> + std::borrow::BorrowMut<Value2>,
1379 MutValue3: std::borrow::BorrowMut<V3>,
1380 LockValue3: std::borrow::Borrow<Lock3>,
1381 MidValue3: std::borrow::Borrow<Mid3>,
1382 MutLock3: std::borrow::BorrowMut<Lock3>,
1383 MutMid3: std::borrow::BorrowMut<Mid3>,
1384 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
1385 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
1386 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
1387 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
1388 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
1389 Lock3: Clone,
1390 {
1391 ComposedAsyncLockKp {
1392 first: self,
1393 second: other,
1394 _p: std::marker::PhantomData,
1395 }
1396 }
1397
1398 pub fn then_lock<
1400 Lock3,
1401 Mid3,
1402 V3,
1403 LockValue3,
1404 MidValue3,
1405 Value3,
1406 MutLock3,
1407 MutMid3,
1408 MutValue3,
1409 G3_1,
1410 S3_1,
1411 L3,
1412 G3_2,
1413 S3_2,
1414 >(
1415 self,
1416 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>,
1417 ) -> 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>>
1418 where
1419 V3: 'static,
1420 Value2: std::borrow::Borrow<V2>,
1421 Value3: std::borrow::Borrow<V3>,
1422 MutValue2: std::borrow::BorrowMut<Value2>,
1423 MutValue3: std::borrow::BorrowMut<V3>,
1424 LockValue3: std::borrow::Borrow<Lock3>,
1425 MidValue3: std::borrow::Borrow<Mid3>,
1426 MutLock3: std::borrow::BorrowMut<Lock3>,
1427 MutMid3: std::borrow::BorrowMut<Mid3>,
1428 G3_1: Fn(Value2) -> Option<LockValue3>,
1429 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1430 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
1431 G3_2: Fn(MidValue3) -> Option<Value3>,
1432 S3_2: Fn(MutMid3) -> Option<MutValue3>,
1433 {
1434 AsyncLockKpThenLockKp {
1435 first: self,
1436 second: lock_kp,
1437 _p: std::marker::PhantomData,
1438 }
1439 }
1440
1441 pub fn then<V3, Value3, MutValue3, G3, S3>(
1443 self,
1444 next_kp: crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1445 ) -> AsyncKeyPathThenKp<R, V3, Root, Value3, MutRoot, MutValue3, Self, crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>>
1446 where
1447 V3: 'static,
1448 Value2: std::borrow::Borrow<V2>,
1449 Value3: std::borrow::Borrow<V3>,
1450 MutValue2: std::borrow::BorrowMut<Value2>,
1451 MutValue3: std::borrow::BorrowMut<V3>,
1452 G3: Fn(Value2) -> Option<Value3> + Clone,
1453 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1454 {
1455 AsyncKeyPathThenKp {
1456 first: self,
1457 second: next_kp,
1458 _p: std::marker::PhantomData,
1459 }
1460 }
1461}
1462
1463#[cfg(feature = "tokio")]
1468#[derive(Clone)] pub struct TokioMutexAccess<T> {
1476 _phantom: std::marker::PhantomData<T>,
1477}
1478
1479#[cfg(feature = "tokio")]
1480impl<T> TokioMutexAccess<T> {
1481 pub fn new() -> Self {
1482 Self {
1483 _phantom: std::marker::PhantomData,
1484 }
1485 }
1486}
1487
1488#[cfg(feature = "tokio")]
1489impl<T> Default for TokioMutexAccess<T> {
1490 fn default() -> Self {
1491 Self::new()
1492 }
1493}
1494
1495#[cfg(feature = "tokio")]
1497#[async_trait]
1498impl<'a, T: 'static + Send + Sync> AsyncLockLike<Arc<tokio::sync::Mutex<T>>, &'a T>
1499 for TokioMutexAccess<T>
1500{
1501 #[inline]
1502 async fn lock_read(&self, lock: &Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
1503 let guard = lock.lock().await;
1505 let ptr = &*guard as *const T;
1506 unsafe { Some(&*ptr) }
1507 }
1508
1509 #[inline]
1510 async fn lock_write(&self, lock: &mut Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
1511 let guard = lock.lock().await;
1512 let ptr = &*guard as *const T;
1513 unsafe { Some(&*ptr) }
1514 }
1515}
1516
1517#[cfg(feature = "tokio")]
1519#[async_trait]
1520impl<'a, T: 'static + Send + Sync> AsyncLockLike<Arc<tokio::sync::Mutex<T>>, &'a mut T>
1521 for TokioMutexAccess<T>
1522{
1523 #[inline]
1524 async fn lock_read(&self, lock: &Arc<tokio::sync::Mutex<T>>) -> Option<&'a mut T> {
1525 let mut guard = lock.lock().await;
1527 let ptr = &mut *guard as *mut T;
1528 unsafe { Some(&mut *ptr) }
1529 }
1530
1531 #[inline]
1532 async fn lock_write(&self, lock: &mut Arc<tokio::sync::Mutex<T>>) -> Option<&'a mut T> {
1533 let mut guard = lock.lock().await;
1534 let ptr = &mut *guard as *mut T;
1535 unsafe { Some(&mut *ptr) }
1536 }
1537}
1538
1539#[cfg(feature = "tokio")]
1544pub struct TokioRwLockAccess<T> {
1552 _phantom: std::marker::PhantomData<T>,
1553}
1554
1555#[cfg(feature = "tokio")]
1556impl<T> TokioRwLockAccess<T> {
1557 pub fn new() -> Self {
1558 Self {
1559 _phantom: std::marker::PhantomData,
1560 }
1561 }
1562}
1563
1564#[cfg(feature = "tokio")]
1565impl<T> Default for TokioRwLockAccess<T> {
1566 fn default() -> Self {
1567 Self::new()
1568 }
1569}
1570
1571#[cfg(feature = "tokio")]
1572impl<T> Clone for TokioRwLockAccess<T> {
1573 fn clone(&self) -> Self {
1574 Self {
1575 _phantom: self._phantom,
1576 }
1577 }
1578}
1579
1580#[cfg(feature = "tokio")]
1582#[async_trait]
1583impl<'a, T: 'static + Send + Sync> AsyncLockLike<Arc<tokio::sync::RwLock<T>>, &'a T>
1584 for TokioRwLockAccess<T>
1585{
1586 async fn lock_read(&self, lock: &Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
1587 let guard = lock.read().await;
1589 let ptr = &*guard as *const T;
1590 unsafe { Some(&*ptr) }
1591 }
1592
1593 async fn lock_write(&self, lock: &mut Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
1594 let guard = lock.read().await;
1596 let ptr = &*guard as *const T;
1597 unsafe { Some(&*ptr) }
1598 }
1599}
1600
1601#[cfg(feature = "tokio")]
1603#[async_trait]
1604impl<'a, T: 'static + Send + Sync> AsyncLockLike<Arc<tokio::sync::RwLock<T>>, &'a mut T>
1605 for TokioRwLockAccess<T>
1606{
1607 async fn lock_read(&self, lock: &Arc<tokio::sync::RwLock<T>>) -> Option<&'a mut T> {
1608 let mut guard = lock.write().await;
1610 let ptr = &mut *guard as *mut T;
1611 unsafe { Some(&mut *ptr) }
1612 }
1613
1614 async fn lock_write(&self, lock: &mut Arc<tokio::sync::RwLock<T>>) -> Option<&'a mut T> {
1615 let mut guard = lock.write().await;
1617 let ptr = &mut *guard as *mut T;
1618 unsafe { Some(&mut *ptr) }
1619 }
1620}
1621
1622#[cfg(feature = "tokio")]
1630pub type AsyncLockKpMutexFor<Root, Lock, Inner> = AsyncLockKp<
1632 Root,
1633 Lock,
1634 Inner,
1635 Inner,
1636 &'static Root,
1637 &'static Lock,
1638 &'static Inner,
1639 &'static Inner,
1640 &'static mut Root,
1641 &'static mut Lock,
1642 &'static mut Inner,
1643 &'static mut Inner,
1644 for<'b> fn(&'b Root) -> Option<&'b Lock>,
1645 for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1646 TokioMutexAccess<Inner>,
1647 for<'b> fn(&'b Inner) -> Option<&'b Inner>,
1648 for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
1649>;
1650
1651#[cfg(feature = "tokio")]
1652pub type AsyncLockKpRwLockFor<Root, Lock, Inner> = AsyncLockKp<
1654 Root,
1655 Lock,
1656 Inner,
1657 Inner,
1658 &'static Root,
1659 &'static Lock,
1660 &'static Inner,
1661 &'static Inner,
1662 &'static mut Root,
1663 &'static mut Lock,
1664 &'static mut Inner,
1665 &'static mut Inner,
1666 for<'b> fn(&'b Root) -> Option<&'b Lock>,
1667 for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1668 TokioRwLockAccess<Inner>,
1669 for<'b> fn(&'b Inner) -> Option<&'b Inner>,
1670 for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
1671>;
1672
1673#[cfg(all(test, feature = "tokio"))]
1678mod tests {
1679 use super::*;
1680 use crate::KpType;
1681
1682 #[tokio::test]
1683 async fn test_async_lock_kp_tokio_mutex_basic() {
1684 use tokio::sync::Mutex;
1685
1686 #[derive(Clone)]
1687 struct Root {
1688 data: Arc<Mutex<String>>,
1689 }
1690
1691 let root = Root {
1692 data: Arc::new(Mutex::new("hello".to_string())),
1693 };
1694
1695 let lock_kp = {
1697 let prev: KpType<Root, Arc<Mutex<String>>> =
1698 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1699 let next: KpType<String, String> =
1700 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
1701 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1702 };
1703
1704 let value = lock_kp.get(&root).await;
1706 assert!(value.is_some());
1707 assert_eq!(value.unwrap(), &"hello".to_string());
1708 }
1709
1710 #[tokio::test]
1711 async fn test_async_lock_kp_tokio_rwlock_basic() {
1712 use tokio::sync::RwLock;
1713
1714 #[derive(Clone)]
1715 struct Root {
1716 data: Arc<RwLock<Vec<i32>>>,
1717 }
1718
1719 let root = Root {
1720 data: Arc::new(RwLock::new(vec![1, 2, 3, 4, 5])),
1721 };
1722
1723 let lock_kp = {
1725 let prev: KpType<Root, Arc<RwLock<Vec<i32>>>> =
1726 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1727 let next: KpType<Vec<i32>, Vec<i32>> =
1728 Kp::new(|v: &Vec<i32>| Some(v), |v: &mut Vec<i32>| Some(v));
1729 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
1730 };
1731
1732 let value = lock_kp.get(&root).await;
1734 assert!(value.is_some());
1735 assert_eq!(value.unwrap().len(), 5);
1736 }
1737
1738 #[tokio::test]
1739 async fn test_async_lock_kp_concurrent_reads() {
1740 use tokio::sync::RwLock;
1741
1742 #[derive(Clone)]
1743 struct Root {
1744 data: Arc<RwLock<i32>>,
1745 }
1746
1747 let root = Root {
1748 data: Arc::new(RwLock::new(42)),
1749 };
1750
1751 let lock_kp = {
1753 let prev: KpType<Root, Arc<RwLock<i32>>> =
1754 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1755 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
1756 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
1757 };
1758
1759 let mut handles = vec![];
1761 for _ in 0..10 {
1762 let root_clone = root.clone();
1763
1764 let lock_kp_for_task = {
1766 let prev: KpType<Root, Arc<RwLock<i32>>> =
1767 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1768 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
1769 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
1770 };
1771
1772 let handle = tokio::spawn(async move { lock_kp_for_task.get(&root_clone).await });
1773 handles.push(handle);
1774 }
1775
1776 for handle in handles {
1778 let result = handle.await.unwrap();
1779 assert_eq!(result, Some(&42));
1780 }
1781
1782 let value = lock_kp.get(&root).await;
1784 assert_eq!(value, Some(&42));
1785 }
1786
1787 #[tokio::test]
1788 async fn test_async_lock_kp_panic_on_clone_proof() {
1789 use tokio::sync::Mutex;
1790
1791 struct PanicOnClone {
1793 data: String,
1794 }
1795
1796 impl Clone for PanicOnClone {
1797 fn clone(&self) -> Self {
1798 panic!("❌ ASYNC DEEP CLONE DETECTED! PanicOnClone was cloned!");
1799 }
1800 }
1801
1802 #[derive(Clone)]
1803 struct Root {
1804 level1: Arc<Mutex<Level1>>,
1805 }
1806
1807 struct Level1 {
1808 panic_data: PanicOnClone,
1809 value: i32,
1810 }
1811
1812 impl Clone for Level1 {
1813 fn clone(&self) -> Self {
1814 panic!("❌ Level1 was deeply cloned in async context!");
1815 }
1816 }
1817
1818 let root = Root {
1820 level1: Arc::new(Mutex::new(Level1 {
1821 panic_data: PanicOnClone {
1822 data: "test".to_string(),
1823 },
1824 value: 123,
1825 })),
1826 };
1827
1828 let lock_kp = {
1830 let prev: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
1831 |r: &Root| Some(&r.level1),
1832 |r: &mut Root| Some(&mut r.level1),
1833 );
1834 let next: KpType<Level1, i32> = Kp::new(
1835 |l: &Level1| Some(&l.value),
1836 |l: &mut Level1| Some(&mut l.value),
1837 );
1838 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1839 };
1840
1841 let value = lock_kp.get(&root).await;
1843
1844 assert_eq!(value, Some(&123));
1846 }
1847
1848 #[tokio::test]
1849 async fn test_async_lock_kp_structure() {
1850 use tokio::sync::Mutex;
1851
1852 #[derive(Clone)]
1853 struct Root {
1854 data: Arc<Mutex<String>>,
1855 }
1856
1857 let lock_kp = {
1858 let prev: KpType<Root, Arc<Mutex<String>>> =
1859 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1860 let next: KpType<String, String> =
1861 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
1862 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1863 };
1864
1865 let _ = &lock_kp.prev;
1867 let _ = &lock_kp.mid;
1868 let _ = &lock_kp.next;
1869 }
1870
1871 #[tokio::test]
1872 async fn test_async_kp_then() {
1873 use tokio::sync::Mutex;
1874
1875 #[derive(Clone)]
1876 struct Root {
1877 data: Arc<Mutex<Inner>>,
1878 }
1879
1880 #[derive(Clone)]
1881 struct Inner {
1882 value: i32,
1883 }
1884
1885 let root = Root {
1886 data: Arc::new(Mutex::new(Inner { value: 42 })),
1887 };
1888
1889 let async_kp = {
1891 let prev: KpType<Root, Arc<Mutex<Inner>>> =
1892 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1893 let next: KpType<Inner, Inner> = Kp::new(|i: &Inner| Some(i), |i: &mut Inner| Some(i));
1894 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1895 };
1896
1897 let value_kp: KpType<Inner, i32> = Kp::new(
1899 |i: &Inner| Some(&i.value),
1900 |i: &mut Inner| Some(&mut i.value),
1901 );
1902
1903 let chained = async_kp.then(value_kp);
1904 let result = chained.get(&root).await;
1905 assert_eq!(result, Some(&42));
1906 }
1907
1908 #[tokio::test]
1909 async fn test_async_kp_later_then() {
1910 use tokio::sync::Mutex;
1911
1912 #[derive(Clone)]
1913 struct Root {
1914 lock1: Arc<Mutex<Container>>,
1915 }
1916
1917 #[derive(Clone)]
1918 struct Container {
1919 lock2: Arc<Mutex<i32>>,
1920 }
1921
1922 let root = Root {
1923 lock1: Arc::new(Mutex::new(Container {
1924 lock2: Arc::new(Mutex::new(999)),
1925 })),
1926 };
1927
1928 let async_kp1 = {
1930 let prev: KpType<Root, Arc<Mutex<Container>>> =
1931 Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
1932 let next: KpType<Container, Container> =
1933 Kp::new(|c: &Container| Some(c), |c: &mut Container| Some(c));
1934 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1935 };
1936
1937 let async_kp2 = {
1939 let prev: KpType<Container, Arc<Mutex<i32>>> = Kp::new(
1940 |c: &Container| Some(&c.lock2),
1941 |c: &mut Container| Some(&mut c.lock2),
1942 );
1943 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
1944 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1945 };
1946
1947 let chained = async_kp1.then_async(async_kp2);
1949 let result = chained.get(&root).await;
1950 assert_eq!(result, Some(&999));
1951 }
1952
1953 #[tokio::test]
1954 async fn test_async_kp_then_async_three_levels() {
1955 use tokio::sync::Mutex;
1956
1957 #[derive(Clone)]
1958 struct Root {
1959 a: Arc<Mutex<Level1>>,
1960 }
1961 #[derive(Clone)]
1962 struct Level1 {
1963 b: Arc<Mutex<Level2>>,
1964 }
1965 #[derive(Clone)]
1966 struct Level2 {
1967 c: Arc<Mutex<i32>>,
1968 }
1969
1970 let root = Root {
1971 a: Arc::new(Mutex::new(Level1 {
1972 b: Arc::new(Mutex::new(Level2 {
1973 c: Arc::new(Mutex::new(42)),
1974 })),
1975 })),
1976 };
1977
1978 let kp1 = {
1979 let prev: KpType<Root, Arc<Mutex<Level1>>> =
1980 Kp::new(|r: &Root| Some(&r.a), |r: &mut Root| Some(&mut r.a));
1981 let next: KpType<Level1, Level1> =
1982 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
1983 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1984 };
1985 let kp2 = {
1986 let prev: KpType<Level1, Arc<Mutex<Level2>>> =
1987 Kp::new(|l: &Level1| Some(&l.b), |l: &mut Level1| Some(&mut l.b));
1988 let next: KpType<Level2, Level2> =
1989 Kp::new(|l: &Level2| Some(l), |l: &mut Level2| Some(l));
1990 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1991 };
1992 let kp3 = {
1993 let prev: KpType<Level2, Arc<Mutex<i32>>> =
1994 Kp::new(|l: &Level2| Some(&l.c), |l: &mut Level2| Some(&mut l.c));
1995 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
1996 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
1997 };
1998
1999 let chained = kp1.then_async(kp2).then_async(kp3);
2000 let result = chained.get(&root).await;
2001 assert_eq!(result, Some(&42));
2002 }
2003}