1use crate::{AccessorTrait, Kp, KpTrait};
33use async_trait::async_trait;
34#[cfg(feature = "tokio")]
36pub use tokio::sync::{Mutex as TokioMutex, RwLock as TokioRwLock};
37
38#[async_trait]
56pub trait AsyncLockLike<Lock, Inner>: Send + Sync {
57 async fn lock_read(&self, lock: &Lock) -> Option<Inner>;
59
60 async fn lock_write(&self, lock: &mut Lock) -> Option<Inner>;
62}
63
64pub trait SyncKeyPathLike<Root, Value, MutRoot, MutValue> {
67 fn sync_get(&self, root: Root) -> Option<Value>;
98
99 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue>;
130}
131
132impl<R, V, Root, Value, MutRoot, MutValue, G, S> SyncKeyPathLike<Root, Value, MutRoot, MutValue>
133 for crate::Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
134where
135 Root: std::borrow::Borrow<R>,
136 Value: std::borrow::Borrow<V>,
137 MutRoot: std::borrow::BorrowMut<R>,
138 MutValue: std::borrow::BorrowMut<V>,
139 G: Fn(Root) -> Option<Value>,
140 S: Fn(MutRoot) -> Option<MutValue>,
141 {
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.set)(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> SyncKeyPathLike<Root, Value, MutRoot, MutValue>
170 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 #[inline]
417 pub async fn get_optional(&self, root: Option<Root>) -> Option<Value>
418 where
419 Lock: Clone,
420 {
421 match root {
422 Some(r) => self.get(r).await,
423 None => None,
424 }
425 }
426
427 #[inline]
429 pub async fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue>
430 where
431 Lock: Clone,
432 {
433 match root {
434 Some(r) => self.get_mut(r).await,
435 None => None,
436 }
437 }
438
439 #[inline]
441 pub async fn get_or_else<F>(&self, root: Option<Root>, f: F) -> Value
442 where
443 Lock: Clone,
444 F: FnOnce() -> Value,
445 {
446 self.get_optional(root).await.unwrap_or_else(f)
447 }
448
449 #[inline]
451 pub async fn get_mut_or_else<F>(&self, root: Option<MutRoot>, f: F) -> MutValue
452 where
453 Lock: Clone,
454 F: FnOnce() -> MutValue,
455 {
456 self.get_mut_optional(root).await.unwrap_or_else(f)
457 }
458
459 pub async fn set<F>(&self, root: Root, updater: F) -> Result<(), String>
466 where
467 Lock: Clone,
468 F: FnOnce(&mut V),
469 {
470 let lock_value = (self.prev.get)(root).ok_or("Failed to get lock from root")?;
472 let lock: &Lock = lock_value.borrow();
473 let lock_clone = lock.clone(); let mid_value = self
477 .mid
478 .lock_read(&lock_clone)
479 .await
480 .ok_or("Failed to lock")?;
481
482 let mut mut_value = (self.next.set)(mid_value).ok_or("Failed to navigate to value")?;
484 let v: &mut V = mut_value.borrow_mut();
485
486 updater(v);
488
489 Ok(())
490 }
491
492 pub fn then<V2, Value2, MutValue2, G3, S3>(
508 self,
509 next_kp: crate::Kp<V, V2, Value, Value2, MutValue, MutValue2, G3, S3>,
510 ) -> AsyncLockKp<
511 R,
512 Lock,
513 Mid,
514 V2,
515 Root,
516 LockValue,
517 MidValue,
518 Value2,
519 MutRoot,
520 MutLock,
521 MutMid,
522 MutValue2,
523 G1,
524 S1,
525 L,
526 impl Fn(MidValue) -> Option<Value2>
527 + Clone
528 + use<
529 G1,
530 G2,
531 G3,
532 L,
533 Lock,
534 LockValue,
535 Mid,
536 MidValue,
537 MutLock,
538 MutMid,
539 MutRoot,
540 MutValue,
541 MutValue2,
542 R,
543 Root,
544 S1,
545 S2,
546 S3,
547 Value,
548 Value2,
549 V,
550 V2,
551 >,
552 impl Fn(MutMid) -> Option<MutValue2>
553 + Clone
554 + use<
555 G1,
556 G2,
557 G3,
558 L,
559 Lock,
560 LockValue,
561 Mid,
562 MidValue,
563 MutLock,
564 MutMid,
565 MutRoot,
566 MutValue,
567 MutValue2,
568 R,
569 Root,
570 S1,
571 S2,
572 S3,
573 Value,
574 Value2,
575 V,
576 V2,
577 >,
578 >
579 where
580 V: 'static,
581 V2: 'static,
582 Value: std::borrow::Borrow<V>,
583 Value2: std::borrow::Borrow<V2>,
584 MutValue: std::borrow::BorrowMut<V>,
585 MutValue2: std::borrow::BorrowMut<V2>,
586 G3: Fn(Value) -> Option<Value2> + Clone,
587 S3: Fn(MutValue) -> Option<MutValue2> + Clone,
588 {
589 let next_get = self.next.get;
590 let next_set = self.next.set;
591 let chained_kp = crate::Kp::new(
592 move |mid_value: MidValue| next_get(mid_value).and_then(|v| (next_kp.get)(v)),
593 move |mid_value: MutMid| next_set(mid_value).and_then(|v| (next_kp.set)(v)),
594 );
595 AsyncLockKp::new(self.prev, self.mid, chained_kp)
596 }
597
598 pub fn then_lock<
601 Lock2,
602 Mid2,
603 V2,
604 LockValue2,
605 MidValue2,
606 Value2,
607 MutLock2,
608 MutMid2,
609 MutValue2,
610 G2_1,
611 S2_1,
612 L2,
613 G2_2,
614 S2_2,
615 >(
616 self,
617 lock_kp: crate::lock::LockKp<
618 V,
619 Lock2,
620 Mid2,
621 V2,
622 Value,
623 LockValue2,
624 MidValue2,
625 Value2,
626 MutValue,
627 MutLock2,
628 MutMid2,
629 MutValue2,
630 G2_1,
631 S2_1,
632 L2,
633 G2_2,
634 S2_2,
635 >,
636 ) -> AsyncLockKpThenLockKp<
637 R,
638 V2,
639 Root,
640 Value2,
641 MutRoot,
642 MutValue2,
643 Self,
644 crate::lock::LockKp<
645 V,
646 Lock2,
647 Mid2,
648 V2,
649 Value,
650 LockValue2,
651 MidValue2,
652 Value2,
653 MutValue,
654 MutLock2,
655 MutMid2,
656 MutValue2,
657 G2_1,
658 S2_1,
659 L2,
660 G2_2,
661 S2_2,
662 >,
663 >
664 where
665 V: 'static,
666 V2: 'static,
667 Value: std::borrow::Borrow<V>,
668 Value2: std::borrow::Borrow<V2>,
669 MutValue: std::borrow::BorrowMut<V>,
670 MutValue2: std::borrow::BorrowMut<V2>,
671 LockValue2: std::borrow::Borrow<Lock2>,
672 MidValue2: std::borrow::Borrow<Mid2>,
673 MutLock2: std::borrow::BorrowMut<Lock2>,
674 MutMid2: std::borrow::BorrowMut<Mid2>,
675 G2_1: Fn(Value) -> Option<LockValue2>,
676 S2_1: Fn(MutValue) -> Option<MutLock2>,
677 L2: crate::lock::LockAccess<Lock2, MidValue2> + crate::lock::LockAccess<Lock2, MutMid2>,
678 G2_2: Fn(MidValue2) -> Option<Value2>,
679 S2_2: Fn(MutMid2) -> Option<MutValue2>,
680 {
681 AsyncLockKpThenLockKp {
682 first: self,
683 second: lock_kp,
684 _p: std::marker::PhantomData,
685 }
686 }
687
688 pub fn then_async<
704 Lock2,
705 Mid2,
706 V2,
707 LockValue2,
708 MidValue2,
709 Value2,
710 MutLock2,
711 MutMid2,
712 MutValue2,
713 G2_1,
714 S2_1,
715 L2,
716 G2_2,
717 S2_2,
718 >(
719 self,
720 other: AsyncLockKp<
721 V,
722 Lock2,
723 Mid2,
724 V2,
725 Value,
726 LockValue2,
727 MidValue2,
728 Value2,
729 MutValue,
730 MutLock2,
731 MutMid2,
732 MutValue2,
733 G2_1,
734 S2_1,
735 L2,
736 G2_2,
737 S2_2,
738 >,
739 ) -> ComposedAsyncLockKp<
740 R,
741 V2,
742 Root,
743 Value2,
744 MutRoot,
745 MutValue2,
746 Self,
747 AsyncLockKp<
748 V,
749 Lock2,
750 Mid2,
751 V2,
752 Value,
753 LockValue2,
754 MidValue2,
755 Value2,
756 MutValue,
757 MutLock2,
758 MutMid2,
759 MutValue2,
760 G2_1,
761 S2_1,
762 L2,
763 G2_2,
764 S2_2,
765 >,
766 >
767 where
768 Lock: Clone,
769 Lock2: Clone,
770 V: 'static,
771 V2: 'static,
772 Value: std::borrow::Borrow<V>,
773 LockValue2: std::borrow::Borrow<Lock2>,
774 MidValue2: std::borrow::Borrow<Mid2>,
775 Value2: std::borrow::Borrow<V2>,
776 MutValue: std::borrow::BorrowMut<V>,
777 MutLock2: std::borrow::BorrowMut<Lock2>,
778 MutMid2: std::borrow::BorrowMut<Mid2>,
779 MutValue2: std::borrow::BorrowMut<V2>,
780 G2_1: Fn(Value) -> Option<LockValue2> + Clone,
781 S2_1: Fn(MutValue) -> Option<MutLock2> + Clone,
782 L2: AsyncLockLike<Lock2, MidValue2> + AsyncLockLike<Lock2, MutMid2> + Clone,
783 G2_2: Fn(MidValue2) -> Option<Value2> + Clone,
784 S2_2: Fn(MutMid2) -> Option<MutValue2> + Clone,
785 {
786 ComposedAsyncLockKp {
787 first: self,
788 second: other,
789 _p: std::marker::PhantomData,
790 }
791 }
792}
793
794#[async_trait(?Send)]
796impl<
797 R,
798 Lock,
799 Mid,
800 V,
801 Root,
802 LockValue,
803 MidValue,
804 Value,
805 MutRoot,
806 MutLock,
807 MutMid,
808 MutValue,
809 G1,
810 S1,
811 L,
812 G2,
813 S2,
814> AsyncKeyPathLike<Root, MutRoot>
815 for AsyncLockKp<
816 R,
817 Lock,
818 Mid,
819 V,
820 Root,
821 LockValue,
822 MidValue,
823 Value,
824 MutRoot,
825 MutLock,
826 MutMid,
827 MutValue,
828 G1,
829 S1,
830 L,
831 G2,
832 S2,
833 >
834where
835 Root: std::borrow::Borrow<R>,
836 LockValue: std::borrow::Borrow<Lock>,
837 MidValue: std::borrow::Borrow<Mid>,
838 Value: std::borrow::Borrow<V>,
839 MutRoot: std::borrow::BorrowMut<R>,
840 MutLock: std::borrow::BorrowMut<Lock>,
841 MutMid: std::borrow::BorrowMut<Mid>,
842 MutValue: std::borrow::BorrowMut<V>,
843 G1: Fn(Root) -> Option<LockValue> + Clone,
844 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
845 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
846 G2: Fn(MidValue) -> Option<Value> + Clone,
847 S2: Fn(MutMid) -> Option<MutValue> + Clone,
848 Lock: Clone,
849{
850 type Value = Value;
851 type MutValue = MutValue;
852 async fn get(&self, root: Root) -> Option<Value> {
853 AsyncLockKp::get(self, root).await
854 }
855 async fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
856 AsyncLockKp::get_mut(self, root).await
857 }
858}
859
860#[derive(Clone)]
867pub struct ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
868 pub(crate) first: First,
869 pub(crate) second: Second,
870 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
871}
872
873impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
874 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
875where
876 First: AsyncKeyPathLike<Root, MutRoot>,
877 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
878{
879 pub async fn get(&self, root: Root) -> Option<Value2> {
881 let value = self.first.get(root).await?;
882 self.second.get(value).await
883 }
884
885 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
887 let mut_value = self.first.get_mut(root).await?;
888 self.second.get_mut(mut_value).await
889 }
890
891 pub fn then_async<
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 other: AsyncLockKp<
910 V2,
911 Lock3,
912 Mid3,
913 V3,
914 Value2,
915 LockValue3,
916 MidValue3,
917 Value3,
918 MutValue2,
919 MutLock3,
920 MutMid3,
921 MutValue3,
922 G3_1,
923 S3_1,
924 L3,
925 G3_2,
926 S3_2,
927 >,
928 ) -> ComposedAsyncLockKp<
929 R,
930 V3,
931 Root,
932 Value3,
933 MutRoot,
934 MutValue3,
935 Self,
936 AsyncLockKp<
937 V2,
938 Lock3,
939 Mid3,
940 V3,
941 Value2,
942 LockValue3,
943 MidValue3,
944 Value3,
945 MutValue2,
946 MutLock3,
947 MutMid3,
948 MutValue3,
949 G3_1,
950 S3_1,
951 L3,
952 G3_2,
953 S3_2,
954 >,
955 >
956 where
957 V2: 'static,
958 V3: 'static,
959 Value2: std::borrow::Borrow<V2>,
960 Value3: std::borrow::Borrow<V3>,
961 MutValue2: std::borrow::BorrowMut<V2>,
962 MutValue3: std::borrow::BorrowMut<V3>,
963 LockValue3: std::borrow::Borrow<Lock3>,
964 MidValue3: std::borrow::Borrow<Mid3>,
965 MutLock3: std::borrow::BorrowMut<Lock3>,
966 MutMid3: std::borrow::BorrowMut<Mid3>,
967 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
968 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
969 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
970 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
971 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
972 Lock3: Clone,
973 {
974 ComposedAsyncLockKp {
975 first: self,
976 second: other,
977 _p: std::marker::PhantomData,
978 }
979 }
980
981 pub fn then<V3, Value3, MutValue3, G3, S3>(
983 self,
984 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
985 ) -> AsyncKeyPathThenKp<
986 R,
987 V3,
988 Root,
989 Value3,
990 MutRoot,
991 MutValue3,
992 Self,
993 crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
994 >
995 where
996 V2: 'static,
997 V3: 'static,
998 Value2: std::borrow::Borrow<V2>,
999 Value3: std::borrow::Borrow<V3>,
1000 MutValue2: std::borrow::BorrowMut<V2>,
1001 MutValue3: std::borrow::BorrowMut<V3>,
1002 G3: Fn(Value2) -> Option<Value3> + Clone,
1003 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1004 {
1005 AsyncKeyPathThenKp {
1006 first: self,
1007 second: next_kp,
1008 _p: std::marker::PhantomData,
1009 }
1010 }
1011
1012 pub fn then_lock<
1014 Lock3,
1015 Mid3,
1016 V3,
1017 LockValue3,
1018 MidValue3,
1019 Value3,
1020 MutLock3,
1021 MutMid3,
1022 MutValue3,
1023 G3_1,
1024 S3_1,
1025 L3,
1026 G3_2,
1027 S3_2,
1028 >(
1029 self,
1030 lock_kp: crate::lock::LockKp<
1031 V2,
1032 Lock3,
1033 Mid3,
1034 V3,
1035 Value2,
1036 LockValue3,
1037 MidValue3,
1038 Value3,
1039 MutValue2,
1040 MutLock3,
1041 MutMid3,
1042 MutValue3,
1043 G3_1,
1044 S3_1,
1045 L3,
1046 G3_2,
1047 S3_2,
1048 >,
1049 ) -> AsyncLockKpThenLockKp<
1050 R,
1051 V3,
1052 Root,
1053 Value3,
1054 MutRoot,
1055 MutValue3,
1056 Self,
1057 crate::lock::LockKp<
1058 V2,
1059 Lock3,
1060 Mid3,
1061 V3,
1062 Value2,
1063 LockValue3,
1064 MidValue3,
1065 Value3,
1066 MutValue2,
1067 MutLock3,
1068 MutMid3,
1069 MutValue3,
1070 G3_1,
1071 S3_1,
1072 L3,
1073 G3_2,
1074 S3_2,
1075 >,
1076 >
1077 where
1078 V2: 'static,
1079 V3: 'static,
1080 Value2: std::borrow::Borrow<V2>,
1081 Value3: std::borrow::Borrow<V3>,
1082 MutValue2: std::borrow::BorrowMut<V2>,
1083 MutValue3: std::borrow::BorrowMut<V3>,
1084 LockValue3: std::borrow::Borrow<Lock3>,
1085 MidValue3: std::borrow::Borrow<Mid3>,
1086 MutLock3: std::borrow::BorrowMut<Lock3>,
1087 MutMid3: std::borrow::BorrowMut<Mid3>,
1088 G3_1: Fn(Value2) -> Option<LockValue3>,
1089 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1090 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
1091 G3_2: Fn(MidValue3) -> Option<Value3>,
1092 S3_2: Fn(MutMid3) -> Option<MutValue3>,
1093 {
1094 AsyncLockKpThenLockKp {
1095 first: self,
1096 second: lock_kp,
1097 _p: std::marker::PhantomData,
1098 }
1099 }
1100}
1101
1102#[derive(Clone)]
1104pub struct KpThenAsyncKeyPath<
1105 R,
1106 V,
1107 V2,
1108 Root,
1109 Value,
1110 Value2,
1111 MutRoot,
1112 MutValue,
1113 MutValue2,
1114 First,
1115 Second,
1116> {
1117 pub(crate) first: First,
1118 pub(crate) second: Second,
1119 pub(crate) _p:
1120 std::marker::PhantomData<(R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2)>,
1121}
1122
1123impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1124 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1125where
1126 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1127 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1128{
1129 #[inline]
1131 pub async fn get(&self, root: Root) -> Option<Value2> {
1132 let v = self.first.sync_get(root)?;
1133 self.second.get(v).await
1134 }
1135 #[inline]
1137 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1138 let mut_v = self.first.sync_get_mut(root)?;
1139 self.second.get_mut(mut_v).await
1140 }
1141}
1142
1143#[async_trait(?Send)]
1144impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1145 AsyncKeyPathLike<Root, MutRoot>
1146 for KpThenAsyncKeyPath<
1147 R,
1148 V,
1149 V2,
1150 Root,
1151 Value,
1152 Value2,
1153 MutRoot,
1154 MutValue,
1155 MutValue2,
1156 First,
1157 Second,
1158 >
1159where
1160 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1161 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1162{
1163 type Value = Value2;
1164 type MutValue = MutValue2;
1165 async fn get(&self, root: Root) -> Option<Value2> {
1166 let v = self.first.sync_get(root)?;
1167 self.second.get(v).await
1168 }
1169 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1170 let mut_v = self.first.sync_get_mut(root)?;
1171 self.second.get_mut(mut_v).await
1172 }
1173}
1174
1175impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1176 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1177where
1178 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1179 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1180{
1181 pub fn then<V3, Value3, MutValue3, G3, S3>(
1183 self,
1184 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1185 ) -> AsyncKeyPathThenKp<
1186 R,
1187 V3,
1188 Root,
1189 Value3,
1190 MutRoot,
1191 MutValue3,
1192 Self,
1193 crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1194 >
1195 where
1196 V3: 'static,
1197 Value2: std::borrow::Borrow<V2>,
1198 MutValue2: std::borrow::BorrowMut<V2>,
1199 Value3: std::borrow::Borrow<V3>,
1200 MutValue3: std::borrow::BorrowMut<V3>,
1201 G3: Fn(Value2) -> Option<Value3> + Clone,
1202 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1203 {
1204 AsyncKeyPathThenKp {
1205 first: self,
1206 second: next_kp,
1207 _p: std::marker::PhantomData,
1208 }
1209 }
1210}
1211
1212#[derive(Clone)]
1214pub struct AsyncKeyPathThenKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1215 pub(crate) first: First,
1216 pub(crate) second: Second,
1217 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1218}
1219
1220impl<R, V2, Root, Value2, MutRoot, MutValue2, First, RKp, G, S>
1222 AsyncKeyPathThenKp<
1223 R,
1224 V2,
1225 Root,
1226 Value2,
1227 MutRoot,
1228 MutValue2,
1229 First,
1230 crate::Kp<RKp, V2, First::Value, Value2, First::MutValue, MutValue2, G, S>,
1231 >
1232where
1233 First: AsyncKeyPathLike<Root, MutRoot>,
1234 First::Value: std::borrow::Borrow<RKp>,
1235 First::MutValue: std::borrow::BorrowMut<RKp>,
1236 Value2: std::borrow::Borrow<V2>,
1237 MutValue2: std::borrow::BorrowMut<V2>,
1238 G: Fn(First::Value) -> Option<Value2>,
1239 S: Fn(First::MutValue) -> Option<MutValue2>,
1240{
1241 #[inline]
1243 pub async fn get(&self, root: Root) -> Option<Value2> {
1244 let value = self.first.get(root).await?;
1245 (self.second.get)(value)
1246 }
1247 #[inline]
1249 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1250 let mut_value = self.first.get_mut(root).await?;
1251 (self.second.set)(mut_value)
1252 }
1253}
1254
1255#[async_trait(?Send)]
1256impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncKeyPathLike<Root, MutRoot>
1257 for ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1258where
1259 First: AsyncKeyPathLike<Root, MutRoot>,
1260 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1261{
1262 type Value = Value2;
1263 type MutValue = MutValue2;
1264 async fn get(&self, root: Root) -> Option<Value2> {
1265 ComposedAsyncLockKp::get(self, root).await
1266 }
1267 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1268 ComposedAsyncLockKp::get_mut(self, root).await
1269 }
1270}
1271
1272#[derive(Clone)]
1279pub struct AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1280 pub(crate) first: First,
1281 pub(crate) second: Second,
1282 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1283}
1284
1285impl<
1286 R,
1287 V2,
1288 Root,
1289 Value2,
1290 MutRoot,
1291 MutValue2,
1292 Lock,
1293 Mid,
1294 V,
1295 LockValue,
1296 MidValue,
1297 Value,
1298 MutLock,
1299 MutMid,
1300 MutValue,
1301 G1,
1302 S1,
1303 L,
1304 G2,
1305 S2,
1306 Lock2,
1307 Mid2,
1308 LockValue2,
1309 MidValue2,
1310 MutLock2,
1311 MutMid2,
1312 G2_1,
1313 S2_1,
1314 L2,
1315 G2_2,
1316 S2_2,
1317>
1318 AsyncLockKpThenLockKp<
1319 R,
1320 V2,
1321 Root,
1322 Value2,
1323 MutRoot,
1324 MutValue2,
1325 AsyncLockKp<
1326 R,
1327 Lock,
1328 Mid,
1329 V,
1330 Root,
1331 LockValue,
1332 MidValue,
1333 Value,
1334 MutRoot,
1335 MutLock,
1336 MutMid,
1337 MutValue,
1338 G1,
1339 S1,
1340 L,
1341 G2,
1342 S2,
1343 >,
1344 crate::lock::LockKp<
1345 V,
1346 Lock2,
1347 Mid2,
1348 V2,
1349 Value,
1350 LockValue2,
1351 MidValue2,
1352 Value2,
1353 MutValue,
1354 MutLock2,
1355 MutMid2,
1356 MutValue2,
1357 G2_1,
1358 S2_1,
1359 L2,
1360 G2_2,
1361 S2_2,
1362 >,
1363 >
1364where
1365 Root: std::borrow::Borrow<R>,
1366 LockValue: std::borrow::Borrow<Lock>,
1367 MidValue: std::borrow::Borrow<Mid>,
1368 Value: std::borrow::Borrow<V>,
1369 MutRoot: std::borrow::BorrowMut<R>,
1370 MutLock: std::borrow::BorrowMut<Lock>,
1371 MutMid: std::borrow::BorrowMut<Mid>,
1372 MutValue: std::borrow::BorrowMut<V>,
1373 Value2: std::borrow::Borrow<V2>,
1374 MutValue2: std::borrow::BorrowMut<V2>,
1375 G1: Fn(Root) -> Option<LockValue> + Clone,
1376 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
1377 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
1378 G2: Fn(MidValue) -> Option<Value> + Clone,
1379 S2: Fn(MutMid) -> Option<MutValue> + Clone,
1380 LockValue2: std::borrow::Borrow<Lock2>,
1381 MidValue2: std::borrow::Borrow<Mid2>,
1382 MutLock2: std::borrow::BorrowMut<Lock2>,
1383 MutMid2: std::borrow::BorrowMut<Mid2>,
1384 G2_1: Fn(Value) -> Option<LockValue2>,
1385 S2_1: Fn(MutValue) -> Option<MutLock2>,
1386 L2: crate::lock::LockAccess<Lock2, MidValue2> + crate::lock::LockAccess<Lock2, MutMid2>,
1387 G2_2: Fn(MidValue2) -> Option<Value2>,
1388 S2_2: Fn(MutMid2) -> Option<MutValue2>,
1389 Lock: Clone,
1390 V: Clone,
1391 V2: Clone,
1392{
1393 pub async fn get(&self, root: Root) -> Option<Value2> {
1395 let value = self.first.get(root).await?;
1396 self.second.get(value)
1397 }
1398
1399 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1401 let mut_value = self.first.get_mut(root).await?;
1402 self.second.get_mut(mut_value)
1403 }
1404}
1405
1406impl<
1408 R,
1409 V2,
1410 Root,
1411 Value2,
1412 MutRoot,
1413 MutValue2,
1414 Lock3,
1415 Mid3,
1416 LockValue3,
1417 MidValue3,
1418 MutLock3,
1419 MutMid3,
1420 G3_1,
1421 S3_1,
1422 L3,
1423 G3_2,
1424 S3_2,
1425 First,
1426 Second,
1427>
1428 AsyncLockKpThenLockKp<
1429 R,
1430 V2,
1431 Root,
1432 Value2,
1433 MutRoot,
1434 MutValue2,
1435 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>,
1436 crate::lock::LockKp<
1437 Value2,
1438 Lock3,
1439 Mid3,
1440 V2,
1441 Value2,
1442 LockValue3,
1443 MidValue3,
1444 Value2,
1445 MutValue2,
1446 MutLock3,
1447 MutMid3,
1448 MutValue2,
1449 G3_1,
1450 S3_1,
1451 L3,
1452 G3_2,
1453 S3_2,
1454 >,
1455 >
1456where
1457 First: AsyncKeyPathLike<Root, MutRoot>,
1458 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1459 Value2: std::borrow::Borrow<V2>,
1460 MutValue2: std::borrow::BorrowMut<Value2> + std::borrow::BorrowMut<V2>,
1461 LockValue3: std::borrow::Borrow<Lock3>,
1462 MidValue3: std::borrow::Borrow<Mid3>,
1463 MutLock3: std::borrow::BorrowMut<Lock3>,
1464 MutMid3: std::borrow::BorrowMut<Mid3>,
1465 G3_1: Fn(Value2) -> Option<LockValue3>,
1466 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1467 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
1468 G3_2: Fn(MidValue3) -> Option<Value2>,
1469 S3_2: Fn(MutMid3) -> Option<MutValue2>,
1470 Value2: Clone,
1471 V2: Clone,
1472{
1473 pub async fn get(&self, root: Root) -> Option<Value2> {
1475 let value = self.first.get(root).await?;
1476 self.second.get(value)
1477 }
1478 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1480 let mut_value = self.first.get_mut(root).await?;
1481 self.second.get_mut(mut_value)
1482 }
1483}
1484
1485impl<
1487 R,
1488 V2,
1489 Root,
1490 Value2,
1491 MutRoot,
1492 MutValue2,
1493 Lock3,
1494 Mid3,
1495 LockValue3,
1496 MidValue3,
1497 MutLock3,
1498 MutMid3,
1499 G3_1,
1500 S3_1,
1501 L3,
1502 G3_2,
1503 S3_2,
1504 F,
1505 S,
1506>
1507 AsyncLockKpThenLockKp<
1508 R,
1509 V2,
1510 Root,
1511 Value2,
1512 MutRoot,
1513 MutValue2,
1514 AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, F, S>,
1515 crate::lock::LockKp<
1516 Value2,
1517 Lock3,
1518 Mid3,
1519 V2,
1520 Value2,
1521 LockValue3,
1522 MidValue3,
1523 Value2,
1524 MutValue2,
1525 MutLock3,
1526 MutMid3,
1527 MutValue2,
1528 G3_1,
1529 S3_1,
1530 L3,
1531 G3_2,
1532 S3_2,
1533 >,
1534 >
1535where
1536 F: AsyncKeyPathLike<Root, MutRoot, Value = Value2, MutValue = MutValue2>,
1537 S: SyncKeyPathLike<Value2, Value2, MutValue2, MutValue2>,
1538 Value2: std::borrow::Borrow<V2>,
1539 MutValue2: std::borrow::BorrowMut<Value2> + std::borrow::BorrowMut<V2>,
1540 LockValue3: std::borrow::Borrow<Lock3>,
1541 MidValue3: std::borrow::Borrow<Mid3>,
1542 MutLock3: std::borrow::BorrowMut<Lock3>,
1543 MutMid3: std::borrow::BorrowMut<Mid3>,
1544 G3_1: Fn(Value2) -> Option<LockValue3>,
1545 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1546 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
1547 G3_2: Fn(MidValue3) -> Option<Value2>,
1548 S3_2: Fn(MutMid3) -> Option<MutValue2>,
1549 Value2: Clone,
1550 V2: Clone,
1551{
1552 pub async fn get(&self, root: Root) -> Option<Value2> {
1554 let value = AsyncKeyPathLike::get(&self.first, root).await?;
1555 self.second.get(value)
1556 }
1557 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1559 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
1560 self.second.get_mut(mut_value)
1561 }
1562}
1563
1564#[async_trait(?Send)]
1566impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncKeyPathLike<Root, MutRoot>
1567 for AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1568where
1569 First: AsyncKeyPathLike<Root, MutRoot>,
1570 Second: SyncKeyPathLike<First::Value, Value2, First::MutValue, MutValue2>,
1571{
1572 type Value = Value2;
1573 type MutValue = MutValue2;
1574 async fn get(&self, root: Root) -> Option<Value2> {
1575 let value = AsyncKeyPathLike::get(&self.first, root).await?;
1576 SyncKeyPathLike::sync_get(&self.second, value)
1577 }
1578 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1579 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
1580 SyncKeyPathLike::sync_get_mut(&self.second, mut_value)
1581 }
1582}
1583
1584impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1586 AsyncLockKpThenLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1587where
1588 First: AsyncKeyPathLike<Root, MutRoot>,
1589{
1590 pub fn then_async<
1593 Lock3,
1594 Mid3,
1595 V3,
1596 LockValue3,
1597 MidValue3,
1598 Value3,
1599 MutLock3,
1600 MutMid3,
1601 MutValue3,
1602 G3_1,
1603 S3_1,
1604 L3,
1605 G3_2,
1606 S3_2,
1607 >(
1608 self,
1609 other: AsyncLockKp<
1610 Value2,
1611 Lock3,
1612 Mid3,
1613 V3,
1614 Value2,
1615 LockValue3,
1616 MidValue3,
1617 Value3,
1618 MutValue2,
1619 MutLock3,
1620 MutMid3,
1621 MutValue3,
1622 G3_1,
1623 S3_1,
1624 L3,
1625 G3_2,
1626 S3_2,
1627 >,
1628 ) -> ComposedAsyncLockKp<
1629 Root,
1630 V3,
1631 Root,
1632 Value3,
1633 MutRoot,
1634 MutValue3,
1635 Self,
1636 AsyncLockKp<
1637 Value2,
1638 Lock3,
1639 Mid3,
1640 V3,
1641 Value2,
1642 LockValue3,
1643 MidValue3,
1644 Value3,
1645 MutValue2,
1646 MutLock3,
1647 MutMid3,
1648 MutValue3,
1649 G3_1,
1650 S3_1,
1651 L3,
1652 G3_2,
1653 S3_2,
1654 >,
1655 >
1656 where
1657 V2: 'static,
1658 V3: 'static,
1659 Value2: std::borrow::Borrow<V2>,
1660 Value3: std::borrow::Borrow<V3>,
1661 MutValue2: std::borrow::BorrowMut<V2> + std::borrow::BorrowMut<Value2>,
1662 MutValue3: std::borrow::BorrowMut<V3>,
1663 LockValue3: std::borrow::Borrow<Lock3>,
1664 MidValue3: std::borrow::Borrow<Mid3>,
1665 MutLock3: std::borrow::BorrowMut<Lock3>,
1666 MutMid3: std::borrow::BorrowMut<Mid3>,
1667 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
1668 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
1669 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
1670 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
1671 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
1672 Lock3: Clone,
1673 {
1674 ComposedAsyncLockKp {
1675 first: self,
1676 second: other,
1677 _p: std::marker::PhantomData,
1678 }
1679 }
1680
1681 pub fn then_lock<
1683 Lock3,
1684 Mid3,
1685 V3,
1686 LockValue3,
1687 MidValue3,
1688 Value3,
1689 MutLock3,
1690 MutMid3,
1691 MutValue3,
1692 G3_1,
1693 S3_1,
1694 L3,
1695 G3_2,
1696 S3_2,
1697 >(
1698 self,
1699 lock_kp: crate::lock::LockKp<
1700 Value2,
1701 Lock3,
1702 Mid3,
1703 V3,
1704 Value2,
1705 LockValue3,
1706 MidValue3,
1707 Value3,
1708 MutValue2,
1709 MutLock3,
1710 MutMid3,
1711 MutValue3,
1712 G3_1,
1713 S3_1,
1714 L3,
1715 G3_2,
1716 S3_2,
1717 >,
1718 ) -> AsyncLockKpThenLockKp<
1719 R,
1720 V3,
1721 Root,
1722 Value3,
1723 MutRoot,
1724 MutValue3,
1725 Self,
1726 crate::lock::LockKp<
1727 Value2,
1728 Lock3,
1729 Mid3,
1730 V3,
1731 Value2,
1732 LockValue3,
1733 MidValue3,
1734 Value3,
1735 MutValue2,
1736 MutLock3,
1737 MutMid3,
1738 MutValue3,
1739 G3_1,
1740 S3_1,
1741 L3,
1742 G3_2,
1743 S3_2,
1744 >,
1745 >
1746 where
1747 V3: 'static,
1748 Value2: std::borrow::Borrow<V2>,
1749 Value3: std::borrow::Borrow<V3>,
1750 MutValue2: std::borrow::BorrowMut<Value2>,
1751 MutValue3: std::borrow::BorrowMut<V3>,
1752 LockValue3: std::borrow::Borrow<Lock3>,
1753 MidValue3: std::borrow::Borrow<Mid3>,
1754 MutLock3: std::borrow::BorrowMut<Lock3>,
1755 MutMid3: std::borrow::BorrowMut<Mid3>,
1756 G3_1: Fn(Value2) -> Option<LockValue3>,
1757 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1758 L3: crate::lock::LockAccess<Lock3, MidValue3> + crate::lock::LockAccess<Lock3, MutMid3>,
1759 G3_2: Fn(MidValue3) -> Option<Value3>,
1760 S3_2: Fn(MutMid3) -> Option<MutValue3>,
1761 {
1762 AsyncLockKpThenLockKp {
1763 first: self,
1764 second: lock_kp,
1765 _p: std::marker::PhantomData,
1766 }
1767 }
1768
1769 pub fn then<V3, Value3, MutValue3, G3, S3>(
1771 self,
1772 next_kp: crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1773 ) -> AsyncKeyPathThenKp<
1774 R,
1775 V3,
1776 Root,
1777 Value3,
1778 MutRoot,
1779 MutValue3,
1780 Self,
1781 crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1782 >
1783 where
1784 V3: 'static,
1785 Value2: std::borrow::Borrow<V2>,
1786 Value3: std::borrow::Borrow<V3>,
1787 MutValue2: std::borrow::BorrowMut<Value2>,
1788 MutValue3: std::borrow::BorrowMut<V3>,
1789 G3: Fn(Value2) -> Option<Value3> + Clone,
1790 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1791 {
1792 AsyncKeyPathThenKp {
1793 first: self,
1794 second: next_kp,
1795 _p: std::marker::PhantomData,
1796 }
1797 }
1798}
1799
1800#[cfg(feature = "tokio")]
1805#[derive(Clone)] pub struct TokioMutexAccess<T> {
1813 _phantom: std::marker::PhantomData<T>,
1814}
1815
1816#[cfg(feature = "tokio")]
1817impl<T> TokioMutexAccess<T> {
1818 pub fn new() -> Self {
1819 Self {
1820 _phantom: std::marker::PhantomData,
1821 }
1822 }
1823}
1824
1825#[cfg(feature = "tokio")]
1826impl<T> Default for TokioMutexAccess<T> {
1827 fn default() -> Self {
1828 Self::new()
1829 }
1830}
1831
1832#[cfg(feature = "tokio")]
1834#[async_trait]
1835impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::Mutex<T>>, &'a T>
1836 for TokioMutexAccess<T>
1837{
1838 #[inline]
1839 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
1840 let guard = lock.lock().await;
1842 let ptr = &*guard as *const T;
1843 unsafe { Some(&*ptr) }
1844 }
1845
1846 #[inline]
1847 async fn lock_write(&self, lock: &mut std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
1848 let guard = lock.lock().await;
1849 let ptr = &*guard as *const T;
1850 unsafe { Some(&*ptr) }
1851 }
1852}
1853
1854#[cfg(feature = "tokio")]
1856#[async_trait]
1857impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::Mutex<T>>, &'a mut T>
1858 for TokioMutexAccess<T>
1859{
1860 #[inline]
1861 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a mut T> {
1862 let mut guard = lock.lock().await;
1864 let ptr = &mut *guard as *mut T;
1865 unsafe { Some(&mut *ptr) }
1866 }
1867
1868 #[inline]
1869 async fn lock_write(&self, lock: &mut std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a mut T> {
1870 let mut guard = lock.lock().await;
1871 let ptr = &mut *guard as *mut T;
1872 unsafe { Some(&mut *ptr) }
1873 }
1874}
1875
1876#[cfg(feature = "tokio")]
1881pub struct TokioRwLockAccess<T> {
1889 _phantom: std::marker::PhantomData<T>,
1890}
1891
1892#[cfg(feature = "tokio")]
1893impl<T> TokioRwLockAccess<T> {
1894 pub fn new() -> Self {
1895 Self {
1896 _phantom: std::marker::PhantomData,
1897 }
1898 }
1899}
1900
1901#[cfg(feature = "tokio")]
1902impl<T> Default for TokioRwLockAccess<T> {
1903 fn default() -> Self {
1904 Self::new()
1905 }
1906}
1907
1908#[cfg(feature = "tokio")]
1909impl<T> Clone for TokioRwLockAccess<T> {
1910 fn clone(&self) -> Self {
1911 Self {
1912 _phantom: self._phantom,
1913 }
1914 }
1915}
1916
1917#[cfg(feature = "tokio")]
1919#[async_trait]
1920impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::RwLock<T>>, &'a T>
1921 for TokioRwLockAccess<T>
1922{
1923 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
1924 let guard = lock.read().await;
1926 let ptr = &*guard as *const T;
1927 unsafe { Some(&*ptr) }
1928 }
1929
1930 async fn lock_write(&self, lock: &mut std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
1931 let guard = lock.read().await;
1933 let ptr = &*guard as *const T;
1934 unsafe { Some(&*ptr) }
1935 }
1936}
1937
1938#[cfg(feature = "tokio")]
1940#[async_trait]
1941impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::RwLock<T>>, &'a mut T>
1942 for TokioRwLockAccess<T>
1943{
1944 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a mut T> {
1945 let mut guard = lock.write().await;
1947 let ptr = &mut *guard as *mut T;
1948 unsafe { Some(&mut *ptr) }
1949 }
1950
1951 async fn lock_write(&self, lock: &mut std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a mut T> {
1952 let mut guard = lock.write().await;
1954 let ptr = &mut *guard as *mut T;
1955 unsafe { Some(&mut *ptr) }
1956 }
1957}
1958
1959#[cfg(feature = "tokio")]
1967pub type AsyncLockKpMutexFor<Root, Lock, Inner> = AsyncLockKp<
1969 Root,
1970 Lock,
1971 Inner,
1972 Inner,
1973 &'static Root,
1974 &'static Lock,
1975 &'static Inner,
1976 &'static Inner,
1977 &'static mut Root,
1978 &'static mut Lock,
1979 &'static mut Inner,
1980 &'static mut Inner,
1981 for<'b> fn(&'b Root) -> Option<&'b Lock>,
1982 for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1983 TokioMutexAccess<Inner>,
1984 for<'b> fn(&'b Inner) -> Option<&'b Inner>,
1985 for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
1986>;
1987
1988#[cfg(feature = "tokio")]
1989pub type AsyncLockKpRwLockFor<Root, Lock, Inner> = AsyncLockKp<
1991 Root,
1992 Lock,
1993 Inner,
1994 Inner,
1995 &'static Root,
1996 &'static Lock,
1997 &'static Inner,
1998 &'static Inner,
1999 &'static mut Root,
2000 &'static mut Lock,
2001 &'static mut Inner,
2002 &'static mut Inner,
2003 for<'b> fn(&'b Root) -> Option<&'b Lock>,
2004 for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
2005 TokioRwLockAccess<Inner>,
2006 for<'b> fn(&'b Inner) -> Option<&'b Inner>,
2007 for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
2008>;
2009
2010#[cfg(all(test, feature = "tokio"))]
2015mod tests {
2016 use super::*;
2017 use crate::KpType;
2018
2019 #[tokio::test]
2020 async fn test_async_lock_kp_tokio_mutex_basic() {
2021 use tokio::sync::Mutex;
2022
2023 #[derive(Clone)]
2024 struct Root {
2025 data: std::sync::Arc<Mutex<String>>,
2026 }
2027
2028 let root = Root {
2029 data: std::sync::Arc::new(Mutex::new("hello".to_string())),
2030 };
2031
2032 let lock_kp = {
2034 let prev: KpType<Root, std::sync::Arc<Mutex<String>>> =
2035 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2036 let next: KpType<String, String> =
2037 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
2038 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2039 };
2040
2041 let value = lock_kp.get(&root).await;
2043 assert!(value.is_some());
2044 assert_eq!(value.unwrap(), &"hello".to_string());
2045 }
2046
2047 #[tokio::test]
2048 async fn test_async_lock_kp_get_optional_or_else() {
2049 use tokio::sync::Mutex;
2050
2051 #[derive(Clone)]
2052 struct Root {
2053 data: std::sync::Arc<Mutex<i32>>,
2054 }
2055
2056 let mut root = Root {
2057 data: std::sync::Arc::new(Mutex::new(42)),
2058 };
2059
2060 let lock_kp = {
2061 let prev: KpType<Root, std::sync::Arc<Mutex<i32>>> =
2062 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2063 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2064 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2065 };
2066
2067 assert!(lock_kp.get_optional(None).await.is_none());
2069 assert_eq!(lock_kp.get_optional(Some(&root)).await, Some(&42));
2070
2071 assert!(lock_kp.get_mut_optional(None).await.is_none());
2073 if let Some(m) = lock_kp.get_mut_optional(Some(&mut root)).await {
2074 *m = 99;
2075 }
2076 assert_eq!(lock_kp.get(&root).await, Some(&99));
2077
2078 assert_eq!(*lock_kp.get_or_else(None, || &0).await, 0);
2080 assert_eq!(*lock_kp.get_or_else(Some(&root), || &0).await, 99);
2081
2082 let m = lock_kp
2084 .get_mut_or_else(Some(&mut root), || panic!("unexpected"))
2085 .await;
2086 *m = 100;
2087 assert_eq!(lock_kp.get(&root).await, Some(&100));
2088 }
2089
2090 #[tokio::test]
2091 async fn test_async_lock_kp_tokio_rwlock_basic() {
2092 use tokio::sync::RwLock;
2093
2094 #[derive(Clone)]
2095 struct Root {
2096 data: std::sync::Arc<RwLock<Vec<i32>>>,
2097 }
2098
2099 let root = Root {
2100 data: std::sync::Arc::new(RwLock::new(vec![1, 2, 3, 4, 5])),
2101 };
2102
2103 let lock_kp = {
2105 let prev: KpType<Root, std::sync::Arc<RwLock<Vec<i32>>>> =
2106 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2107 let next: KpType<Vec<i32>, Vec<i32>> =
2108 Kp::new(|v: &Vec<i32>| Some(v), |v: &mut Vec<i32>| Some(v));
2109 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
2110 };
2111
2112 let value = lock_kp.get(&root).await;
2114 assert!(value.is_some());
2115 assert_eq!(value.unwrap().len(), 5);
2116 }
2117
2118 #[tokio::test]
2119 async fn test_async_lock_kp_concurrent_reads() {
2120 use tokio::sync::RwLock;
2121
2122 #[derive(Clone)]
2123 struct Root {
2124 data: std::sync::Arc<RwLock<i32>>,
2125 }
2126
2127 let root = Root {
2128 data: std::sync::Arc::new(RwLock::new(42)),
2129 };
2130
2131 let lock_kp = {
2133 let prev: KpType<Root, std::sync::Arc<RwLock<i32>>> =
2134 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2135 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2136 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
2137 };
2138
2139 let lock_kp2 = {
2142 let prev: KpType<Root, std::sync::Arc<RwLock<i32>>> =
2143 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2144 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2145 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
2146 };
2147 let (a, b) = tokio::join!(lock_kp.get(&root), lock_kp2.get(&root));
2148 assert_eq!(a, Some(&42));
2149 assert_eq!(b, Some(&42));
2150
2151 let value = lock_kp.get(&root).await;
2153 assert_eq!(value, Some(&42));
2154 }
2155
2156 #[tokio::test]
2157 async fn test_async_lock_kp_panic_on_clone_proof() {
2158 use tokio::sync::Mutex;
2159
2160 struct PanicOnClone {
2162 data: String,
2163 }
2164
2165 impl Clone for PanicOnClone {
2166 fn clone(&self) -> Self {
2167 panic!("❌ ASYNC DEEP CLONE DETECTED! PanicOnClone was cloned!");
2168 }
2169 }
2170
2171 #[derive(Clone)]
2172 struct Root {
2173 level1: std::sync::Arc<Mutex<Level1>>,
2174 }
2175
2176 struct Level1 {
2177 panic_data: PanicOnClone,
2178 value: i32,
2179 }
2180
2181 impl Clone for Level1 {
2182 fn clone(&self) -> Self {
2183 panic!("❌ Level1 was deeply cloned in async context!");
2184 }
2185 }
2186
2187 let root = Root {
2189 level1: std::sync::Arc::new(Mutex::new(Level1 {
2190 panic_data: PanicOnClone {
2191 data: "test".to_string(),
2192 },
2193 value: 123,
2194 })),
2195 };
2196
2197 let lock_kp = {
2199 let prev: KpType<Root, std::sync::Arc<Mutex<Level1>>> = Kp::new(
2200 |r: &Root| Some(&r.level1),
2201 |r: &mut Root| Some(&mut r.level1),
2202 );
2203 let next: KpType<Level1, i32> = Kp::new(
2204 |l: &Level1| Some(&l.value),
2205 |l: &mut Level1| Some(&mut l.value),
2206 );
2207 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2208 };
2209
2210 let value = lock_kp.get(&root).await;
2212
2213 assert_eq!(value, Some(&123));
2215 }
2216
2217 #[tokio::test]
2218 async fn test_async_lock_kp_structure() {
2219 use tokio::sync::Mutex;
2220
2221 #[derive(Clone)]
2222 struct Root {
2223 data: std::sync::Arc<Mutex<String>>,
2224 }
2225
2226 let lock_kp = {
2227 let prev: KpType<Root, std::sync::Arc<Mutex<String>>> =
2228 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2229 let next: KpType<String, String> =
2230 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
2231 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2232 };
2233
2234 let _ = &lock_kp.prev;
2236 let _ = &lock_kp.mid;
2237 let _ = &lock_kp.next;
2238 }
2239
2240 #[tokio::test]
2241 async fn test_async_kp_then() {
2242 use tokio::sync::Mutex;
2243
2244 #[derive(Clone)]
2245 struct Root {
2246 data: std::sync::Arc<Mutex<Inner>>,
2247 }
2248
2249 #[derive(Clone)]
2250 struct Inner {
2251 value: i32,
2252 }
2253
2254 let root = Root {
2255 data: std::sync::Arc::new(Mutex::new(Inner { value: 42 })),
2256 };
2257
2258 let async_kp = {
2260 let prev: KpType<Root, std::sync::Arc<Mutex<Inner>>> =
2261 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2262 let next: KpType<Inner, Inner> = Kp::new(|i: &Inner| Some(i), |i: &mut Inner| Some(i));
2263 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2264 };
2265
2266 let value_kp: KpType<Inner, i32> = Kp::new(
2268 |i: &Inner| Some(&i.value),
2269 |i: &mut Inner| Some(&mut i.value),
2270 );
2271
2272 let chained = async_kp.then(value_kp);
2273 let result = chained.get(&root).await;
2274 assert_eq!(result, Some(&42));
2275 }
2276
2277 #[tokio::test]
2278 async fn test_async_kp_later_then() {
2279 use tokio::sync::Mutex;
2280
2281 #[derive(Clone)]
2282 struct Root {
2283 lock1: std::sync::Arc<Mutex<Container>>,
2284 }
2285
2286 #[derive(Clone)]
2287 struct Container {
2288 lock2: std::sync::Arc<Mutex<i32>>,
2289 }
2290
2291 let root = Root {
2292 lock1: std::sync::Arc::new(Mutex::new(Container {
2293 lock2: std::sync::Arc::new(Mutex::new(999)),
2294 })),
2295 };
2296
2297 let async_kp1 = {
2299 let prev: KpType<Root, std::sync::Arc<Mutex<Container>>> =
2300 Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
2301 let next: KpType<Container, Container> =
2302 Kp::new(|c: &Container| Some(c), |c: &mut Container| Some(c));
2303 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2304 };
2305
2306 let async_kp2 = {
2308 let prev: KpType<Container, std::sync::Arc<Mutex<i32>>> = Kp::new(
2309 |c: &Container| Some(&c.lock2),
2310 |c: &mut Container| Some(&mut c.lock2),
2311 );
2312 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2313 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2314 };
2315
2316 let chained = async_kp1.then_async(async_kp2);
2318 let result = chained.get(&root).await;
2319 assert_eq!(result, Some(&999));
2320 }
2321
2322 #[tokio::test]
2323 async fn test_async_kp_then_async_three_levels() {
2324 use tokio::sync::Mutex;
2325
2326 #[derive(Clone)]
2327 struct Root {
2328 a: std::sync::Arc<Mutex<Level1>>,
2329 }
2330 #[derive(Clone)]
2331 struct Level1 {
2332 b: std::sync::Arc<Mutex<Level2>>,
2333 }
2334 #[derive(Clone)]
2335 struct Level2 {
2336 c: std::sync::Arc<Mutex<i32>>,
2337 }
2338
2339 let root = Root {
2340 a: std::sync::Arc::new(Mutex::new(Level1 {
2341 b: std::sync::Arc::new(Mutex::new(Level2 {
2342 c: std::sync::Arc::new(Mutex::new(42)),
2343 })),
2344 })),
2345 };
2346
2347 let kp1 = {
2348 let prev: KpType<Root, std::sync::Arc<Mutex<Level1>>> =
2349 Kp::new(|r: &Root| Some(&r.a), |r: &mut Root| Some(&mut r.a));
2350 let next: KpType<Level1, Level1> =
2351 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
2352 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2353 };
2354 let kp2 = {
2355 let prev: KpType<Level1, std::sync::Arc<Mutex<Level2>>> =
2356 Kp::new(|l: &Level1| Some(&l.b), |l: &mut Level1| Some(&mut l.b));
2357 let next: KpType<Level2, Level2> =
2358 Kp::new(|l: &Level2| Some(l), |l: &mut Level2| Some(l));
2359 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2360 };
2361 let kp3 = {
2362 let prev: KpType<Level2, std::sync::Arc<Mutex<i32>>> =
2363 Kp::new(|l: &Level2| Some(&l.c), |l: &mut Level2| Some(&mut l.c));
2364 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2365 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2366 };
2367
2368 let chained = kp1.then_async(kp2).then_async(kp3);
2369 let result = chained.get(&root).await;
2370 assert_eq!(result, Some(&42));
2371 }
2372}