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