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