1use crate::Kp;
33use async_trait::async_trait;
34use std::fmt;
35#[cfg(feature = "tokio")]
37pub use tokio::sync::{Mutex as TokioMutex, RwLock as TokioRwLock};
38
39#[async_trait]
57pub trait AsyncLockLike<Lock, Inner>: Send + Sync {
58 async fn lock_read(&self, lock: &Lock) -> Option<Inner>;
60
61 async fn lock_write(&self, lock: &mut Lock) -> Option<Inner>;
63}
64
65pub trait SyncKeyPathLike<Root, Value, MutRoot, MutValue> {
68 fn sync_get(&self, root: Root) -> Option<Value>;
99
100 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue>;
131}
132
133impl<R, V, Root, Value, MutRoot, MutValue, G, S> SyncKeyPathLike<Root, Value, MutRoot, MutValue>
134 for crate::Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
135where
136 Root: std::borrow::Borrow<R>,
137 Value: std::borrow::Borrow<V>,
138 MutRoot: std::borrow::BorrowMut<R>,
139 MutValue: std::borrow::BorrowMut<V>,
140 G: Fn(Root) -> Option<Value>,
141 S: Fn(MutRoot) -> Option<MutValue>,
142 {
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.set)(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::sync_kp::SyncKp<
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::sync_kp::LockAccess<Lock, MidValue> + crate::sync_kp::LockAccess<Lock, MutMid>,
202 G2: Fn(MidValue) -> Option<Value>,
203 S2: Fn(MutMid) -> Option<MutValue>,
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<
268 R,
269 Lock,
270 Mid,
271 V,
272 Root,
273 LockValue,
274 MidValue,
275 Value,
276 MutRoot,
277 MutLock,
278 MutMid,
279 MutValue,
280 G1,
281 S1,
282 L,
283 G2,
284 S2,
285> where
286 Root: std::borrow::Borrow<R>,
287 LockValue: std::borrow::Borrow<Lock>,
288 MidValue: std::borrow::Borrow<Mid>,
289 Value: std::borrow::Borrow<V>,
290 MutRoot: std::borrow::BorrowMut<R>,
291 MutLock: std::borrow::BorrowMut<Lock>,
292 MutMid: std::borrow::BorrowMut<Mid>,
293 MutValue: std::borrow::BorrowMut<V>,
294 G1: Fn(Root) -> Option<LockValue> + Clone,
295 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
296 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
297 G2: Fn(MidValue) -> Option<Value> + Clone,
298 S2: Fn(MutMid) -> Option<MutValue> + Clone,
299{
300 prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
302
303 mid: L,
305
306 next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
308}
309
310impl<
311 R,
312 Lock,
313 Mid,
314 V,
315 Root,
316 LockValue,
317 MidValue,
318 Value,
319 MutRoot,
320 MutLock,
321 MutMid,
322 MutValue,
323 G1,
324 S1,
325 L,
326 G2,
327 S2,
328> fmt::Debug
329 for AsyncLockKp<
330 R,
331 Lock,
332 Mid,
333 V,
334 Root,
335 LockValue,
336 MidValue,
337 Value,
338 MutRoot,
339 MutLock,
340 MutMid,
341 MutValue,
342 G1,
343 S1,
344 L,
345 G2,
346 S2,
347 >
348where
349 Root: std::borrow::Borrow<R>,
350 LockValue: std::borrow::Borrow<Lock>,
351 MidValue: std::borrow::Borrow<Mid>,
352 Value: std::borrow::Borrow<V>,
353 MutRoot: std::borrow::BorrowMut<R>,
354 MutLock: std::borrow::BorrowMut<Lock>,
355 MutMid: std::borrow::BorrowMut<Mid>,
356 MutValue: std::borrow::BorrowMut<V>,
357 G1: Fn(Root) -> Option<LockValue> + Clone,
358 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
359 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
360 G2: Fn(MidValue) -> Option<Value> + Clone,
361 S2: Fn(MutMid) -> Option<MutValue> + Clone,
362{
363 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
364 f.debug_struct("AsyncLockKp")
365 .field("root_ty", &std::any::type_name::<R>())
366 .field("lock_ty", &std::any::type_name::<Lock>())
367 .field("mid_ty", &std::any::type_name::<Mid>())
368 .field("value_ty", &std::any::type_name::<V>())
369 .finish_non_exhaustive()
370 }
371}
372
373impl<
374 R,
375 Lock,
376 Mid,
377 V,
378 Root,
379 LockValue,
380 MidValue,
381 Value,
382 MutRoot,
383 MutLock,
384 MutMid,
385 MutValue,
386 G1,
387 S1,
388 L,
389 G2,
390 S2,
391> fmt::Display
392 for AsyncLockKp<
393 R,
394 Lock,
395 Mid,
396 V,
397 Root,
398 LockValue,
399 MidValue,
400 Value,
401 MutRoot,
402 MutLock,
403 MutMid,
404 MutValue,
405 G1,
406 S1,
407 L,
408 G2,
409 S2,
410 >
411where
412 Root: std::borrow::Borrow<R>,
413 LockValue: std::borrow::Borrow<Lock>,
414 MidValue: std::borrow::Borrow<Mid>,
415 Value: std::borrow::Borrow<V>,
416 MutRoot: std::borrow::BorrowMut<R>,
417 MutLock: std::borrow::BorrowMut<Lock>,
418 MutMid: std::borrow::BorrowMut<Mid>,
419 MutValue: std::borrow::BorrowMut<V>,
420 G1: Fn(Root) -> Option<LockValue> + Clone,
421 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
422 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
423 G2: Fn(MidValue) -> Option<Value> + Clone,
424 S2: Fn(MutMid) -> Option<MutValue> + Clone,
425{
426 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
427 write!(
428 f,
429 "AsyncLockKp<{}, {}, {}, {}>",
430 std::any::type_name::<R>(),
431 std::any::type_name::<Lock>(),
432 std::any::type_name::<Mid>(),
433 std::any::type_name::<V>()
434 )
435 }
436}
437
438impl<
439 R,
440 Lock,
441 Mid,
442 V,
443 Root,
444 LockValue,
445 MidValue,
446 Value,
447 MutRoot,
448 MutLock,
449 MutMid,
450 MutValue,
451 G1,
452 S1,
453 L,
454 G2,
455 S2,
456>
457 AsyncLockKp<
458 R,
459 Lock,
460 Mid,
461 V,
462 Root,
463 LockValue,
464 MidValue,
465 Value,
466 MutRoot,
467 MutLock,
468 MutMid,
469 MutValue,
470 G1,
471 S1,
472 L,
473 G2,
474 S2,
475 >
476where
477 Root: std::borrow::Borrow<R>,
478 LockValue: std::borrow::Borrow<Lock>,
479 MidValue: std::borrow::Borrow<Mid>,
480 Value: std::borrow::Borrow<V>,
481 MutRoot: std::borrow::BorrowMut<R>,
482 MutLock: std::borrow::BorrowMut<Lock>,
483 MutMid: std::borrow::BorrowMut<Mid>,
484 MutValue: std::borrow::BorrowMut<V>,
485 G1: Fn(Root) -> Option<LockValue> + Clone,
486 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
487 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
488 G2: Fn(MidValue) -> Option<Value> + Clone,
489 S2: Fn(MutMid) -> Option<MutValue> + Clone,
490{
491 pub fn new(
493 prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
494 mid: L,
495 next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
496 ) -> Self {
497 Self { prev, mid, next }
498 }
499
500 #[inline]
514 pub async fn get(&self, root: Root) -> Option<Value>
515 where
516 Lock: Clone,
517 {
518 let lock_value = (self.prev.get)(root)?;
521 let lock: &Lock = lock_value.borrow();
522 let lock_clone = lock.clone(); let mid_value = self.mid.lock_read(&lock_clone).await?;
526
527 (self.next.get)(mid_value)
529 }
530
531 #[inline]
533 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue>
534 where
535 Lock: Clone,
536 {
537 let mut lock_value = (self.prev.set)(root)?;
539 let lock: &mut Lock = lock_value.borrow_mut();
540 let mut lock_clone = lock.clone(); let mid_value = self.mid.lock_write(&mut lock_clone).await?;
544
545 (self.next.set)(mid_value)
547 }
548
549 #[inline]
551 pub async fn get_optional(&self, root: Option<Root>) -> Option<Value>
552 where
553 Lock: Clone,
554 {
555 match root {
556 Some(r) => self.get(r).await,
557 None => None,
558 }
559 }
560
561 #[inline]
563 pub async fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue>
564 where
565 Lock: Clone,
566 {
567 match root {
568 Some(r) => self.get_mut(r).await,
569 None => None,
570 }
571 }
572
573 #[inline]
575 pub async fn get_or_else<F>(&self, root: Option<Root>, f: F) -> Value
576 where
577 Lock: Clone,
578 F: FnOnce() -> Value,
579 {
580 self.get_optional(root).await.unwrap_or_else(f)
581 }
582
583 #[inline]
585 pub async fn get_mut_or_else<F>(&self, root: Option<MutRoot>, f: F) -> MutValue
586 where
587 Lock: Clone,
588 F: FnOnce() -> MutValue,
589 {
590 self.get_mut_optional(root).await.unwrap_or_else(f)
591 }
592
593 pub async fn set<F>(&self, root: Root, updater: F) -> Result<(), String>
600 where
601 Lock: Clone,
602 F: FnOnce(&mut V),
603 {
604 let lock_value = (self.prev.get)(root).ok_or("Failed to get lock from root")?;
606 let lock: &Lock = lock_value.borrow();
607 let lock_clone = lock.clone(); let mid_value = self
611 .mid
612 .lock_read(&lock_clone)
613 .await
614 .ok_or("Failed to lock")?;
615
616 let mut mut_value = (self.next.set)(mid_value).ok_or("Failed to navigate to value")?;
618 let v: &mut V = mut_value.borrow_mut();
619
620 updater(v);
622
623 Ok(())
624 }
625
626 pub fn then<V2, Value2, MutValue2, G3, S3>(
642 self,
643 next_kp: crate::Kp<V, V2, Value, Value2, MutValue, MutValue2, G3, S3>,
644 ) -> AsyncLockKp<
645 R,
646 Lock,
647 Mid,
648 V2,
649 Root,
650 LockValue,
651 MidValue,
652 Value2,
653 MutRoot,
654 MutLock,
655 MutMid,
656 MutValue2,
657 G1,
658 S1,
659 L,
660 impl Fn(MidValue) -> Option<Value2>
661 + Clone
662 + use<
663 G1,
664 G2,
665 G3,
666 L,
667 Lock,
668 LockValue,
669 Mid,
670 MidValue,
671 MutLock,
672 MutMid,
673 MutRoot,
674 MutValue,
675 MutValue2,
676 R,
677 Root,
678 S1,
679 S2,
680 S3,
681 Value,
682 Value2,
683 V,
684 V2,
685 >,
686 impl Fn(MutMid) -> Option<MutValue2>
687 + Clone
688 + use<
689 G1,
690 G2,
691 G3,
692 L,
693 Lock,
694 LockValue,
695 Mid,
696 MidValue,
697 MutLock,
698 MutMid,
699 MutRoot,
700 MutValue,
701 MutValue2,
702 R,
703 Root,
704 S1,
705 S2,
706 S3,
707 Value,
708 Value2,
709 V,
710 V2,
711 >,
712 >
713 where
714 V: 'static,
715 V2: 'static,
716 Value: std::borrow::Borrow<V>,
717 Value2: std::borrow::Borrow<V2>,
718 MutValue: std::borrow::BorrowMut<V>,
719 MutValue2: std::borrow::BorrowMut<V2>,
720 G3: Fn(Value) -> Option<Value2> + Clone,
721 S3: Fn(MutValue) -> Option<MutValue2> + Clone,
722 {
723 let next_get = self.next.get;
724 let next_set = self.next.set;
725 let second_get = next_kp.get;
726 let second_set = next_kp.set;
727 let chained_kp = crate::Kp::new(
728 move |mid_value: MidValue| next_get(mid_value).and_then(|v| second_get(v)),
729 move |mid_value: MutMid| next_set(mid_value).and_then(|v| second_set(v)),
730 );
731 AsyncLockKp::new(self.prev, self.mid, chained_kp)
732 }
733
734 pub fn then_sync<
737 Lock2,
738 Mid2,
739 V2,
740 LockValue2,
741 MidValue2,
742 Value2,
743 MutLock2,
744 MutMid2,
745 MutValue2,
746 G2_1,
747 S2_1,
748 L2,
749 G2_2,
750 S2_2,
751 >(
752 self,
753 lock_kp: crate::sync_kp::SyncKp<
754 V,
755 Lock2,
756 Mid2,
757 V2,
758 Value,
759 LockValue2,
760 MidValue2,
761 Value2,
762 MutValue,
763 MutLock2,
764 MutMid2,
765 MutValue2,
766 G2_1,
767 S2_1,
768 L2,
769 G2_2,
770 S2_2,
771 >,
772 ) -> AsyncLockKpThenSyncKp<
773 R,
774 V2,
775 Root,
776 Value2,
777 MutRoot,
778 MutValue2,
779 Self,
780 crate::sync_kp::SyncKp<
781 V,
782 Lock2,
783 Mid2,
784 V2,
785 Value,
786 LockValue2,
787 MidValue2,
788 Value2,
789 MutValue,
790 MutLock2,
791 MutMid2,
792 MutValue2,
793 G2_1,
794 S2_1,
795 L2,
796 G2_2,
797 S2_2,
798 >,
799 >
800 where
801 V: 'static,
802 V2: 'static,
803 Value: std::borrow::Borrow<V>,
804 Value2: std::borrow::Borrow<V2>,
805 MutValue: std::borrow::BorrowMut<V>,
806 MutValue2: std::borrow::BorrowMut<V2>,
807 LockValue2: std::borrow::Borrow<Lock2>,
808 MidValue2: std::borrow::Borrow<Mid2>,
809 MutLock2: std::borrow::BorrowMut<Lock2>,
810 MutMid2: std::borrow::BorrowMut<Mid2>,
811 G2_1: Fn(Value) -> Option<LockValue2>,
812 S2_1: Fn(MutValue) -> Option<MutLock2>,
813 L2: crate::sync_kp::LockAccess<Lock2, MidValue2> + crate::sync_kp::LockAccess<Lock2, MutMid2>,
814 G2_2: Fn(MidValue2) -> Option<Value2>,
815 S2_2: Fn(MutMid2) -> Option<MutValue2>,
816 {
817 let first = self;
818 let second = lock_kp;
819
820 AsyncLockKpThenSyncKp {
821 first: first,
822 second: second,
823 _p: std::marker::PhantomData,
824 }
825 }
826
827 pub fn then_async<
843 Lock2,
844 Mid2,
845 V2,
846 LockValue2,
847 MidValue2,
848 Value2,
849 MutLock2,
850 MutMid2,
851 MutValue2,
852 G2_1,
853 S2_1,
854 L2,
855 G2_2,
856 S2_2,
857 >(
858 self,
859 other: AsyncLockKp<
860 V,
861 Lock2,
862 Mid2,
863 V2,
864 Value,
865 LockValue2,
866 MidValue2,
867 Value2,
868 MutValue,
869 MutLock2,
870 MutMid2,
871 MutValue2,
872 G2_1,
873 S2_1,
874 L2,
875 G2_2,
876 S2_2,
877 >,
878 ) -> ComposedAsyncLockKp<
879 R,
880 V2,
881 Root,
882 Value2,
883 MutRoot,
884 MutValue2,
885 Self,
886 AsyncLockKp<
887 V,
888 Lock2,
889 Mid2,
890 V2,
891 Value,
892 LockValue2,
893 MidValue2,
894 Value2,
895 MutValue,
896 MutLock2,
897 MutMid2,
898 MutValue2,
899 G2_1,
900 S2_1,
901 L2,
902 G2_2,
903 S2_2,
904 >,
905 >
906 where
907 Lock: Clone,
908 Lock2: Clone,
909 V: 'static,
910 V2: 'static,
911 Value: std::borrow::Borrow<V>,
912 LockValue2: std::borrow::Borrow<Lock2>,
913 MidValue2: std::borrow::Borrow<Mid2>,
914 Value2: std::borrow::Borrow<V2>,
915 MutValue: std::borrow::BorrowMut<V>,
916 MutLock2: std::borrow::BorrowMut<Lock2>,
917 MutMid2: std::borrow::BorrowMut<Mid2>,
918 MutValue2: std::borrow::BorrowMut<V2>,
919 G2_1: Fn(Value) -> Option<LockValue2> + Clone,
920 S2_1: Fn(MutValue) -> Option<MutLock2> + Clone,
921 L2: AsyncLockLike<Lock2, MidValue2> + AsyncLockLike<Lock2, MutMid2> + Clone,
922 G2_2: Fn(MidValue2) -> Option<Value2> + Clone,
923 S2_2: Fn(MutMid2) -> Option<MutValue2> + Clone,
924 {
925 let first = self;
926 let second = other;
927
928 ComposedAsyncLockKp {
929 first: first,
930 second: second,
931 _p: std::marker::PhantomData,
932 }
933 }
934}
935
936#[async_trait(?Send)]
938impl<
939 R,
940 Lock,
941 Mid,
942 V,
943 Root,
944 LockValue,
945 MidValue,
946 Value,
947 MutRoot,
948 MutLock,
949 MutMid,
950 MutValue,
951 G1,
952 S1,
953 L,
954 G2,
955 S2,
956> AsyncKeyPathLike<Root, MutRoot>
957 for AsyncLockKp<
958 R,
959 Lock,
960 Mid,
961 V,
962 Root,
963 LockValue,
964 MidValue,
965 Value,
966 MutRoot,
967 MutLock,
968 MutMid,
969 MutValue,
970 G1,
971 S1,
972 L,
973 G2,
974 S2,
975 >
976where
977 Root: std::borrow::Borrow<R>,
978 LockValue: std::borrow::Borrow<Lock>,
979 MidValue: std::borrow::Borrow<Mid>,
980 Value: std::borrow::Borrow<V>,
981 MutRoot: std::borrow::BorrowMut<R>,
982 MutLock: std::borrow::BorrowMut<Lock>,
983 MutMid: std::borrow::BorrowMut<Mid>,
984 MutValue: std::borrow::BorrowMut<V>,
985 G1: Fn(Root) -> Option<LockValue> + Clone,
986 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
987 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
988 G2: Fn(MidValue) -> Option<Value> + Clone,
989 S2: Fn(MutMid) -> Option<MutValue> + Clone,
990 Lock: Clone,
991{
992 type Value = Value;
993 type MutValue = MutValue;
994 async fn get(&self, root: Root) -> Option<Value> {
995 AsyncLockKp::get(self, root).await
996 }
997 async fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
998 AsyncLockKp::get_mut(self, root).await
999 }
1000}
1001
1002#[derive(Clone)]
1009pub struct ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1010 first: First,
1011 second: Second,
1012 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1013}
1014
1015impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1016 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1017where
1018 First: AsyncKeyPathLike<Root, MutRoot>,
1019 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1020{
1021 pub async fn get(&self, root: Root) -> Option<Value2> {
1023 let value = self.first.get(root).await?;
1024 self.second.get(value).await
1025 }
1026
1027 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1029 let mut_value = self.first.get_mut(root).await?;
1030 self.second.get_mut(mut_value).await
1031 }
1032
1033 pub fn then_async<
1035 Lock3,
1036 Mid3,
1037 V3,
1038 LockValue3,
1039 MidValue3,
1040 Value3,
1041 MutLock3,
1042 MutMid3,
1043 MutValue3,
1044 G3_1,
1045 S3_1,
1046 L3,
1047 G3_2,
1048 S3_2,
1049 >(
1050 self,
1051 other: AsyncLockKp<
1052 V2,
1053 Lock3,
1054 Mid3,
1055 V3,
1056 Value2,
1057 LockValue3,
1058 MidValue3,
1059 Value3,
1060 MutValue2,
1061 MutLock3,
1062 MutMid3,
1063 MutValue3,
1064 G3_1,
1065 S3_1,
1066 L3,
1067 G3_2,
1068 S3_2,
1069 >,
1070 ) -> ComposedAsyncLockKp<
1071 R,
1072 V3,
1073 Root,
1074 Value3,
1075 MutRoot,
1076 MutValue3,
1077 Self,
1078 AsyncLockKp<
1079 V2,
1080 Lock3,
1081 Mid3,
1082 V3,
1083 Value2,
1084 LockValue3,
1085 MidValue3,
1086 Value3,
1087 MutValue2,
1088 MutLock3,
1089 MutMid3,
1090 MutValue3,
1091 G3_1,
1092 S3_1,
1093 L3,
1094 G3_2,
1095 S3_2,
1096 >,
1097 >
1098 where
1099 V2: 'static,
1100 V3: 'static,
1101 Value2: std::borrow::Borrow<V2>,
1102 Value3: std::borrow::Borrow<V3>,
1103 MutValue2: std::borrow::BorrowMut<V2>,
1104 MutValue3: std::borrow::BorrowMut<V3>,
1105 LockValue3: std::borrow::Borrow<Lock3>,
1106 MidValue3: std::borrow::Borrow<Mid3>,
1107 MutLock3: std::borrow::BorrowMut<Lock3>,
1108 MutMid3: std::borrow::BorrowMut<Mid3>,
1109 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
1110 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
1111 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
1112 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
1113 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
1114 Lock3: Clone,
1115 {
1116 let first = self;
1117 let second = other;
1118
1119 ComposedAsyncLockKp {
1120 first: first,
1121 second: second,
1122 _p: std::marker::PhantomData,
1123 }
1124 }
1125
1126 pub fn then<V3, Value3, MutValue3, G3, S3>(
1128 self,
1129 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1130 ) -> AsyncKeyPathThenKp<
1131 R,
1132 V3,
1133 Root,
1134 Value3,
1135 MutRoot,
1136 MutValue3,
1137 Self,
1138 crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1139 >
1140 where
1141 V2: 'static,
1142 V3: 'static,
1143 Value2: std::borrow::Borrow<V2>,
1144 Value3: std::borrow::Borrow<V3>,
1145 MutValue2: std::borrow::BorrowMut<V2>,
1146 MutValue3: std::borrow::BorrowMut<V3>,
1147 G3: Fn(Value2) -> Option<Value3> + Clone,
1148 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1149 {
1150 let first = self;
1151 let second = next_kp;
1152
1153 AsyncKeyPathThenKp {
1154 first: first,
1155 second: second,
1156 _p: std::marker::PhantomData,
1157 }
1158 }
1159
1160 pub fn then_sync<
1162 Lock3,
1163 Mid3,
1164 V3,
1165 LockValue3,
1166 MidValue3,
1167 Value3,
1168 MutLock3,
1169 MutMid3,
1170 MutValue3,
1171 G3_1,
1172 S3_1,
1173 L3,
1174 G3_2,
1175 S3_2,
1176 >(
1177 self,
1178 lock_kp: crate::sync_kp::SyncKp<
1179 V2,
1180 Lock3,
1181 Mid3,
1182 V3,
1183 Value2,
1184 LockValue3,
1185 MidValue3,
1186 Value3,
1187 MutValue2,
1188 MutLock3,
1189 MutMid3,
1190 MutValue3,
1191 G3_1,
1192 S3_1,
1193 L3,
1194 G3_2,
1195 S3_2,
1196 >,
1197 ) -> AsyncLockKpThenSyncKp<
1198 R,
1199 V3,
1200 Root,
1201 Value3,
1202 MutRoot,
1203 MutValue3,
1204 Self,
1205 crate::sync_kp::SyncKp<
1206 V2,
1207 Lock3,
1208 Mid3,
1209 V3,
1210 Value2,
1211 LockValue3,
1212 MidValue3,
1213 Value3,
1214 MutValue2,
1215 MutLock3,
1216 MutMid3,
1217 MutValue3,
1218 G3_1,
1219 S3_1,
1220 L3,
1221 G3_2,
1222 S3_2,
1223 >,
1224 >
1225 where
1226 V2: 'static,
1227 V3: 'static,
1228 Value2: std::borrow::Borrow<V2>,
1229 Value3: std::borrow::Borrow<V3>,
1230 MutValue2: std::borrow::BorrowMut<V2>,
1231 MutValue3: std::borrow::BorrowMut<V3>,
1232 LockValue3: std::borrow::Borrow<Lock3>,
1233 MidValue3: std::borrow::Borrow<Mid3>,
1234 MutLock3: std::borrow::BorrowMut<Lock3>,
1235 MutMid3: std::borrow::BorrowMut<Mid3>,
1236 G3_1: Fn(Value2) -> Option<LockValue3>,
1237 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1238 L3: crate::sync_kp::LockAccess<Lock3, MidValue3> + crate::sync_kp::LockAccess<Lock3, MutMid3>,
1239 G3_2: Fn(MidValue3) -> Option<Value3>,
1240 S3_2: Fn(MutMid3) -> Option<MutValue3>,
1241 {
1242 let first = self;
1243 let second = lock_kp;
1244
1245 AsyncLockKpThenSyncKp {
1246 first: first,
1247 second: second,
1248 _p: std::marker::PhantomData,
1249 }
1250 }
1251}
1252
1253#[derive(Clone)]
1255pub struct KpThenAsyncKeyPath<
1256 R,
1257 V,
1258 V2,
1259 Root,
1260 Value,
1261 Value2,
1262 MutRoot,
1263 MutValue,
1264 MutValue2,
1265 First,
1266 Second,
1267> {
1268 first: First,
1269 second: Second,
1270 _p: std::marker::PhantomData<(R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2)>,
1271}
1272
1273impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1274 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1275{
1276 pub(crate) fn new(first: First, second: Second) -> Self {
1277 Self {
1278 first,
1279 second,
1280 _p: std::marker::PhantomData,
1281 }
1282 }
1283}
1284
1285impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1286 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1287where
1288 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1289 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1290{
1291 #[inline]
1293 pub async fn get(&self, root: Root) -> Option<Value2> {
1294 let v = self.first.sync_get(root)?;
1295 self.second.get(v).await
1296 }
1297 #[inline]
1299 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1300 let mut_v = self.first.sync_get_mut(root)?;
1301 self.second.get_mut(mut_v).await
1302 }
1303}
1304
1305#[async_trait(?Send)]
1306impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1307 AsyncKeyPathLike<Root, MutRoot>
1308 for KpThenAsyncKeyPath<
1309 R,
1310 V,
1311 V2,
1312 Root,
1313 Value,
1314 Value2,
1315 MutRoot,
1316 MutValue,
1317 MutValue2,
1318 First,
1319 Second,
1320 >
1321where
1322 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1323 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1324{
1325 type Value = Value2;
1326 type MutValue = MutValue2;
1327 async fn get(&self, root: Root) -> Option<Value2> {
1328 let v = self.first.sync_get(root)?;
1329 self.second.get(v).await
1330 }
1331 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1332 let mut_v = self.first.sync_get_mut(root)?;
1333 self.second.get_mut(mut_v).await
1334 }
1335}
1336
1337impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1338 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1339where
1340 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1341 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1342{
1343 pub fn then<V3, Value3, MutValue3, G3, S3>(
1345 self,
1346 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1347 ) -> AsyncKeyPathThenKp<
1348 R,
1349 V3,
1350 Root,
1351 Value3,
1352 MutRoot,
1353 MutValue3,
1354 Self,
1355 crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1356 >
1357 where
1358 V3: 'static,
1359 Value2: std::borrow::Borrow<V2>,
1360 MutValue2: std::borrow::BorrowMut<V2>,
1361 Value3: std::borrow::Borrow<V3>,
1362 MutValue3: std::borrow::BorrowMut<V3>,
1363 G3: Fn(Value2) -> Option<Value3> + Clone,
1364 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1365 {
1366 let first = self;
1367 let second = next_kp;
1368
1369 AsyncKeyPathThenKp {
1370 first: first,
1371 second: second,
1372 _p: std::marker::PhantomData,
1373 }
1374 }
1375}
1376
1377#[derive(Clone)]
1379pub struct AsyncKeyPathThenKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1380 first: First,
1381 second: Second,
1382 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1383}
1384
1385impl<R, V2, Root, Value2, MutRoot, MutValue2, First, RKp, G, S>
1387 AsyncKeyPathThenKp<
1388 R,
1389 V2,
1390 Root,
1391 Value2,
1392 MutRoot,
1393 MutValue2,
1394 First,
1395 crate::Kp<RKp, V2, First::Value, Value2, First::MutValue, MutValue2, G, S>,
1396 >
1397where
1398 First: AsyncKeyPathLike<Root, MutRoot>,
1399 First::Value: std::borrow::Borrow<RKp>,
1400 First::MutValue: std::borrow::BorrowMut<RKp>,
1401 Value2: std::borrow::Borrow<V2>,
1402 MutValue2: std::borrow::BorrowMut<V2>,
1403 G: Fn(First::Value) -> Option<Value2>,
1404 S: Fn(First::MutValue) -> Option<MutValue2>,
1405{
1406 #[inline]
1408 pub async fn get(&self, root: Root) -> Option<Value2> {
1409 let value = self.first.get(root).await?;
1410 (self.second.get)(value)
1411 }
1412 #[inline]
1414 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1415 let mut_value = self.first.get_mut(root).await?;
1416 (self.second.set)(mut_value)
1417 }
1418}
1419
1420#[async_trait(?Send)]
1421impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncKeyPathLike<Root, MutRoot>
1422 for ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1423where
1424 First: AsyncKeyPathLike<Root, MutRoot>,
1425 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1426{
1427 type Value = Value2;
1428 type MutValue = MutValue2;
1429 async fn get(&self, root: Root) -> Option<Value2> {
1430 ComposedAsyncLockKp::get(self, root).await
1431 }
1432 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1433 ComposedAsyncLockKp::get_mut(self, root).await
1434 }
1435}
1436
1437#[derive(Clone)]
1444pub struct AsyncLockKpThenSyncKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1445 first: First,
1446 second: Second,
1447 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1448}
1449
1450impl<
1451 R,
1452 V2,
1453 Root,
1454 Value2,
1455 MutRoot,
1456 MutValue2,
1457 Lock,
1458 Mid,
1459 V,
1460 LockValue,
1461 MidValue,
1462 Value,
1463 MutLock,
1464 MutMid,
1465 MutValue,
1466 G1,
1467 S1,
1468 L,
1469 G2,
1470 S2,
1471 Lock2,
1472 Mid2,
1473 LockValue2,
1474 MidValue2,
1475 MutLock2,
1476 MutMid2,
1477 G2_1,
1478 S2_1,
1479 L2,
1480 G2_2,
1481 S2_2,
1482>
1483 AsyncLockKpThenSyncKp<
1484 R,
1485 V2,
1486 Root,
1487 Value2,
1488 MutRoot,
1489 MutValue2,
1490 AsyncLockKp<
1491 R,
1492 Lock,
1493 Mid,
1494 V,
1495 Root,
1496 LockValue,
1497 MidValue,
1498 Value,
1499 MutRoot,
1500 MutLock,
1501 MutMid,
1502 MutValue,
1503 G1,
1504 S1,
1505 L,
1506 G2,
1507 S2,
1508 >,
1509 crate::sync_kp::SyncKp<
1510 V,
1511 Lock2,
1512 Mid2,
1513 V2,
1514 Value,
1515 LockValue2,
1516 MidValue2,
1517 Value2,
1518 MutValue,
1519 MutLock2,
1520 MutMid2,
1521 MutValue2,
1522 G2_1,
1523 S2_1,
1524 L2,
1525 G2_2,
1526 S2_2,
1527 >,
1528 >
1529where
1530 Root: std::borrow::Borrow<R>,
1531 LockValue: std::borrow::Borrow<Lock>,
1532 MidValue: std::borrow::Borrow<Mid>,
1533 Value: std::borrow::Borrow<V>,
1534 MutRoot: std::borrow::BorrowMut<R>,
1535 MutLock: std::borrow::BorrowMut<Lock>,
1536 MutMid: std::borrow::BorrowMut<Mid>,
1537 MutValue: std::borrow::BorrowMut<V>,
1538 Value2: std::borrow::Borrow<V2>,
1539 MutValue2: std::borrow::BorrowMut<V2>,
1540 G1: Fn(Root) -> Option<LockValue> + Clone,
1541 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
1542 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
1543 G2: Fn(MidValue) -> Option<Value> + Clone,
1544 S2: Fn(MutMid) -> Option<MutValue> + Clone,
1545 LockValue2: std::borrow::Borrow<Lock2>,
1546 MidValue2: std::borrow::Borrow<Mid2>,
1547 MutLock2: std::borrow::BorrowMut<Lock2>,
1548 MutMid2: std::borrow::BorrowMut<Mid2>,
1549 G2_1: Fn(Value) -> Option<LockValue2>,
1550 S2_1: Fn(MutValue) -> Option<MutLock2>,
1551 L2: crate::sync_kp::LockAccess<Lock2, MidValue2> + crate::sync_kp::LockAccess<Lock2, MutMid2>,
1552 G2_2: Fn(MidValue2) -> Option<Value2>,
1553 S2_2: Fn(MutMid2) -> Option<MutValue2>,
1554 Lock: Clone,
1555{
1556 pub async fn get(&self, root: Root) -> Option<Value2> {
1558 let value = self.first.get(root).await?;
1559 self.second.get(value)
1560 }
1561
1562 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1564 let mut_value = self.first.get_mut(root).await?;
1565 self.second.get_mut(mut_value)
1566 }
1567}
1568
1569impl<
1571 R,
1572 V2,
1573 Root,
1574 Value2,
1575 MutRoot,
1576 MutValue2,
1577 Lock3,
1578 Mid3,
1579 LockValue3,
1580 MidValue3,
1581 MutLock3,
1582 MutMid3,
1583 G3_1,
1584 S3_1,
1585 L3,
1586 G3_2,
1587 S3_2,
1588 First,
1589 Second,
1590>
1591 AsyncLockKpThenSyncKp<
1592 R,
1593 V2,
1594 Root,
1595 Value2,
1596 MutRoot,
1597 MutValue2,
1598 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>,
1599 crate::sync_kp::SyncKp<
1600 Value2,
1601 Lock3,
1602 Mid3,
1603 V2,
1604 Value2,
1605 LockValue3,
1606 MidValue3,
1607 Value2,
1608 MutValue2,
1609 MutLock3,
1610 MutMid3,
1611 MutValue2,
1612 G3_1,
1613 S3_1,
1614 L3,
1615 G3_2,
1616 S3_2,
1617 >,
1618 >
1619where
1620 First: AsyncKeyPathLike<Root, MutRoot>,
1621 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1622 Value2: std::borrow::Borrow<V2>,
1623 MutValue2: std::borrow::BorrowMut<Value2> + std::borrow::BorrowMut<V2>,
1624 LockValue3: std::borrow::Borrow<Lock3>,
1625 MidValue3: std::borrow::Borrow<Mid3>,
1626 MutLock3: std::borrow::BorrowMut<Lock3>,
1627 MutMid3: std::borrow::BorrowMut<Mid3>,
1628 G3_1: Fn(Value2) -> Option<LockValue3>,
1629 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1630 L3: crate::sync_kp::LockAccess<Lock3, MidValue3> + crate::sync_kp::LockAccess<Lock3, MutMid3>,
1631 G3_2: Fn(MidValue3) -> Option<Value2>,
1632 S3_2: Fn(MutMid3) -> Option<MutValue2>,
1633{
1634 pub async fn get(&self, root: Root) -> Option<Value2> {
1636 let value = self.first.get(root).await?;
1637 self.second.get(value)
1638 }
1639 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1641 let mut_value = self.first.get_mut(root).await?;
1642 self.second.get_mut(mut_value)
1643 }
1644}
1645
1646impl<
1648 R,
1649 V2,
1650 Root,
1651 Value2,
1652 MutRoot,
1653 MutValue2,
1654 Lock3,
1655 Mid3,
1656 LockValue3,
1657 MidValue3,
1658 MutLock3,
1659 MutMid3,
1660 G3_1,
1661 S3_1,
1662 L3,
1663 G3_2,
1664 S3_2,
1665 F,
1666 S,
1667>
1668 AsyncLockKpThenSyncKp<
1669 R,
1670 V2,
1671 Root,
1672 Value2,
1673 MutRoot,
1674 MutValue2,
1675 AsyncLockKpThenSyncKp<R, V2, Root, Value2, MutRoot, MutValue2, F, S>,
1676 crate::sync_kp::SyncKp<
1677 Value2,
1678 Lock3,
1679 Mid3,
1680 V2,
1681 Value2,
1682 LockValue3,
1683 MidValue3,
1684 Value2,
1685 MutValue2,
1686 MutLock3,
1687 MutMid3,
1688 MutValue2,
1689 G3_1,
1690 S3_1,
1691 L3,
1692 G3_2,
1693 S3_2,
1694 >,
1695 >
1696where
1697 F: AsyncKeyPathLike<Root, MutRoot, Value = Value2, MutValue = MutValue2>,
1698 S: SyncKeyPathLike<Value2, Value2, MutValue2, MutValue2>,
1699 Value2: std::borrow::Borrow<V2>,
1700 MutValue2: std::borrow::BorrowMut<Value2> + std::borrow::BorrowMut<V2>,
1701 LockValue3: std::borrow::Borrow<Lock3>,
1702 MidValue3: std::borrow::Borrow<Mid3>,
1703 MutLock3: std::borrow::BorrowMut<Lock3>,
1704 MutMid3: std::borrow::BorrowMut<Mid3>,
1705 G3_1: Fn(Value2) -> Option<LockValue3>,
1706 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1707 L3: crate::sync_kp::LockAccess<Lock3, MidValue3> + crate::sync_kp::LockAccess<Lock3, MutMid3>,
1708 G3_2: Fn(MidValue3) -> Option<Value2>,
1709 S3_2: Fn(MutMid3) -> Option<MutValue2>,
1710{
1711 pub async fn get(&self, root: Root) -> Option<Value2> {
1713 let value = AsyncKeyPathLike::get(&self.first, root).await?;
1714 self.second.get(value)
1715 }
1716 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1718 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
1719 self.second.get_mut(mut_value)
1720 }
1721}
1722
1723#[async_trait(?Send)]
1725impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncKeyPathLike<Root, MutRoot>
1726 for AsyncLockKpThenSyncKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1727where
1728 First: AsyncKeyPathLike<Root, MutRoot>,
1729 Second: SyncKeyPathLike<First::Value, Value2, First::MutValue, MutValue2>,
1730{
1731 type Value = Value2;
1732 type MutValue = MutValue2;
1733 async fn get(&self, root: Root) -> Option<Value2> {
1734 let value = AsyncKeyPathLike::get(&self.first, root).await?;
1735 SyncKeyPathLike::sync_get(&self.second, value)
1736 }
1737 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1738 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
1739 SyncKeyPathLike::sync_get_mut(&self.second, mut_value)
1740 }
1741}
1742
1743impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1745 AsyncLockKpThenSyncKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1746where
1747 First: AsyncKeyPathLike<Root, MutRoot>,
1748{
1749 pub fn then_async<
1752 Lock3,
1753 Mid3,
1754 V3,
1755 LockValue3,
1756 MidValue3,
1757 Value3,
1758 MutLock3,
1759 MutMid3,
1760 MutValue3,
1761 G3_1,
1762 S3_1,
1763 L3,
1764 G3_2,
1765 S3_2,
1766 >(
1767 self,
1768 other: AsyncLockKp<
1769 Value2,
1770 Lock3,
1771 Mid3,
1772 V3,
1773 Value2,
1774 LockValue3,
1775 MidValue3,
1776 Value3,
1777 MutValue2,
1778 MutLock3,
1779 MutMid3,
1780 MutValue3,
1781 G3_1,
1782 S3_1,
1783 L3,
1784 G3_2,
1785 S3_2,
1786 >,
1787 ) -> ComposedAsyncLockKp<
1788 Root,
1789 V3,
1790 Root,
1791 Value3,
1792 MutRoot,
1793 MutValue3,
1794 Self,
1795 AsyncLockKp<
1796 Value2,
1797 Lock3,
1798 Mid3,
1799 V3,
1800 Value2,
1801 LockValue3,
1802 MidValue3,
1803 Value3,
1804 MutValue2,
1805 MutLock3,
1806 MutMid3,
1807 MutValue3,
1808 G3_1,
1809 S3_1,
1810 L3,
1811 G3_2,
1812 S3_2,
1813 >,
1814 >
1815 where
1816 V2: 'static,
1817 V3: 'static,
1818 Value2: std::borrow::Borrow<V2>,
1819 Value3: std::borrow::Borrow<V3>,
1820 MutValue2: std::borrow::BorrowMut<V2> + std::borrow::BorrowMut<Value2>,
1821 MutValue3: std::borrow::BorrowMut<V3>,
1822 LockValue3: std::borrow::Borrow<Lock3>,
1823 MidValue3: std::borrow::Borrow<Mid3>,
1824 MutLock3: std::borrow::BorrowMut<Lock3>,
1825 MutMid3: std::borrow::BorrowMut<Mid3>,
1826 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
1827 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
1828 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
1829 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
1830 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
1831 Lock3: Clone,
1832 {
1833 let first = self;
1834 let second = other;
1835
1836 ComposedAsyncLockKp {
1837 first: first,
1838 second: second,
1839 _p: std::marker::PhantomData,
1840 }
1841 }
1842
1843 pub fn then_sync<
1845 Lock3,
1846 Mid3,
1847 V3,
1848 LockValue3,
1849 MidValue3,
1850 Value3,
1851 MutLock3,
1852 MutMid3,
1853 MutValue3,
1854 G3_1,
1855 S3_1,
1856 L3,
1857 G3_2,
1858 S3_2,
1859 >(
1860 self,
1861 lock_kp: crate::sync_kp::SyncKp<
1862 Value2,
1863 Lock3,
1864 Mid3,
1865 V3,
1866 Value2,
1867 LockValue3,
1868 MidValue3,
1869 Value3,
1870 MutValue2,
1871 MutLock3,
1872 MutMid3,
1873 MutValue3,
1874 G3_1,
1875 S3_1,
1876 L3,
1877 G3_2,
1878 S3_2,
1879 >,
1880 ) -> AsyncLockKpThenSyncKp<
1881 R,
1882 V3,
1883 Root,
1884 Value3,
1885 MutRoot,
1886 MutValue3,
1887 Self,
1888 crate::sync_kp::SyncKp<
1889 Value2,
1890 Lock3,
1891 Mid3,
1892 V3,
1893 Value2,
1894 LockValue3,
1895 MidValue3,
1896 Value3,
1897 MutValue2,
1898 MutLock3,
1899 MutMid3,
1900 MutValue3,
1901 G3_1,
1902 S3_1,
1903 L3,
1904 G3_2,
1905 S3_2,
1906 >,
1907 >
1908 where
1909 V3: 'static,
1910 Value2: std::borrow::Borrow<V2>,
1911 Value3: std::borrow::Borrow<V3>,
1912 MutValue2: std::borrow::BorrowMut<Value2>,
1913 MutValue3: std::borrow::BorrowMut<V3>,
1914 LockValue3: std::borrow::Borrow<Lock3>,
1915 MidValue3: std::borrow::Borrow<Mid3>,
1916 MutLock3: std::borrow::BorrowMut<Lock3>,
1917 MutMid3: std::borrow::BorrowMut<Mid3>,
1918 G3_1: Fn(Value2) -> Option<LockValue3>,
1919 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1920 L3: crate::sync_kp::LockAccess<Lock3, MidValue3> + crate::sync_kp::LockAccess<Lock3, MutMid3>,
1921 G3_2: Fn(MidValue3) -> Option<Value3>,
1922 S3_2: Fn(MutMid3) -> Option<MutValue3>,
1923 {
1924 let first = self;
1925 let second = lock_kp;
1926
1927 AsyncLockKpThenSyncKp {
1928 first: first,
1929 second: second,
1930 _p: std::marker::PhantomData,
1931 }
1932 }
1933
1934 pub fn then<V3, Value3, MutValue3, G3, S3>(
1936 self,
1937 next_kp: crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1938 ) -> AsyncKeyPathThenKp<
1939 R,
1940 V3,
1941 Root,
1942 Value3,
1943 MutRoot,
1944 MutValue3,
1945 Self,
1946 crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1947 >
1948 where
1949 V3: 'static,
1950 Value2: std::borrow::Borrow<V2>,
1951 Value3: std::borrow::Borrow<V3>,
1952 MutValue2: std::borrow::BorrowMut<Value2>,
1953 MutValue3: std::borrow::BorrowMut<V3>,
1954 G3: Fn(Value2) -> Option<Value3> + Clone,
1955 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1956 {
1957 let first = self;
1958 let second = next_kp;
1959
1960 AsyncKeyPathThenKp {
1961 first: first,
1962 second: second,
1963 _p: std::marker::PhantomData,
1964 }
1965 }
1966}
1967
1968#[cfg(feature = "tokio")]
1973#[derive(Clone)] pub struct TokioMutexAccess<T> {
1981 _phantom: std::marker::PhantomData<T>,
1982}
1983
1984#[cfg(feature = "tokio")]
1985impl<T> TokioMutexAccess<T> {
1986 pub fn new() -> Self {
1987 Self {
1988 _phantom: std::marker::PhantomData,
1989 }
1990 }
1991}
1992
1993#[cfg(feature = "tokio")]
1994impl<T> Default for TokioMutexAccess<T> {
1995 fn default() -> Self {
1996 Self::new()
1997 }
1998}
1999
2000#[cfg(feature = "tokio")]
2002#[async_trait]
2003impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::Mutex<T>>, &'a T>
2004 for TokioMutexAccess<T>
2005{
2006 #[inline]
2007 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
2008 let guard = lock.lock().await;
2010 let ptr = &*guard as *const T;
2011 unsafe { Some(&*ptr) }
2012 }
2013
2014 #[inline]
2015 async fn lock_write(&self, lock: &mut std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
2016 let guard = lock.lock().await;
2017 let ptr = &*guard as *const T;
2018 unsafe { Some(&*ptr) }
2019 }
2020}
2021
2022#[cfg(feature = "tokio")]
2024#[async_trait]
2025impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::Mutex<T>>, &'a mut T>
2026 for TokioMutexAccess<T>
2027{
2028 #[inline]
2029 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a mut T> {
2030 let mut guard = lock.lock().await;
2032 let ptr = &mut *guard as *mut T;
2033 unsafe { Some(&mut *ptr) }
2034 }
2035
2036 #[inline]
2037 async fn lock_write(
2038 &self,
2039 lock: &mut std::sync::Arc<tokio::sync::Mutex<T>>,
2040 ) -> Option<&'a mut T> {
2041 let mut guard = lock.lock().await;
2042 let ptr = &mut *guard as *mut T;
2043 unsafe { Some(&mut *ptr) }
2044 }
2045}
2046
2047#[cfg(feature = "tokio")]
2052pub struct TokioRwLockAccess<T> {
2060 _phantom: std::marker::PhantomData<T>,
2061}
2062
2063#[cfg(feature = "tokio")]
2064impl<T> TokioRwLockAccess<T> {
2065 pub fn new() -> Self {
2066 Self {
2067 _phantom: std::marker::PhantomData,
2068 }
2069 }
2070}
2071
2072#[cfg(feature = "tokio")]
2073impl<T> Default for TokioRwLockAccess<T> {
2074 fn default() -> Self {
2075 Self::new()
2076 }
2077}
2078
2079#[cfg(feature = "tokio")]
2080impl<T> Clone for TokioRwLockAccess<T> {
2081 fn clone(&self) -> Self {
2082 Self {
2083 _phantom: self._phantom,
2084 }
2085 }
2086}
2087
2088#[cfg(feature = "tokio")]
2090#[async_trait]
2091impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::RwLock<T>>, &'a T>
2092 for TokioRwLockAccess<T>
2093{
2094 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
2095 let guard = lock.read().await;
2097 let ptr = &*guard as *const T;
2098 unsafe { Some(&*ptr) }
2099 }
2100
2101 async fn lock_write(&self, lock: &mut std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
2102 let guard = lock.read().await;
2104 let ptr = &*guard as *const T;
2105 unsafe { Some(&*ptr) }
2106 }
2107}
2108
2109#[cfg(feature = "tokio")]
2111#[async_trait]
2112impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::RwLock<T>>, &'a mut T>
2113 for TokioRwLockAccess<T>
2114{
2115 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a mut T> {
2116 let mut guard = lock.write().await;
2118 let ptr = &mut *guard as *mut T;
2119 unsafe { Some(&mut *ptr) }
2120 }
2121
2122 async fn lock_write(
2123 &self,
2124 lock: &mut std::sync::Arc<tokio::sync::RwLock<T>>,
2125 ) -> Option<&'a mut T> {
2126 let mut guard = lock.write().await;
2128 let ptr = &mut *guard as *mut T;
2129 unsafe { Some(&mut *ptr) }
2130 }
2131}
2132
2133#[cfg(feature = "tokio")]
2141pub type AsyncLockKpMutexFor<Root, Lock, Inner> = AsyncLockKp<
2143 Root,
2144 Lock,
2145 Inner,
2146 Inner,
2147 &'static Root,
2148 &'static Lock,
2149 &'static Inner,
2150 &'static Inner,
2151 &'static mut Root,
2152 &'static mut Lock,
2153 &'static mut Inner,
2154 &'static mut Inner,
2155 for<'b> fn(&'b Root) -> Option<&'b Lock>,
2156 for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
2157 TokioMutexAccess<Inner>,
2158 for<'b> fn(&'b Inner) -> Option<&'b Inner>,
2159 for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
2160>;
2161
2162#[cfg(feature = "tokio")]
2163pub type AsyncLockKpRwLockFor<Root, Lock, Inner> = AsyncLockKp<
2165 Root,
2166 Lock,
2167 Inner,
2168 Inner,
2169 &'static Root,
2170 &'static Lock,
2171 &'static Inner,
2172 &'static Inner,
2173 &'static mut Root,
2174 &'static mut Lock,
2175 &'static mut Inner,
2176 &'static mut Inner,
2177 for<'b> fn(&'b Root) -> Option<&'b Lock>,
2178 for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
2179 TokioRwLockAccess<Inner>,
2180 for<'b> fn(&'b Inner) -> Option<&'b Inner>,
2181 for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
2182>;
2183
2184#[cfg(all(test, feature = "tokio"))]
2189mod tests {
2190 use super::*;
2191 use crate::KpType;
2192
2193 #[tokio::test]
2194 async fn test_async_lock_kp_tokio_mutex_basic() {
2195 use tokio::sync::Mutex;
2196
2197 #[derive(Clone)]
2198 struct Root {
2199 data: std::sync::Arc<Mutex<String>>,
2200 }
2201
2202 let root = Root {
2203 data: std::sync::Arc::new(Mutex::new("hello".to_string())),
2204 };
2205
2206 let lock_kp = {
2208 let prev: KpType<Root, std::sync::Arc<Mutex<String>>> =
2209 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2210 let next: KpType<String, String> =
2211 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
2212 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2213 };
2214
2215 let value = lock_kp.get(&root).await;
2217 assert!(value.is_some());
2218 assert_eq!(value.unwrap(), &"hello".to_string());
2219 }
2220
2221 #[tokio::test]
2222 async fn test_async_lock_kp_get_optional_or_else() {
2223 use tokio::sync::Mutex;
2224
2225 #[derive(Clone)]
2226 struct Root {
2227 data: std::sync::Arc<Mutex<i32>>,
2228 }
2229
2230 let mut root = Root {
2231 data: std::sync::Arc::new(Mutex::new(42)),
2232 };
2233
2234 let lock_kp = {
2235 let prev: KpType<Root, std::sync::Arc<Mutex<i32>>> =
2236 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2237 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2238 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2239 };
2240
2241 assert!(lock_kp.get_optional(None).await.is_none());
2243 assert_eq!(lock_kp.get_optional(Some(&root)).await, Some(&42));
2244
2245 assert!(lock_kp.get_mut_optional(None).await.is_none());
2247 if let Some(m) = lock_kp.get_mut_optional(Some(&mut root)).await {
2248 *m = 99;
2249 }
2250 assert_eq!(lock_kp.get(&root).await, Some(&99));
2251
2252 assert_eq!(*lock_kp.get_or_else(None, || &0).await, 0);
2254 assert_eq!(*lock_kp.get_or_else(Some(&root), || &0).await, 99);
2255
2256 let m = lock_kp
2258 .get_mut_or_else(Some(&mut root), || panic!("unexpected"))
2259 .await;
2260 *m = 100;
2261 assert_eq!(lock_kp.get(&root).await, Some(&100));
2262 }
2263
2264 #[tokio::test]
2265 async fn test_async_lock_kp_tokio_rwlock_basic() {
2266 use tokio::sync::RwLock;
2267
2268 #[derive(Clone)]
2269 struct Root {
2270 data: std::sync::Arc<RwLock<Vec<i32>>>,
2271 }
2272
2273 let root = Root {
2274 data: std::sync::Arc::new(RwLock::new(vec![1, 2, 3, 4, 5])),
2275 };
2276
2277 let lock_kp = {
2279 let prev: KpType<Root, std::sync::Arc<RwLock<Vec<i32>>>> =
2280 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2281 let next: KpType<Vec<i32>, Vec<i32>> =
2282 Kp::new(|v: &Vec<i32>| Some(v), |v: &mut Vec<i32>| Some(v));
2283 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
2284 };
2285
2286 let value = lock_kp.get(&root).await;
2288 assert!(value.is_some());
2289 assert_eq!(value.unwrap().len(), 5);
2290 }
2291
2292 #[tokio::test]
2293 async fn test_async_lock_kp_concurrent_reads() {
2294 use tokio::sync::RwLock;
2295
2296 #[derive(Clone)]
2297 struct Root {
2298 data: std::sync::Arc<RwLock<i32>>,
2299 }
2300
2301 let root = Root {
2302 data: std::sync::Arc::new(RwLock::new(42)),
2303 };
2304
2305 let lock_kp = {
2307 let prev: KpType<Root, std::sync::Arc<RwLock<i32>>> =
2308 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2309 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2310 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
2311 };
2312
2313 let lock_kp2 = {
2316 let prev: KpType<Root, std::sync::Arc<RwLock<i32>>> =
2317 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2318 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2319 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
2320 };
2321 let (a, b) = tokio::join!(lock_kp.get(&root), lock_kp2.get(&root));
2322 assert_eq!(a, Some(&42));
2323 assert_eq!(b, Some(&42));
2324
2325 let value = lock_kp.get(&root).await;
2327 assert_eq!(value, Some(&42));
2328 }
2329
2330 #[tokio::test]
2331 async fn test_async_lock_kp_panic_on_clone_proof() {
2332 use tokio::sync::Mutex;
2333
2334 struct PanicOnClone {
2336 data: String,
2337 }
2338
2339 impl Clone for PanicOnClone {
2340 fn clone(&self) -> Self {
2341 panic!("❌ ASYNC DEEP CLONE DETECTED! PanicOnClone was cloned!");
2342 }
2343 }
2344
2345 #[derive(Clone)]
2346 struct Root {
2347 level1: std::sync::Arc<Mutex<Level1>>,
2348 }
2349
2350 struct Level1 {
2351 panic_data: PanicOnClone,
2352 value: i32,
2353 }
2354
2355 impl Clone for Level1 {
2356 fn clone(&self) -> Self {
2357 panic!("❌ Level1 was deeply cloned in async context!");
2358 }
2359 }
2360
2361 let root = Root {
2363 level1: std::sync::Arc::new(Mutex::new(Level1 {
2364 panic_data: PanicOnClone {
2365 data: "test".to_string(),
2366 },
2367 value: 123,
2368 })),
2369 };
2370
2371 let lock_kp = {
2373 let prev: KpType<Root, std::sync::Arc<Mutex<Level1>>> = Kp::new(
2374 |r: &Root| Some(&r.level1),
2375 |r: &mut Root| Some(&mut r.level1),
2376 );
2377 let next: KpType<Level1, i32> = Kp::new(
2378 |l: &Level1| Some(&l.value),
2379 |l: &mut Level1| Some(&mut l.value),
2380 );
2381 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2382 };
2383
2384 let value = lock_kp.get(&root).await;
2386
2387 assert_eq!(value, Some(&123));
2389 }
2390
2391 #[tokio::test]
2392 async fn test_async_lock_kp_structure() {
2393 use tokio::sync::Mutex;
2394
2395 #[derive(Clone)]
2396 struct Root {
2397 data: std::sync::Arc<Mutex<String>>,
2398 }
2399
2400 let lock_kp = {
2401 let prev: KpType<Root, std::sync::Arc<Mutex<String>>> =
2402 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2403 let next: KpType<String, String> =
2404 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
2405 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2406 };
2407
2408 let _ = &lock_kp.prev;
2410 let _ = &lock_kp.mid;
2411 let _ = &lock_kp.next;
2412 }
2413
2414 #[tokio::test]
2415 async fn test_async_kp_then() {
2416 use tokio::sync::Mutex;
2417
2418 #[derive(Clone)]
2419 struct Root {
2420 data: std::sync::Arc<Mutex<Inner>>,
2421 }
2422
2423 #[derive(Clone)]
2424 struct Inner {
2425 value: i32,
2426 }
2427
2428 let root = Root {
2429 data: std::sync::Arc::new(Mutex::new(Inner { value: 42 })),
2430 };
2431
2432 let async_kp = {
2434 let prev: KpType<Root, std::sync::Arc<Mutex<Inner>>> =
2435 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2436 let next: KpType<Inner, Inner> = Kp::new(|i: &Inner| Some(i), |i: &mut Inner| Some(i));
2437 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2438 };
2439
2440 let value_kp: KpType<Inner, i32> = Kp::new(
2442 |i: &Inner| Some(&i.value),
2443 |i: &mut Inner| Some(&mut i.value),
2444 );
2445
2446 let chained = async_kp.then(value_kp);
2447 let result = chained.get(&root).await;
2448 assert_eq!(result, Some(&42));
2449 }
2450
2451 #[tokio::test]
2452 async fn test_async_kp_later_then() {
2453 use tokio::sync::Mutex;
2454
2455 #[derive(Clone)]
2456 struct Root {
2457 lock1: std::sync::Arc<Mutex<Container>>,
2458 }
2459
2460 #[derive(Clone)]
2461 struct Container {
2462 lock2: std::sync::Arc<Mutex<i32>>,
2463 }
2464
2465 let root = Root {
2466 lock1: std::sync::Arc::new(Mutex::new(Container {
2467 lock2: std::sync::Arc::new(Mutex::new(999)),
2468 })),
2469 };
2470
2471 let async_kp1 = {
2473 let prev: KpType<Root, std::sync::Arc<Mutex<Container>>> =
2474 Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
2475 let next: KpType<Container, Container> =
2476 Kp::new(|c: &Container| Some(c), |c: &mut Container| Some(c));
2477 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2478 };
2479
2480 let async_kp2 = {
2482 let prev: KpType<Container, std::sync::Arc<Mutex<i32>>> = Kp::new(
2483 |c: &Container| Some(&c.lock2),
2484 |c: &mut Container| Some(&mut c.lock2),
2485 );
2486 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2487 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2488 };
2489
2490 let chained = async_kp1.then_async(async_kp2);
2492 let result = chained.get(&root).await;
2493 assert_eq!(result, Some(&999));
2494 }
2495
2496 #[tokio::test]
2497 async fn test_async_kp_then_async_three_levels() {
2498 use tokio::sync::Mutex;
2499
2500 #[derive(Clone)]
2501 struct Root {
2502 a: std::sync::Arc<Mutex<Level1>>,
2503 }
2504 #[derive(Clone)]
2505 struct Level1 {
2506 b: std::sync::Arc<Mutex<Level2>>,
2507 }
2508 #[derive(Clone)]
2509 struct Level2 {
2510 c: std::sync::Arc<Mutex<i32>>,
2511 }
2512
2513 let root = Root {
2514 a: std::sync::Arc::new(Mutex::new(Level1 {
2515 b: std::sync::Arc::new(Mutex::new(Level2 {
2516 c: std::sync::Arc::new(Mutex::new(42)),
2517 })),
2518 })),
2519 };
2520
2521 let kp1 = {
2522 let prev: KpType<Root, std::sync::Arc<Mutex<Level1>>> =
2523 Kp::new(|r: &Root| Some(&r.a), |r: &mut Root| Some(&mut r.a));
2524 let next: KpType<Level1, Level1> =
2525 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
2526 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2527 };
2528 let kp2 = {
2529 let prev: KpType<Level1, std::sync::Arc<Mutex<Level2>>> =
2530 Kp::new(|l: &Level1| Some(&l.b), |l: &mut Level1| Some(&mut l.b));
2531 let next: KpType<Level2, Level2> =
2532 Kp::new(|l: &Level2| Some(l), |l: &mut Level2| Some(l));
2533 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2534 };
2535 let kp3 = {
2536 let prev: KpType<Level2, std::sync::Arc<Mutex<i32>>> =
2537 Kp::new(|l: &Level2| Some(&l.c), |l: &mut Level2| Some(&mut l.c));
2538 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2539 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2540 };
2541
2542 let chained = kp1.then_async(kp2).then_async(kp3);
2543 let result = chained.get(&root).await;
2544 assert_eq!(result, Some(&42));
2545 }
2546}