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