1use key_paths_core::{Readable, Writable};
33use crate::Kp;
34use async_trait::async_trait;
35use std::fmt;
36#[cfg(feature = "tokio")]
37use std::sync::OnceLock;
38
39#[cfg(feature = "tokio")]
44fn block_async<F>(future: F) -> F::Output
45where
46 F: std::future::Future,
47{
48 match tokio::runtime::Handle::try_current() {
49 Ok(handle) => handle.block_on(future),
50 Err(_) => {
51 static RT: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
52 RT.get_or_init(|| {
53 tokio::runtime::Builder::new_multi_thread()
54 .enable_all()
55 .build()
56 .expect("failed to build tokio Runtime for rust_key_paths::async_lock::block_async")
57 })
58 .block_on(future)
59 }
60 }
61}
62#[cfg(feature = "tokio")]
64pub use tokio::sync::{Mutex as TokioMutex, RwLock as TokioRwLock};
65
66#[async_trait]
84pub trait AsyncLockLike<Lock, Inner>: Send + Sync {
85 async fn lock_read(&self, lock: &Lock) -> Option<Inner>;
87
88 async fn lock_write(&self, lock: &mut Lock) -> Option<Inner>;
90}
91
92pub trait SyncKeyPathLike<Root, Value, MutRoot, MutValue> {
95 fn sync_get(&self, root: Root) -> Option<Value>;
126
127 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue>;
158}
159
160impl<R, V, Root, Value, MutRoot, MutValue, G, S> SyncKeyPathLike<Root, Value, MutRoot, MutValue>
161 for crate::Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
162where
163 Root: std::borrow::Borrow<R>,
164 Value: std::borrow::Borrow<V>,
165 MutRoot: std::borrow::BorrowMut<R>,
166 MutValue: std::borrow::BorrowMut<V>,
167 G: Fn(Root) -> Option<Value>,
168 S: Fn(MutRoot) -> Option<MutValue>,
169 {
171 fn sync_get(&self, root: Root) -> Option<Value> {
172 (self.get)(root)
173 }
174 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue> {
175 (self.set)(root)
176 }
177}
178
179impl<
180 R,
181 Lock,
182 Mid,
183 V,
184 Root,
185 LockValue,
186 MidValue,
187 Value,
188 MutRoot,
189 MutLock,
190 MutMid,
191 MutValue,
192 G1,
193 S1,
194 L,
195 G2,
196 S2,
197> SyncKeyPathLike<Root, Value, MutRoot, MutValue>
198 for crate::sync_kp::SyncKp<
199 R,
200 Lock,
201 Mid,
202 V,
203 Root,
204 LockValue,
205 MidValue,
206 Value,
207 MutRoot,
208 MutLock,
209 MutMid,
210 MutValue,
211 G1,
212 S1,
213 L,
214 G2,
215 S2,
216 >
217where
218 Root: std::borrow::Borrow<R>,
219 LockValue: std::borrow::Borrow<Lock>,
220 MidValue: std::borrow::Borrow<Mid>,
221 Value: std::borrow::Borrow<V>,
222 MutRoot: std::borrow::BorrowMut<R>,
223 MutLock: std::borrow::BorrowMut<Lock>,
224 MutMid: std::borrow::BorrowMut<Mid>,
225 MutValue: std::borrow::BorrowMut<V>,
226 G1: Fn(Root) -> Option<LockValue>,
227 S1: Fn(MutRoot) -> Option<MutLock>,
228 L: crate::sync_kp::LockAccess<Lock, MidValue> + crate::sync_kp::LockAccess<Lock, MutMid>,
229 G2: Fn(MidValue) -> Option<Value>,
230 S2: Fn(MutMid) -> Option<MutValue>,
231{
232 #[inline]
233 fn sync_get(&self, root: Root) -> Option<Value> {
234 self.get(root)
235 }
236 #[inline]
237 fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue> {
238 self.get_mut(root)
239 }
240}
241
242#[async_trait(?Send)]
253pub trait AsyncKeyPathLike<Root, MutRoot> {
254 type Value;
256 type MutValue;
258 async fn get(&self, root: Root) -> Option<Self::Value>;
260 async fn get_mut(&self, root: MutRoot) -> Option<Self::MutValue>;
262}
263
264#[derive(Clone)] pub struct AsyncLockKp<
295 R,
296 Lock,
297 Mid,
298 V,
299 Root,
300 LockValue,
301 MidValue,
302 Value,
303 MutRoot,
304 MutLock,
305 MutMid,
306 MutValue,
307 G1,
308 S1,
309 L,
310 G2,
311 S2,
312> where
313 Root: std::borrow::Borrow<R>,
314 LockValue: std::borrow::Borrow<Lock>,
315 MidValue: std::borrow::Borrow<Mid>,
316 Value: std::borrow::Borrow<V>,
317 MutRoot: std::borrow::BorrowMut<R>,
318 MutLock: std::borrow::BorrowMut<Lock>,
319 MutMid: std::borrow::BorrowMut<Mid>,
320 MutValue: std::borrow::BorrowMut<V>,
321 G1: Fn(Root) -> Option<LockValue> + Clone,
322 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
323 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
324 G2: Fn(MidValue) -> Option<Value> + Clone,
325 S2: Fn(MutMid) -> Option<MutValue> + Clone,
326{
327 prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
329
330 mid: L,
332
333 next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
335}
336
337impl<
338 R,
339 Lock,
340 Mid,
341 V,
342 Root,
343 LockValue,
344 MidValue,
345 Value,
346 MutRoot,
347 MutLock,
348 MutMid,
349 MutValue,
350 G1,
351 S1,
352 L,
353 G2,
354 S2,
355> fmt::Debug
356 for AsyncLockKp<
357 R,
358 Lock,
359 Mid,
360 V,
361 Root,
362 LockValue,
363 MidValue,
364 Value,
365 MutRoot,
366 MutLock,
367 MutMid,
368 MutValue,
369 G1,
370 S1,
371 L,
372 G2,
373 S2,
374 >
375where
376 Root: std::borrow::Borrow<R>,
377 LockValue: std::borrow::Borrow<Lock>,
378 MidValue: std::borrow::Borrow<Mid>,
379 Value: std::borrow::Borrow<V>,
380 MutRoot: std::borrow::BorrowMut<R>,
381 MutLock: std::borrow::BorrowMut<Lock>,
382 MutMid: std::borrow::BorrowMut<Mid>,
383 MutValue: std::borrow::BorrowMut<V>,
384 G1: Fn(Root) -> Option<LockValue> + Clone,
385 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
386 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
387 G2: Fn(MidValue) -> Option<Value> + Clone,
388 S2: Fn(MutMid) -> Option<MutValue> + Clone,
389{
390 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391 f.debug_struct("AsyncLockKp")
392 .field("root_ty", &std::any::type_name::<R>())
393 .field("lock_ty", &std::any::type_name::<Lock>())
394 .field("mid_ty", &std::any::type_name::<Mid>())
395 .field("value_ty", &std::any::type_name::<V>())
396 .finish_non_exhaustive()
397 }
398}
399
400impl<
401 R,
402 Lock,
403 Mid,
404 V,
405 Root,
406 LockValue,
407 MidValue,
408 Value,
409 MutRoot,
410 MutLock,
411 MutMid,
412 MutValue,
413 G1,
414 S1,
415 L,
416 G2,
417 S2,
418> fmt::Display
419 for AsyncLockKp<
420 R,
421 Lock,
422 Mid,
423 V,
424 Root,
425 LockValue,
426 MidValue,
427 Value,
428 MutRoot,
429 MutLock,
430 MutMid,
431 MutValue,
432 G1,
433 S1,
434 L,
435 G2,
436 S2,
437 >
438where
439 Root: std::borrow::Borrow<R>,
440 LockValue: std::borrow::Borrow<Lock>,
441 MidValue: std::borrow::Borrow<Mid>,
442 Value: std::borrow::Borrow<V>,
443 MutRoot: std::borrow::BorrowMut<R>,
444 MutLock: std::borrow::BorrowMut<Lock>,
445 MutMid: std::borrow::BorrowMut<Mid>,
446 MutValue: std::borrow::BorrowMut<V>,
447 G1: Fn(Root) -> Option<LockValue> + Clone,
448 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
449 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
450 G2: Fn(MidValue) -> Option<Value> + Clone,
451 S2: Fn(MutMid) -> Option<MutValue> + Clone,
452{
453 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
454 write!(
455 f,
456 "AsyncLockKp<{}, {}, {}, {}>",
457 std::any::type_name::<R>(),
458 std::any::type_name::<Lock>(),
459 std::any::type_name::<Mid>(),
460 std::any::type_name::<V>()
461 )
462 }
463}
464
465impl<
466 R,
467 Lock,
468 Mid,
469 V,
470 Root,
471 LockValue,
472 MidValue,
473 Value,
474 MutRoot,
475 MutLock,
476 MutMid,
477 MutValue,
478 G1,
479 S1,
480 L,
481 G2,
482 S2,
483>
484 AsyncLockKp<
485 R,
486 Lock,
487 Mid,
488 V,
489 Root,
490 LockValue,
491 MidValue,
492 Value,
493 MutRoot,
494 MutLock,
495 MutMid,
496 MutValue,
497 G1,
498 S1,
499 L,
500 G2,
501 S2,
502 >
503where
504 Root: std::borrow::Borrow<R>,
505 LockValue: std::borrow::Borrow<Lock>,
506 MidValue: std::borrow::Borrow<Mid>,
507 Value: std::borrow::Borrow<V>,
508 MutRoot: std::borrow::BorrowMut<R>,
509 MutLock: std::borrow::BorrowMut<Lock>,
510 MutMid: std::borrow::BorrowMut<Mid>,
511 MutValue: std::borrow::BorrowMut<V>,
512 G1: Fn(Root) -> Option<LockValue> + Clone,
513 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
514 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
515 G2: Fn(MidValue) -> Option<Value> + Clone,
516 S2: Fn(MutMid) -> Option<MutValue> + Clone,
517{
518 pub fn new(
520 prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
521 mid: L,
522 next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
523 ) -> Self {
524 Self { prev, mid, next }
525 }
526
527 #[inline]
541 pub async fn get(&self, root: Root) -> Option<Value>
542 where
543 Lock: Clone,
544 {
545 let lock_value = (self.prev.get)(root)?;
548 let lock: &Lock = lock_value.borrow();
549 let lock_clone = lock.clone(); let mid_value = self.mid.lock_read(&lock_clone).await?;
553
554 (self.next.get)(mid_value)
556 }
557
558 #[inline]
560 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue>
561 where
562 Lock: Clone,
563 {
564 let mut lock_value = (self.prev.set)(root)?;
566 let lock: &mut Lock = lock_value.borrow_mut();
567 let mut lock_clone = lock.clone(); let mid_value = self.mid.lock_write(&mut lock_clone).await?;
571
572 (self.next.set)(mid_value)
574 }
575
576 #[inline]
578 pub async fn get_optional(&self, root: Option<Root>) -> Option<Value>
579 where
580 Lock: Clone,
581 {
582 match root {
583 Some(r) => self.get(r).await,
584 None => None,
585 }
586 }
587
588 #[inline]
590 pub async fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue>
591 where
592 Lock: Clone,
593 {
594 match root {
595 Some(r) => self.get_mut(r).await,
596 None => None,
597 }
598 }
599
600 #[inline]
602 pub async fn get_or_else<F>(&self, root: Option<Root>, f: F) -> Value
603 where
604 Lock: Clone,
605 F: FnOnce() -> Value,
606 {
607 self.get_optional(root).await.unwrap_or_else(f)
608 }
609
610 #[inline]
612 pub async fn get_mut_or_else<F>(&self, root: Option<MutRoot>, f: F) -> MutValue
613 where
614 Lock: Clone,
615 F: FnOnce() -> MutValue,
616 {
617 self.get_mut_optional(root).await.unwrap_or_else(f)
618 }
619
620 pub async fn set<F>(&self, root: Root, updater: F) -> Result<(), String>
627 where
628 Lock: Clone,
629 F: FnOnce(&mut V),
630 {
631 let lock_value = (self.prev.get)(root).ok_or("Failed to get lock from root")?;
633 let lock: &Lock = lock_value.borrow();
634 let lock_clone = lock.clone(); let mid_value = self
638 .mid
639 .lock_read(&lock_clone)
640 .await
641 .ok_or("Failed to lock")?;
642
643 let mut mut_value = (self.next.set)(mid_value).ok_or("Failed to navigate to value")?;
645 let v: &mut V = mut_value.borrow_mut();
646
647 updater(v);
649
650 Ok(())
651 }
652
653 pub fn then<V2, Value2, MutValue2, G3, S3>(
669 self,
670 next_kp: crate::Kp<V, V2, Value, Value2, MutValue, MutValue2, G3, S3>,
671 ) -> AsyncLockKp<
672 R,
673 Lock,
674 Mid,
675 V2,
676 Root,
677 LockValue,
678 MidValue,
679 Value2,
680 MutRoot,
681 MutLock,
682 MutMid,
683 MutValue2,
684 G1,
685 S1,
686 L,
687 impl Fn(MidValue) -> Option<Value2>
688 + Clone
689 + use<
690 G1,
691 G2,
692 G3,
693 L,
694 Lock,
695 LockValue,
696 Mid,
697 MidValue,
698 MutLock,
699 MutMid,
700 MutRoot,
701 MutValue,
702 MutValue2,
703 R,
704 Root,
705 S1,
706 S2,
707 S3,
708 Value,
709 Value2,
710 V,
711 V2,
712 >,
713 impl Fn(MutMid) -> Option<MutValue2>
714 + Clone
715 + use<
716 G1,
717 G2,
718 G3,
719 L,
720 Lock,
721 LockValue,
722 Mid,
723 MidValue,
724 MutLock,
725 MutMid,
726 MutRoot,
727 MutValue,
728 MutValue2,
729 R,
730 Root,
731 S1,
732 S2,
733 S3,
734 Value,
735 Value2,
736 V,
737 V2,
738 >,
739 >
740 where
741 V: 'static,
742 V2: 'static,
743 Value: std::borrow::Borrow<V>,
744 Value2: std::borrow::Borrow<V2>,
745 MutValue: std::borrow::BorrowMut<V>,
746 MutValue2: std::borrow::BorrowMut<V2>,
747 G3: Fn(Value) -> Option<Value2> + Clone,
748 S3: Fn(MutValue) -> Option<MutValue2> + Clone,
749 {
750 let next_get = self.next.get;
751 let next_set = self.next.set;
752 let second_get = next_kp.get;
753 let second_set = next_kp.set;
754 let chained_kp = crate::Kp::new(
755 move |mid_value: MidValue| next_get(mid_value).and_then(|v| second_get(v)),
756 move |mid_value: MutMid| next_set(mid_value).and_then(|v| second_set(v)),
757 );
758 AsyncLockKp::new(self.prev, self.mid, chained_kp)
759 }
760
761 pub fn then_sync<
764 Lock2,
765 Mid2,
766 V2,
767 LockValue2,
768 MidValue2,
769 Value2,
770 MutLock2,
771 MutMid2,
772 MutValue2,
773 G2_1,
774 S2_1,
775 L2,
776 G2_2,
777 S2_2,
778 >(
779 self,
780 lock_kp: 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 ) -> AsyncLockKpThenSyncKp<
800 R,
801 V2,
802 Root,
803 Value2,
804 MutRoot,
805 MutValue2,
806 Self,
807 crate::sync_kp::SyncKp<
808 V,
809 Lock2,
810 Mid2,
811 V2,
812 Value,
813 LockValue2,
814 MidValue2,
815 Value2,
816 MutValue,
817 MutLock2,
818 MutMid2,
819 MutValue2,
820 G2_1,
821 S2_1,
822 L2,
823 G2_2,
824 S2_2,
825 >,
826 >
827 where
828 V: 'static,
829 V2: 'static,
830 Value: std::borrow::Borrow<V>,
831 Value2: std::borrow::Borrow<V2>,
832 MutValue: std::borrow::BorrowMut<V>,
833 MutValue2: std::borrow::BorrowMut<V2>,
834 LockValue2: std::borrow::Borrow<Lock2>,
835 MidValue2: std::borrow::Borrow<Mid2>,
836 MutLock2: std::borrow::BorrowMut<Lock2>,
837 MutMid2: std::borrow::BorrowMut<Mid2>,
838 G2_1: Fn(Value) -> Option<LockValue2>,
839 S2_1: Fn(MutValue) -> Option<MutLock2>,
840 L2: crate::sync_kp::LockAccess<Lock2, MidValue2> + crate::sync_kp::LockAccess<Lock2, MutMid2>,
841 G2_2: Fn(MidValue2) -> Option<Value2>,
842 S2_2: Fn(MutMid2) -> Option<MutValue2>,
843 {
844 let first = self;
845 let second = lock_kp;
846
847 AsyncLockKpThenSyncKp {
848 first: first,
849 second: second,
850 _p: std::marker::PhantomData,
851 }
852 }
853
854 pub fn then_async<
870 Lock2,
871 Mid2,
872 V2,
873 LockValue2,
874 MidValue2,
875 Value2,
876 MutLock2,
877 MutMid2,
878 MutValue2,
879 G2_1,
880 S2_1,
881 L2,
882 G2_2,
883 S2_2,
884 >(
885 self,
886 other: 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 ) -> ComposedAsyncLockKp<
906 R,
907 V2,
908 Root,
909 Value2,
910 MutRoot,
911 MutValue2,
912 Self,
913 AsyncLockKp<
914 V,
915 Lock2,
916 Mid2,
917 V2,
918 Value,
919 LockValue2,
920 MidValue2,
921 Value2,
922 MutValue,
923 MutLock2,
924 MutMid2,
925 MutValue2,
926 G2_1,
927 S2_1,
928 L2,
929 G2_2,
930 S2_2,
931 >,
932 >
933 where
934 Lock: Clone,
935 Lock2: Clone,
936 V: 'static,
937 V2: 'static,
938 Value: std::borrow::Borrow<V>,
939 LockValue2: std::borrow::Borrow<Lock2>,
940 MidValue2: std::borrow::Borrow<Mid2>,
941 Value2: std::borrow::Borrow<V2>,
942 MutValue: std::borrow::BorrowMut<V>,
943 MutLock2: std::borrow::BorrowMut<Lock2>,
944 MutMid2: std::borrow::BorrowMut<Mid2>,
945 MutValue2: std::borrow::BorrowMut<V2>,
946 G2_1: Fn(Value) -> Option<LockValue2> + Clone,
947 S2_1: Fn(MutValue) -> Option<MutLock2> + Clone,
948 L2: AsyncLockLike<Lock2, MidValue2> + AsyncLockLike<Lock2, MutMid2> + Clone,
949 G2_2: Fn(MidValue2) -> Option<Value2> + Clone,
950 S2_2: Fn(MutMid2) -> Option<MutValue2> + Clone,
951 {
952 let first = self;
953 let second = other;
954
955 ComposedAsyncLockKp {
956 first: first,
957 second: second,
958 _p: std::marker::PhantomData,
959 }
960 }
961}
962
963#[async_trait(?Send)]
965impl<
966 R,
967 Lock,
968 Mid,
969 V,
970 Root,
971 LockValue,
972 MidValue,
973 Value,
974 MutRoot,
975 MutLock,
976 MutMid,
977 MutValue,
978 G1,
979 S1,
980 L,
981 G2,
982 S2,
983> AsyncKeyPathLike<Root, MutRoot>
984 for AsyncLockKp<
985 R,
986 Lock,
987 Mid,
988 V,
989 Root,
990 LockValue,
991 MidValue,
992 Value,
993 MutRoot,
994 MutLock,
995 MutMid,
996 MutValue,
997 G1,
998 S1,
999 L,
1000 G2,
1001 S2,
1002 >
1003where
1004 Root: std::borrow::Borrow<R>,
1005 LockValue: std::borrow::Borrow<Lock>,
1006 MidValue: std::borrow::Borrow<Mid>,
1007 Value: std::borrow::Borrow<V>,
1008 MutRoot: std::borrow::BorrowMut<R>,
1009 MutLock: std::borrow::BorrowMut<Lock>,
1010 MutMid: std::borrow::BorrowMut<Mid>,
1011 MutValue: std::borrow::BorrowMut<V>,
1012 G1: Fn(Root) -> Option<LockValue> + Clone,
1013 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
1014 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
1015 G2: Fn(MidValue) -> Option<Value> + Clone,
1016 S2: Fn(MutMid) -> Option<MutValue> + Clone,
1017 Lock: Clone,
1018{
1019 type Value = Value;
1020 type MutValue = MutValue;
1021 async fn get(&self, root: Root) -> Option<Value> {
1022 AsyncLockKp::get(self, root).await
1023 }
1024 async fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1025 AsyncLockKp::get_mut(self, root).await
1026 }
1027}
1028
1029#[cfg(feature = "tokio")]
1030impl<
1031 R,
1032 Lock,
1033 Mid,
1034 V,
1035 Root,
1036 LockValue,
1037 MidValue,
1038 Value,
1039 MutRoot,
1040 MutLock,
1041 MutMid,
1042 MutValue,
1043 G1,
1044 S1,
1045 L,
1046 G2,
1047 S2,
1048> Readable<Root, Value>
1049 for AsyncLockKp<
1050 R,
1051 Lock,
1052 Mid,
1053 V,
1054 Root,
1055 LockValue,
1056 MidValue,
1057 Value,
1058 MutRoot,
1059 MutLock,
1060 MutMid,
1061 MutValue,
1062 G1,
1063 S1,
1064 L,
1065 G2,
1066 S2,
1067 >
1068where
1069 Root: std::borrow::Borrow<R>,
1070 LockValue: std::borrow::Borrow<Lock>,
1071 MidValue: std::borrow::Borrow<Mid>,
1072 Value: std::borrow::Borrow<V>,
1073 MutRoot: std::borrow::BorrowMut<R>,
1074 MutLock: std::borrow::BorrowMut<Lock>,
1075 MutMid: std::borrow::BorrowMut<Mid>,
1076 MutValue: std::borrow::BorrowMut<V>,
1077 G1: Fn(Root) -> Option<LockValue> + Clone,
1078 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
1079 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
1080 G2: Fn(MidValue) -> Option<Value> + Clone,
1081 S2: Fn(MutMid) -> Option<MutValue> + Clone,
1082 Lock: Clone,
1083{
1084 #[inline]
1085 fn get(&self, root: Root) -> Option<Value> {
1086 block_async(AsyncLockKp::get(self, root))
1087 }
1088}
1089
1090#[cfg(feature = "tokio")]
1091impl<
1092 R,
1093 Lock,
1094 Mid,
1095 V,
1096 Root,
1097 LockValue,
1098 MidValue,
1099 Value,
1100 MutRoot,
1101 MutLock,
1102 MutMid,
1103 MutValue,
1104 G1,
1105 S1,
1106 L,
1107 G2,
1108 S2,
1109> Writable<MutRoot, MutValue>
1110 for AsyncLockKp<
1111 R,
1112 Lock,
1113 Mid,
1114 V,
1115 Root,
1116 LockValue,
1117 MidValue,
1118 Value,
1119 MutRoot,
1120 MutLock,
1121 MutMid,
1122 MutValue,
1123 G1,
1124 S1,
1125 L,
1126 G2,
1127 S2,
1128 >
1129where
1130 Root: std::borrow::Borrow<R>,
1131 LockValue: std::borrow::Borrow<Lock>,
1132 MidValue: std::borrow::Borrow<Mid>,
1133 Value: std::borrow::Borrow<V>,
1134 MutRoot: std::borrow::BorrowMut<R>,
1135 MutLock: std::borrow::BorrowMut<Lock>,
1136 MutMid: std::borrow::BorrowMut<Mid>,
1137 MutValue: std::borrow::BorrowMut<V>,
1138 G1: Fn(Root) -> Option<LockValue> + Clone,
1139 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
1140 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
1141 G2: Fn(MidValue) -> Option<Value> + Clone,
1142 S2: Fn(MutMid) -> Option<MutValue> + Clone,
1143 Lock: Clone,
1144{
1145 #[inline]
1146 fn set(&self, root: MutRoot) -> Option<MutValue> {
1147 block_async(AsyncLockKp::get_mut(self, root))
1148 }
1149}
1150
1151#[derive(Clone)]
1158pub struct ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1159 first: First,
1160 second: Second,
1161 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1162}
1163
1164impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1165 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1166where
1167 First: AsyncKeyPathLike<Root, MutRoot>,
1168 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1169{
1170 pub async fn get(&self, root: Root) -> Option<Value2> {
1172 let value = self.first.get(root).await?;
1173 self.second.get(value).await
1174 }
1175
1176 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1178 let mut_value = self.first.get_mut(root).await?;
1179 self.second.get_mut(mut_value).await
1180 }
1181}
1182
1183#[cfg(feature = "tokio")]
1184impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> Readable<Root, Value2>
1185 for ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1186where
1187 First: AsyncKeyPathLike<Root, MutRoot>,
1188 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1189{
1190 #[inline]
1191 fn get(&self, root: Root) -> Option<Value2> {
1192 block_async(ComposedAsyncLockKp::get(self, root))
1193 }
1194}
1195
1196#[cfg(feature = "tokio")]
1197impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> Writable<MutRoot, MutValue2>
1198 for ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1199where
1200 First: AsyncKeyPathLike<Root, MutRoot>,
1201 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1202{
1203 #[inline]
1204 fn set(&self, root: MutRoot) -> Option<MutValue2> {
1205 block_async(ComposedAsyncLockKp::get_mut(self, root))
1206 }
1207}
1208
1209impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1210 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1211where
1212 First: AsyncKeyPathLike<Root, MutRoot>,
1213 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1214{
1215 pub fn then_async<
1217 Lock3,
1218 Mid3,
1219 V3,
1220 LockValue3,
1221 MidValue3,
1222 Value3,
1223 MutLock3,
1224 MutMid3,
1225 MutValue3,
1226 G3_1,
1227 S3_1,
1228 L3,
1229 G3_2,
1230 S3_2,
1231 >(
1232 self,
1233 other: AsyncLockKp<
1234 V2,
1235 Lock3,
1236 Mid3,
1237 V3,
1238 Value2,
1239 LockValue3,
1240 MidValue3,
1241 Value3,
1242 MutValue2,
1243 MutLock3,
1244 MutMid3,
1245 MutValue3,
1246 G3_1,
1247 S3_1,
1248 L3,
1249 G3_2,
1250 S3_2,
1251 >,
1252 ) -> ComposedAsyncLockKp<
1253 R,
1254 V3,
1255 Root,
1256 Value3,
1257 MutRoot,
1258 MutValue3,
1259 Self,
1260 AsyncLockKp<
1261 V2,
1262 Lock3,
1263 Mid3,
1264 V3,
1265 Value2,
1266 LockValue3,
1267 MidValue3,
1268 Value3,
1269 MutValue2,
1270 MutLock3,
1271 MutMid3,
1272 MutValue3,
1273 G3_1,
1274 S3_1,
1275 L3,
1276 G3_2,
1277 S3_2,
1278 >,
1279 >
1280 where
1281 V2: 'static,
1282 V3: 'static,
1283 Value2: std::borrow::Borrow<V2>,
1284 Value3: std::borrow::Borrow<V3>,
1285 MutValue2: std::borrow::BorrowMut<V2>,
1286 MutValue3: std::borrow::BorrowMut<V3>,
1287 LockValue3: std::borrow::Borrow<Lock3>,
1288 MidValue3: std::borrow::Borrow<Mid3>,
1289 MutLock3: std::borrow::BorrowMut<Lock3>,
1290 MutMid3: std::borrow::BorrowMut<Mid3>,
1291 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
1292 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
1293 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
1294 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
1295 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
1296 Lock3: Clone,
1297 {
1298 let first = self;
1299 let second = other;
1300
1301 ComposedAsyncLockKp {
1302 first: first,
1303 second: second,
1304 _p: std::marker::PhantomData,
1305 }
1306 }
1307
1308 pub fn then<V3, Value3, MutValue3, G3, S3>(
1310 self,
1311 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1312 ) -> AsyncKeyPathThenKp<
1313 R,
1314 V3,
1315 Root,
1316 Value3,
1317 MutRoot,
1318 MutValue3,
1319 Self,
1320 crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1321 >
1322 where
1323 V2: 'static,
1324 V3: 'static,
1325 Value2: std::borrow::Borrow<V2>,
1326 Value3: std::borrow::Borrow<V3>,
1327 MutValue2: std::borrow::BorrowMut<V2>,
1328 MutValue3: std::borrow::BorrowMut<V3>,
1329 G3: Fn(Value2) -> Option<Value3> + Clone,
1330 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1331 {
1332 let first = self;
1333 let second = next_kp;
1334
1335 AsyncKeyPathThenKp {
1336 first: first,
1337 second: second,
1338 _p: std::marker::PhantomData,
1339 }
1340 }
1341
1342 pub fn then_sync<
1344 Lock3,
1345 Mid3,
1346 V3,
1347 LockValue3,
1348 MidValue3,
1349 Value3,
1350 MutLock3,
1351 MutMid3,
1352 MutValue3,
1353 G3_1,
1354 S3_1,
1355 L3,
1356 G3_2,
1357 S3_2,
1358 >(
1359 self,
1360 lock_kp: crate::sync_kp::SyncKp<
1361 V2,
1362 Lock3,
1363 Mid3,
1364 V3,
1365 Value2,
1366 LockValue3,
1367 MidValue3,
1368 Value3,
1369 MutValue2,
1370 MutLock3,
1371 MutMid3,
1372 MutValue3,
1373 G3_1,
1374 S3_1,
1375 L3,
1376 G3_2,
1377 S3_2,
1378 >,
1379 ) -> AsyncLockKpThenSyncKp<
1380 R,
1381 V3,
1382 Root,
1383 Value3,
1384 MutRoot,
1385 MutValue3,
1386 Self,
1387 crate::sync_kp::SyncKp<
1388 V2,
1389 Lock3,
1390 Mid3,
1391 V3,
1392 Value2,
1393 LockValue3,
1394 MidValue3,
1395 Value3,
1396 MutValue2,
1397 MutLock3,
1398 MutMid3,
1399 MutValue3,
1400 G3_1,
1401 S3_1,
1402 L3,
1403 G3_2,
1404 S3_2,
1405 >,
1406 >
1407 where
1408 V2: 'static,
1409 V3: 'static,
1410 Value2: std::borrow::Borrow<V2>,
1411 Value3: std::borrow::Borrow<V3>,
1412 MutValue2: std::borrow::BorrowMut<V2>,
1413 MutValue3: std::borrow::BorrowMut<V3>,
1414 LockValue3: std::borrow::Borrow<Lock3>,
1415 MidValue3: std::borrow::Borrow<Mid3>,
1416 MutLock3: std::borrow::BorrowMut<Lock3>,
1417 MutMid3: std::borrow::BorrowMut<Mid3>,
1418 G3_1: Fn(Value2) -> Option<LockValue3>,
1419 S3_1: Fn(MutValue2) -> Option<MutLock3>,
1420 L3: crate::sync_kp::LockAccess<Lock3, MidValue3> + crate::sync_kp::LockAccess<Lock3, MutMid3>,
1421 G3_2: Fn(MidValue3) -> Option<Value3>,
1422 S3_2: Fn(MutMid3) -> Option<MutValue3>,
1423 {
1424 let first = self;
1425 let second = lock_kp;
1426
1427 AsyncLockKpThenSyncKp {
1428 first: first,
1429 second: second,
1430 _p: std::marker::PhantomData,
1431 }
1432 }
1433}
1434
1435#[derive(Clone)]
1437pub struct KpThenAsyncKeyPath<
1438 R,
1439 V,
1440 V2,
1441 Root,
1442 Value,
1443 Value2,
1444 MutRoot,
1445 MutValue,
1446 MutValue2,
1447 First,
1448 Second,
1449> {
1450 first: First,
1451 second: Second,
1452 _p: std::marker::PhantomData<(R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2)>,
1453}
1454
1455impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1456 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1457{
1458 pub(crate) fn new(first: First, second: Second) -> Self {
1459 Self {
1460 first,
1461 second,
1462 _p: std::marker::PhantomData,
1463 }
1464 }
1465}
1466
1467impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1468 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1469where
1470 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1471 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1472{
1473 #[inline]
1475 pub async fn get(&self, root: Root) -> Option<Value2> {
1476 let v = self.first.sync_get(root)?;
1477 self.second.get(v).await
1478 }
1479 #[inline]
1481 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1482 let mut_v = self.first.sync_get_mut(root)?;
1483 self.second.get_mut(mut_v).await
1484 }
1485}
1486
1487#[cfg(feature = "tokio")]
1488impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1489 Readable<Root, Value2>
1490 for KpThenAsyncKeyPath<
1491 R,
1492 V,
1493 V2,
1494 Root,
1495 Value,
1496 Value2,
1497 MutRoot,
1498 MutValue,
1499 MutValue2,
1500 First,
1501 Second,
1502 >
1503where
1504 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1505 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1506{
1507 #[inline]
1508 fn get(&self, root: Root) -> Option<Value2> {
1509 block_async(KpThenAsyncKeyPath::get(self, root))
1510 }
1511}
1512
1513#[cfg(feature = "tokio")]
1514impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1515 Writable<MutRoot, MutValue2>
1516 for KpThenAsyncKeyPath<
1517 R,
1518 V,
1519 V2,
1520 Root,
1521 Value,
1522 Value2,
1523 MutRoot,
1524 MutValue,
1525 MutValue2,
1526 First,
1527 Second,
1528 >
1529where
1530 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1531 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1532{
1533 #[inline]
1534 fn set(&self, root: MutRoot) -> Option<MutValue2> {
1535 block_async(KpThenAsyncKeyPath::get_mut(self, root))
1536 }
1537}
1538
1539#[async_trait(?Send)]
1540impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1541 AsyncKeyPathLike<Root, MutRoot>
1542 for KpThenAsyncKeyPath<
1543 R,
1544 V,
1545 V2,
1546 Root,
1547 Value,
1548 Value2,
1549 MutRoot,
1550 MutValue,
1551 MutValue2,
1552 First,
1553 Second,
1554 >
1555where
1556 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1557 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1558{
1559 type Value = Value2;
1560 type MutValue = MutValue2;
1561 async fn get(&self, root: Root) -> Option<Value2> {
1562 let v = self.first.sync_get(root)?;
1563 self.second.get(v).await
1564 }
1565 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1566 let mut_v = self.first.sync_get_mut(root)?;
1567 self.second.get_mut(mut_v).await
1568 }
1569}
1570
1571impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1572 KpThenAsyncKeyPath<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
1573where
1574 First: SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
1575 Second: AsyncKeyPathLike<Value, MutValue, Value = Value2, MutValue = MutValue2>,
1576{
1577 pub fn then<V3, Value3, MutValue3, G3, S3>(
1579 self,
1580 next_kp: crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1581 ) -> AsyncKeyPathThenKp<
1582 R,
1583 V3,
1584 Root,
1585 Value3,
1586 MutRoot,
1587 MutValue3,
1588 Self,
1589 crate::Kp<V2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
1590 >
1591 where
1592 V3: 'static,
1593 Value2: std::borrow::Borrow<V2>,
1594 MutValue2: std::borrow::BorrowMut<V2>,
1595 Value3: std::borrow::Borrow<V3>,
1596 MutValue3: std::borrow::BorrowMut<V3>,
1597 G3: Fn(Value2) -> Option<Value3> + Clone,
1598 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
1599 {
1600 let first = self;
1601 let second = next_kp;
1602
1603 AsyncKeyPathThenKp {
1604 first: first,
1605 second: second,
1606 _p: std::marker::PhantomData,
1607 }
1608 }
1609}
1610
1611#[derive(Clone)]
1613pub struct AsyncKeyPathThenKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1614 first: First,
1615 second: Second,
1616 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1617}
1618
1619impl<R, V2, Root, Value2, MutRoot, MutValue2, First, RKp, G, S>
1621 AsyncKeyPathThenKp<
1622 R,
1623 V2,
1624 Root,
1625 Value2,
1626 MutRoot,
1627 MutValue2,
1628 First,
1629 crate::Kp<RKp, V2, First::Value, Value2, First::MutValue, MutValue2, G, S>,
1630 >
1631where
1632 First: AsyncKeyPathLike<Root, MutRoot>,
1633 First::Value: std::borrow::Borrow<RKp>,
1634 First::MutValue: std::borrow::BorrowMut<RKp>,
1635 Value2: std::borrow::Borrow<V2>,
1636 MutValue2: std::borrow::BorrowMut<V2>,
1637 G: Fn(First::Value) -> Option<Value2>,
1638 S: Fn(First::MutValue) -> Option<MutValue2>,
1639{
1640 #[inline]
1642 pub async fn get(&self, root: Root) -> Option<Value2> {
1643 let value = self.first.get(root).await?;
1644 (self.second.get)(value)
1645 }
1646 #[inline]
1648 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1649 let mut_value = self.first.get_mut(root).await?;
1650 (self.second.set)(mut_value)
1651 }
1652}
1653
1654#[cfg(feature = "tokio")]
1655impl<R, V2, Root, Value2, MutRoot, MutValue2, First, RKp, G, S> Readable<Root, Value2>
1656 for AsyncKeyPathThenKp<
1657 R,
1658 V2,
1659 Root,
1660 Value2,
1661 MutRoot,
1662 MutValue2,
1663 First,
1664 crate::Kp<RKp, V2, First::Value, Value2, First::MutValue, MutValue2, G, S>,
1665 >
1666where
1667 First: AsyncKeyPathLike<Root, MutRoot>,
1668 First::Value: std::borrow::Borrow<RKp>,
1669 First::MutValue: std::borrow::BorrowMut<RKp>,
1670 Value2: std::borrow::Borrow<V2>,
1671 MutValue2: std::borrow::BorrowMut<V2>,
1672 G: Fn(First::Value) -> Option<Value2>,
1673 S: Fn(First::MutValue) -> Option<MutValue2>,
1674{
1675 #[inline]
1676 fn get(&self, root: Root) -> Option<Value2> {
1677 block_async(AsyncKeyPathThenKp::get(self, root))
1678 }
1679}
1680
1681#[cfg(feature = "tokio")]
1682impl<R, V2, Root, Value2, MutRoot, MutValue2, First, RKp, G, S> Writable<MutRoot, MutValue2>
1683 for AsyncKeyPathThenKp<
1684 R,
1685 V2,
1686 Root,
1687 Value2,
1688 MutRoot,
1689 MutValue2,
1690 First,
1691 crate::Kp<RKp, V2, First::Value, Value2, First::MutValue, MutValue2, G, S>,
1692 >
1693where
1694 First: AsyncKeyPathLike<Root, MutRoot>,
1695 First::Value: std::borrow::Borrow<RKp>,
1696 First::MutValue: std::borrow::BorrowMut<RKp>,
1697 Value2: std::borrow::Borrow<V2>,
1698 MutValue2: std::borrow::BorrowMut<V2>,
1699 G: Fn(First::Value) -> Option<Value2>,
1700 S: Fn(First::MutValue) -> Option<MutValue2>,
1701{
1702 #[inline]
1703 fn set(&self, root: MutRoot) -> Option<MutValue2> {
1704 block_async(AsyncKeyPathThenKp::get_mut(self, root))
1705 }
1706}
1707
1708#[async_trait(?Send)]
1709impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncKeyPathLike<Root, MutRoot>
1710 for ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
1711where
1712 First: AsyncKeyPathLike<Root, MutRoot>,
1713 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
1714{
1715 type Value = Value2;
1716 type MutValue = MutValue2;
1717 async fn get(&self, root: Root) -> Option<Value2> {
1718 ComposedAsyncLockKp::get(self, root).await
1719 }
1720 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1721 ComposedAsyncLockKp::get_mut(self, root).await
1722 }
1723}
1724
1725#[derive(Clone)]
1732pub struct AsyncLockKpThenSyncKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> {
1733 first: First,
1734 second: Second,
1735 _p: std::marker::PhantomData<(R, V2, Root, Value2, MutRoot, MutValue2)>,
1736}
1737
1738impl<
1739 R,
1740 V2,
1741 Root,
1742 Value2,
1743 MutRoot,
1744 MutValue2,
1745 Lock,
1746 Mid,
1747 V,
1748 LockValue,
1749 MidValue,
1750 Value,
1751 MutLock,
1752 MutMid,
1753 MutValue,
1754 G1,
1755 S1,
1756 L,
1757 G2,
1758 S2,
1759 Lock2,
1760 Mid2,
1761 LockValue2,
1762 MidValue2,
1763 MutLock2,
1764 MutMid2,
1765 G2_1,
1766 S2_1,
1767 L2,
1768 G2_2,
1769 S2_2,
1770>
1771 AsyncLockKpThenSyncKp<
1772 R,
1773 V2,
1774 Root,
1775 Value2,
1776 MutRoot,
1777 MutValue2,
1778 AsyncLockKp<
1779 R,
1780 Lock,
1781 Mid,
1782 V,
1783 Root,
1784 LockValue,
1785 MidValue,
1786 Value,
1787 MutRoot,
1788 MutLock,
1789 MutMid,
1790 MutValue,
1791 G1,
1792 S1,
1793 L,
1794 G2,
1795 S2,
1796 >,
1797 crate::sync_kp::SyncKp<
1798 V,
1799 Lock2,
1800 Mid2,
1801 V2,
1802 Value,
1803 LockValue2,
1804 MidValue2,
1805 Value2,
1806 MutValue,
1807 MutLock2,
1808 MutMid2,
1809 MutValue2,
1810 G2_1,
1811 S2_1,
1812 L2,
1813 G2_2,
1814 S2_2,
1815 >,
1816 >
1817where
1818 Root: std::borrow::Borrow<R>,
1819 LockValue: std::borrow::Borrow<Lock>,
1820 MidValue: std::borrow::Borrow<Mid>,
1821 Value: std::borrow::Borrow<V>,
1822 MutRoot: std::borrow::BorrowMut<R>,
1823 MutLock: std::borrow::BorrowMut<Lock>,
1824 MutMid: std::borrow::BorrowMut<Mid>,
1825 MutValue: std::borrow::BorrowMut<V>,
1826 Value2: std::borrow::Borrow<V2>,
1827 MutValue2: std::borrow::BorrowMut<V2>,
1828 G1: Fn(Root) -> Option<LockValue> + Clone,
1829 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
1830 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
1831 G2: Fn(MidValue) -> Option<Value> + Clone,
1832 S2: Fn(MutMid) -> Option<MutValue> + Clone,
1833 LockValue2: std::borrow::Borrow<Lock2>,
1834 MidValue2: std::borrow::Borrow<Mid2>,
1835 MutLock2: std::borrow::BorrowMut<Lock2>,
1836 MutMid2: std::borrow::BorrowMut<Mid2>,
1837 G2_1: Fn(Value) -> Option<LockValue2>,
1838 S2_1: Fn(MutValue) -> Option<MutLock2>,
1839 L2: crate::sync_kp::LockAccess<Lock2, MidValue2> + crate::sync_kp::LockAccess<Lock2, MutMid2>,
1840 G2_2: Fn(MidValue2) -> Option<Value2>,
1841 S2_2: Fn(MutMid2) -> Option<MutValue2>,
1842 Lock: Clone,
1843{
1844 pub async fn get(&self, root: Root) -> Option<Value2> {
1846 let value = self.first.get(root).await?;
1847 self.second.get(value)
1848 }
1849
1850 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
1852 let mut_value = self.first.get_mut(root).await?;
1853 self.second.get_mut(mut_value)
1854 }
1855
1856 #[cfg(feature = "tokio")]
1858 #[inline]
1859 pub fn get_blocking(&self, root: Root) -> Option<Value2> {
1860 block_async(self.get(root))
1861 }
1862
1863 #[cfg(feature = "tokio")]
1865 #[inline]
1866 pub fn get_mut_blocking(&self, root: MutRoot) -> Option<MutValue2> {
1867 block_async(self.get_mut(root))
1868 }
1869}
1870
1871#[cfg(feature = "tokio")]
1872impl<
1873 R,
1874 V2,
1875 Root,
1876 Value2,
1877 MutRoot,
1878 MutValue2,
1879 Lock,
1880 Mid,
1881 V,
1882 LockValue,
1883 MidValue,
1884 Value,
1885 MutLock,
1886 MutMid,
1887 MutValue,
1888 G1,
1889 S1,
1890 L,
1891 G2,
1892 S2,
1893 Lock2,
1894 Mid2,
1895 LockValue2,
1896 MidValue2,
1897 MutLock2,
1898 MutMid2,
1899 G2_1,
1900 S2_1,
1901 L2,
1902 G2_2,
1903 S2_2,
1904> Readable<Root, Value2>
1905 for AsyncLockKpThenSyncKp<
1906 R,
1907 V2,
1908 Root,
1909 Value2,
1910 MutRoot,
1911 MutValue2,
1912 AsyncLockKp<
1913 R,
1914 Lock,
1915 Mid,
1916 V,
1917 Root,
1918 LockValue,
1919 MidValue,
1920 Value,
1921 MutRoot,
1922 MutLock,
1923 MutMid,
1924 MutValue,
1925 G1,
1926 S1,
1927 L,
1928 G2,
1929 S2,
1930 >,
1931 crate::sync_kp::SyncKp<
1932 V,
1933 Lock2,
1934 Mid2,
1935 V2,
1936 Value,
1937 LockValue2,
1938 MidValue2,
1939 Value2,
1940 MutValue,
1941 MutLock2,
1942 MutMid2,
1943 MutValue2,
1944 G2_1,
1945 S2_1,
1946 L2,
1947 G2_2,
1948 S2_2,
1949 >,
1950 >
1951where
1952 Root: std::borrow::Borrow<R>,
1953 LockValue: std::borrow::Borrow<Lock>,
1954 MidValue: std::borrow::Borrow<Mid>,
1955 Value: std::borrow::Borrow<V>,
1956 MutRoot: std::borrow::BorrowMut<R>,
1957 MutLock: std::borrow::BorrowMut<Lock>,
1958 MutMid: std::borrow::BorrowMut<Mid>,
1959 MutValue: std::borrow::BorrowMut<V>,
1960 Value2: std::borrow::Borrow<V2>,
1961 MutValue2: std::borrow::BorrowMut<V2>,
1962 G1: Fn(Root) -> Option<LockValue> + Clone,
1963 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
1964 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
1965 G2: Fn(MidValue) -> Option<Value> + Clone,
1966 S2: Fn(MutMid) -> Option<MutValue> + Clone,
1967 LockValue2: std::borrow::Borrow<Lock2>,
1968 MidValue2: std::borrow::Borrow<Mid2>,
1969 MutLock2: std::borrow::BorrowMut<Lock2>,
1970 MutMid2: std::borrow::BorrowMut<Mid2>,
1971 G2_1: Fn(Value) -> Option<LockValue2>,
1972 S2_1: Fn(MutValue) -> Option<MutLock2>,
1973 L2: crate::sync_kp::LockAccess<Lock2, MidValue2> + crate::sync_kp::LockAccess<Lock2, MutMid2>,
1974 G2_2: Fn(MidValue2) -> Option<Value2>,
1975 S2_2: Fn(MutMid2) -> Option<MutValue2>,
1976 Lock: Clone,
1977{
1978 #[inline]
1979 fn get(&self, root: Root) -> Option<Value2> {
1980 self.get_blocking(root)
1981 }
1982}
1983
1984#[cfg(feature = "tokio")]
1985impl<
1986 R,
1987 V2,
1988 Root,
1989 Value2,
1990 MutRoot,
1991 MutValue2,
1992 Lock,
1993 Mid,
1994 V,
1995 LockValue,
1996 MidValue,
1997 Value,
1998 MutLock,
1999 MutMid,
2000 MutValue,
2001 G1,
2002 S1,
2003 L,
2004 G2,
2005 S2,
2006 Lock2,
2007 Mid2,
2008 LockValue2,
2009 MidValue2,
2010 MutLock2,
2011 MutMid2,
2012 G2_1,
2013 S2_1,
2014 L2,
2015 G2_2,
2016 S2_2,
2017> Writable<MutRoot, MutValue2>
2018 for AsyncLockKpThenSyncKp<
2019 R,
2020 V2,
2021 Root,
2022 Value2,
2023 MutRoot,
2024 MutValue2,
2025 AsyncLockKp<
2026 R,
2027 Lock,
2028 Mid,
2029 V,
2030 Root,
2031 LockValue,
2032 MidValue,
2033 Value,
2034 MutRoot,
2035 MutLock,
2036 MutMid,
2037 MutValue,
2038 G1,
2039 S1,
2040 L,
2041 G2,
2042 S2,
2043 >,
2044 crate::sync_kp::SyncKp<
2045 V,
2046 Lock2,
2047 Mid2,
2048 V2,
2049 Value,
2050 LockValue2,
2051 MidValue2,
2052 Value2,
2053 MutValue,
2054 MutLock2,
2055 MutMid2,
2056 MutValue2,
2057 G2_1,
2058 S2_1,
2059 L2,
2060 G2_2,
2061 S2_2,
2062 >,
2063 >
2064where
2065 Root: std::borrow::Borrow<R>,
2066 LockValue: std::borrow::Borrow<Lock>,
2067 MidValue: std::borrow::Borrow<Mid>,
2068 Value: std::borrow::Borrow<V>,
2069 MutRoot: std::borrow::BorrowMut<R>,
2070 MutLock: std::borrow::BorrowMut<Lock>,
2071 MutMid: std::borrow::BorrowMut<Mid>,
2072 MutValue: std::borrow::BorrowMut<V>,
2073 Value2: std::borrow::Borrow<V2>,
2074 MutValue2: std::borrow::BorrowMut<V2>,
2075 G1: Fn(Root) -> Option<LockValue> + Clone,
2076 S1: Fn(MutRoot) -> Option<MutLock> + Clone,
2077 L: AsyncLockLike<Lock, MidValue> + AsyncLockLike<Lock, MutMid> + Clone,
2078 G2: Fn(MidValue) -> Option<Value> + Clone,
2079 S2: Fn(MutMid) -> Option<MutValue> + Clone,
2080 LockValue2: std::borrow::Borrow<Lock2>,
2081 MidValue2: std::borrow::Borrow<Mid2>,
2082 MutLock2: std::borrow::BorrowMut<Lock2>,
2083 MutMid2: std::borrow::BorrowMut<Mid2>,
2084 G2_1: Fn(Value) -> Option<LockValue2>,
2085 S2_1: Fn(MutValue) -> Option<MutLock2>,
2086 L2: crate::sync_kp::LockAccess<Lock2, MidValue2> + crate::sync_kp::LockAccess<Lock2, MutMid2>,
2087 G2_2: Fn(MidValue2) -> Option<Value2>,
2088 S2_2: Fn(MutMid2) -> Option<MutValue2>,
2089 Lock: Clone,
2090{
2091 #[inline]
2092 fn set(&self, root: MutRoot) -> Option<MutValue2> {
2093 self.get_mut_blocking(root)
2094 }
2095}
2096
2097impl<
2099 R,
2100 V2,
2101 Root,
2102 Value2,
2103 MutRoot,
2104 MutValue2,
2105 Lock3,
2106 Mid3,
2107 LockValue3,
2108 MidValue3,
2109 MutLock3,
2110 MutMid3,
2111 G3_1,
2112 S3_1,
2113 L3,
2114 G3_2,
2115 S3_2,
2116 First,
2117 Second,
2118>
2119 AsyncLockKpThenSyncKp<
2120 R,
2121 V2,
2122 Root,
2123 Value2,
2124 MutRoot,
2125 MutValue2,
2126 ComposedAsyncLockKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>,
2127 crate::sync_kp::SyncKp<
2128 Value2,
2129 Lock3,
2130 Mid3,
2131 V2,
2132 Value2,
2133 LockValue3,
2134 MidValue3,
2135 Value2,
2136 MutValue2,
2137 MutLock3,
2138 MutMid3,
2139 MutValue2,
2140 G3_1,
2141 S3_1,
2142 L3,
2143 G3_2,
2144 S3_2,
2145 >,
2146 >
2147where
2148 First: AsyncKeyPathLike<Root, MutRoot>,
2149 Second: AsyncKeyPathLike<First::Value, First::MutValue, Value = Value2, MutValue = MutValue2>,
2150 Value2: std::borrow::Borrow<V2>,
2151 MutValue2: std::borrow::BorrowMut<Value2> + std::borrow::BorrowMut<V2>,
2152 LockValue3: std::borrow::Borrow<Lock3>,
2153 MidValue3: std::borrow::Borrow<Mid3>,
2154 MutLock3: std::borrow::BorrowMut<Lock3>,
2155 MutMid3: std::borrow::BorrowMut<Mid3>,
2156 G3_1: Fn(Value2) -> Option<LockValue3>,
2157 S3_1: Fn(MutValue2) -> Option<MutLock3>,
2158 L3: crate::sync_kp::LockAccess<Lock3, MidValue3> + crate::sync_kp::LockAccess<Lock3, MutMid3>,
2159 G3_2: Fn(MidValue3) -> Option<Value2>,
2160 S3_2: Fn(MutMid3) -> Option<MutValue2>,
2161{
2162 pub async fn get(&self, root: Root) -> Option<Value2> {
2164 let value = self.first.get(root).await?;
2165 self.second.get(value)
2166 }
2167 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
2169 let mut_value = self.first.get_mut(root).await?;
2170 self.second.get_mut(mut_value)
2171 }
2172}
2173
2174impl<
2176 R,
2177 V2,
2178 Root,
2179 Value2,
2180 MutRoot,
2181 MutValue2,
2182 Lock3,
2183 Mid3,
2184 LockValue3,
2185 MidValue3,
2186 MutLock3,
2187 MutMid3,
2188 G3_1,
2189 S3_1,
2190 L3,
2191 G3_2,
2192 S3_2,
2193 F,
2194 S,
2195>
2196 AsyncLockKpThenSyncKp<
2197 R,
2198 V2,
2199 Root,
2200 Value2,
2201 MutRoot,
2202 MutValue2,
2203 AsyncLockKpThenSyncKp<R, V2, Root, Value2, MutRoot, MutValue2, F, S>,
2204 crate::sync_kp::SyncKp<
2205 Value2,
2206 Lock3,
2207 Mid3,
2208 V2,
2209 Value2,
2210 LockValue3,
2211 MidValue3,
2212 Value2,
2213 MutValue2,
2214 MutLock3,
2215 MutMid3,
2216 MutValue2,
2217 G3_1,
2218 S3_1,
2219 L3,
2220 G3_2,
2221 S3_2,
2222 >,
2223 >
2224where
2225 F: AsyncKeyPathLike<Root, MutRoot, Value = Value2, MutValue = MutValue2>,
2226 S: SyncKeyPathLike<Value2, Value2, MutValue2, MutValue2>,
2227 Value2: std::borrow::Borrow<V2>,
2228 MutValue2: std::borrow::BorrowMut<Value2> + std::borrow::BorrowMut<V2>,
2229 LockValue3: std::borrow::Borrow<Lock3>,
2230 MidValue3: std::borrow::Borrow<Mid3>,
2231 MutLock3: std::borrow::BorrowMut<Lock3>,
2232 MutMid3: std::borrow::BorrowMut<Mid3>,
2233 G3_1: Fn(Value2) -> Option<LockValue3>,
2234 S3_1: Fn(MutValue2) -> Option<MutLock3>,
2235 L3: crate::sync_kp::LockAccess<Lock3, MidValue3> + crate::sync_kp::LockAccess<Lock3, MutMid3>,
2236 G3_2: Fn(MidValue3) -> Option<Value2>,
2237 S3_2: Fn(MutMid3) -> Option<MutValue2>,
2238{
2239 pub async fn get(&self, root: Root) -> Option<Value2> {
2241 let value = AsyncKeyPathLike::get(&self.first, root).await?;
2242 self.second.get(value)
2243 }
2244 pub async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
2246 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
2247 self.second.get_mut(mut_value)
2248 }
2249}
2250
2251#[async_trait(?Send)]
2253impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second> AsyncKeyPathLike<Root, MutRoot>
2254 for AsyncLockKpThenSyncKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
2255where
2256 First: AsyncKeyPathLike<Root, MutRoot>,
2257 Second: SyncKeyPathLike<First::Value, Value2, First::MutValue, MutValue2>,
2258{
2259 type Value = Value2;
2260 type MutValue = MutValue2;
2261 async fn get(&self, root: Root) -> Option<Value2> {
2262 let value = AsyncKeyPathLike::get(&self.first, root).await?;
2263 SyncKeyPathLike::sync_get(&self.second, value)
2264 }
2265 async fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
2266 let mut_value = AsyncKeyPathLike::get_mut(&self.first, root).await?;
2267 SyncKeyPathLike::sync_get_mut(&self.second, mut_value)
2268 }
2269}
2270
2271impl<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
2273 AsyncLockKpThenSyncKp<R, V2, Root, Value2, MutRoot, MutValue2, First, Second>
2274where
2275 First: AsyncKeyPathLike<Root, MutRoot>,
2276{
2277 pub fn then_async<
2280 Lock3,
2281 Mid3,
2282 V3,
2283 LockValue3,
2284 MidValue3,
2285 Value3,
2286 MutLock3,
2287 MutMid3,
2288 MutValue3,
2289 G3_1,
2290 S3_1,
2291 L3,
2292 G3_2,
2293 S3_2,
2294 >(
2295 self,
2296 other: AsyncLockKp<
2297 Value2,
2298 Lock3,
2299 Mid3,
2300 V3,
2301 Value2,
2302 LockValue3,
2303 MidValue3,
2304 Value3,
2305 MutValue2,
2306 MutLock3,
2307 MutMid3,
2308 MutValue3,
2309 G3_1,
2310 S3_1,
2311 L3,
2312 G3_2,
2313 S3_2,
2314 >,
2315 ) -> ComposedAsyncLockKp<
2316 Root,
2317 V3,
2318 Root,
2319 Value3,
2320 MutRoot,
2321 MutValue3,
2322 Self,
2323 AsyncLockKp<
2324 Value2,
2325 Lock3,
2326 Mid3,
2327 V3,
2328 Value2,
2329 LockValue3,
2330 MidValue3,
2331 Value3,
2332 MutValue2,
2333 MutLock3,
2334 MutMid3,
2335 MutValue3,
2336 G3_1,
2337 S3_1,
2338 L3,
2339 G3_2,
2340 S3_2,
2341 >,
2342 >
2343 where
2344 V2: 'static,
2345 V3: 'static,
2346 Value2: std::borrow::Borrow<V2>,
2347 Value3: std::borrow::Borrow<V3>,
2348 MutValue2: std::borrow::BorrowMut<V2> + std::borrow::BorrowMut<Value2>,
2349 MutValue3: std::borrow::BorrowMut<V3>,
2350 LockValue3: std::borrow::Borrow<Lock3>,
2351 MidValue3: std::borrow::Borrow<Mid3>,
2352 MutLock3: std::borrow::BorrowMut<Lock3>,
2353 MutMid3: std::borrow::BorrowMut<Mid3>,
2354 G3_1: Fn(Value2) -> Option<LockValue3> + Clone,
2355 S3_1: Fn(MutValue2) -> Option<MutLock3> + Clone,
2356 L3: AsyncLockLike<Lock3, MidValue3> + AsyncLockLike<Lock3, MutMid3> + Clone,
2357 G3_2: Fn(MidValue3) -> Option<Value3> + Clone,
2358 S3_2: Fn(MutMid3) -> Option<MutValue3> + Clone,
2359 Lock3: Clone,
2360 {
2361 let first = self;
2362 let second = other;
2363
2364 ComposedAsyncLockKp {
2365 first: first,
2366 second: second,
2367 _p: std::marker::PhantomData,
2368 }
2369 }
2370
2371 pub fn then_sync<
2373 Lock3,
2374 Mid3,
2375 V3,
2376 LockValue3,
2377 MidValue3,
2378 Value3,
2379 MutLock3,
2380 MutMid3,
2381 MutValue3,
2382 G3_1,
2383 S3_1,
2384 L3,
2385 G3_2,
2386 S3_2,
2387 >(
2388 self,
2389 lock_kp: crate::sync_kp::SyncKp<
2390 Value2,
2391 Lock3,
2392 Mid3,
2393 V3,
2394 Value2,
2395 LockValue3,
2396 MidValue3,
2397 Value3,
2398 MutValue2,
2399 MutLock3,
2400 MutMid3,
2401 MutValue3,
2402 G3_1,
2403 S3_1,
2404 L3,
2405 G3_2,
2406 S3_2,
2407 >,
2408 ) -> AsyncLockKpThenSyncKp<
2409 R,
2410 V3,
2411 Root,
2412 Value3,
2413 MutRoot,
2414 MutValue3,
2415 Self,
2416 crate::sync_kp::SyncKp<
2417 Value2,
2418 Lock3,
2419 Mid3,
2420 V3,
2421 Value2,
2422 LockValue3,
2423 MidValue3,
2424 Value3,
2425 MutValue2,
2426 MutLock3,
2427 MutMid3,
2428 MutValue3,
2429 G3_1,
2430 S3_1,
2431 L3,
2432 G3_2,
2433 S3_2,
2434 >,
2435 >
2436 where
2437 V3: 'static,
2438 Value2: std::borrow::Borrow<V2>,
2439 Value3: std::borrow::Borrow<V3>,
2440 MutValue2: std::borrow::BorrowMut<Value2>,
2441 MutValue3: std::borrow::BorrowMut<V3>,
2442 LockValue3: std::borrow::Borrow<Lock3>,
2443 MidValue3: std::borrow::Borrow<Mid3>,
2444 MutLock3: std::borrow::BorrowMut<Lock3>,
2445 MutMid3: std::borrow::BorrowMut<Mid3>,
2446 G3_1: Fn(Value2) -> Option<LockValue3>,
2447 S3_1: Fn(MutValue2) -> Option<MutLock3>,
2448 L3: crate::sync_kp::LockAccess<Lock3, MidValue3> + crate::sync_kp::LockAccess<Lock3, MutMid3>,
2449 G3_2: Fn(MidValue3) -> Option<Value3>,
2450 S3_2: Fn(MutMid3) -> Option<MutValue3>,
2451 {
2452 let first = self;
2453 let second = lock_kp;
2454
2455 AsyncLockKpThenSyncKp {
2456 first: first,
2457 second: second,
2458 _p: std::marker::PhantomData,
2459 }
2460 }
2461
2462 pub fn then<V3, Value3, MutValue3, G3, S3>(
2464 self,
2465 next_kp: crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
2466 ) -> AsyncKeyPathThenKp<
2467 R,
2468 V3,
2469 Root,
2470 Value3,
2471 MutRoot,
2472 MutValue3,
2473 Self,
2474 crate::Kp<Value2, V3, Value2, Value3, MutValue2, MutValue3, G3, S3>,
2475 >
2476 where
2477 V3: 'static,
2478 Value2: std::borrow::Borrow<V2>,
2479 Value3: std::borrow::Borrow<V3>,
2480 MutValue2: std::borrow::BorrowMut<Value2>,
2481 MutValue3: std::borrow::BorrowMut<V3>,
2482 G3: Fn(Value2) -> Option<Value3> + Clone,
2483 S3: Fn(MutValue2) -> Option<MutValue3> + Clone,
2484 {
2485 let first = self;
2486 let second = next_kp;
2487
2488 AsyncKeyPathThenKp {
2489 first: first,
2490 second: second,
2491 _p: std::marker::PhantomData,
2492 }
2493 }
2494}
2495
2496#[cfg(feature = "tokio")]
2501#[derive(Clone)] pub struct TokioMutexAccess<T> {
2509 _phantom: std::marker::PhantomData<T>,
2510}
2511
2512#[cfg(feature = "tokio")]
2513impl<T> TokioMutexAccess<T> {
2514 pub fn new() -> Self {
2515 Self {
2516 _phantom: std::marker::PhantomData,
2517 }
2518 }
2519}
2520
2521#[cfg(feature = "tokio")]
2522impl<T> Default for TokioMutexAccess<T> {
2523 fn default() -> Self {
2524 Self::new()
2525 }
2526}
2527
2528#[cfg(feature = "tokio")]
2530#[async_trait]
2531impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::Mutex<T>>, &'a T>
2532 for TokioMutexAccess<T>
2533{
2534 #[inline]
2535 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
2536 let guard = lock.lock().await;
2538 let ptr = &*guard as *const T;
2539 unsafe { Some(&*ptr) }
2540 }
2541
2542 #[inline]
2543 async fn lock_write(&self, lock: &mut std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a T> {
2544 let guard = lock.lock().await;
2545 let ptr = &*guard as *const T;
2546 unsafe { Some(&*ptr) }
2547 }
2548}
2549
2550#[cfg(feature = "tokio")]
2552#[async_trait]
2553impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::Mutex<T>>, &'a mut T>
2554 for TokioMutexAccess<T>
2555{
2556 #[inline]
2557 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::Mutex<T>>) -> Option<&'a mut T> {
2558 let mut guard = lock.lock().await;
2560 let ptr = &mut *guard as *mut T;
2561 unsafe { Some(&mut *ptr) }
2562 }
2563
2564 #[inline]
2565 async fn lock_write(
2566 &self,
2567 lock: &mut std::sync::Arc<tokio::sync::Mutex<T>>,
2568 ) -> Option<&'a mut T> {
2569 let mut guard = lock.lock().await;
2570 let ptr = &mut *guard as *mut T;
2571 unsafe { Some(&mut *ptr) }
2572 }
2573}
2574
2575#[cfg(feature = "tokio")]
2580pub struct TokioRwLockAccess<T> {
2588 _phantom: std::marker::PhantomData<T>,
2589}
2590
2591#[cfg(feature = "tokio")]
2592impl<T> TokioRwLockAccess<T> {
2593 pub fn new() -> Self {
2594 Self {
2595 _phantom: std::marker::PhantomData,
2596 }
2597 }
2598}
2599
2600#[cfg(feature = "tokio")]
2601impl<T> Default for TokioRwLockAccess<T> {
2602 fn default() -> Self {
2603 Self::new()
2604 }
2605}
2606
2607#[cfg(feature = "tokio")]
2608impl<T> Clone for TokioRwLockAccess<T> {
2609 fn clone(&self) -> Self {
2610 Self {
2611 _phantom: self._phantom,
2612 }
2613 }
2614}
2615
2616#[cfg(feature = "tokio")]
2618#[async_trait]
2619impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::RwLock<T>>, &'a T>
2620 for TokioRwLockAccess<T>
2621{
2622 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
2623 let guard = lock.read().await;
2625 let ptr = &*guard as *const T;
2626 unsafe { Some(&*ptr) }
2627 }
2628
2629 async fn lock_write(&self, lock: &mut std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a T> {
2630 let guard = lock.read().await;
2632 let ptr = &*guard as *const T;
2633 unsafe { Some(&*ptr) }
2634 }
2635}
2636
2637#[cfg(feature = "tokio")]
2639#[async_trait]
2640impl<'a, T: 'static + Send + Sync> AsyncLockLike<std::sync::Arc<tokio::sync::RwLock<T>>, &'a mut T>
2641 for TokioRwLockAccess<T>
2642{
2643 async fn lock_read(&self, lock: &std::sync::Arc<tokio::sync::RwLock<T>>) -> Option<&'a mut T> {
2644 let mut guard = lock.write().await;
2646 let ptr = &mut *guard as *mut T;
2647 unsafe { Some(&mut *ptr) }
2648 }
2649
2650 async fn lock_write(
2651 &self,
2652 lock: &mut std::sync::Arc<tokio::sync::RwLock<T>>,
2653 ) -> Option<&'a mut T> {
2654 let mut guard = lock.write().await;
2656 let ptr = &mut *guard as *mut T;
2657 unsafe { Some(&mut *ptr) }
2658 }
2659}
2660
2661#[cfg(feature = "tokio")]
2669pub type AsyncLockKpMutexFor<Root, Lock, Inner> = AsyncLockKp<
2671 Root,
2672 Lock,
2673 Inner,
2674 Inner,
2675 &'static Root,
2676 &'static Lock,
2677 &'static Inner,
2678 &'static Inner,
2679 &'static mut Root,
2680 &'static mut Lock,
2681 &'static mut Inner,
2682 &'static mut Inner,
2683 for<'b> fn(&'b Root) -> Option<&'b Lock>,
2684 for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
2685 TokioMutexAccess<Inner>,
2686 for<'b> fn(&'b Inner) -> Option<&'b Inner>,
2687 for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
2688>;
2689
2690#[cfg(feature = "tokio")]
2691pub type AsyncLockKpRwLockFor<Root, Lock, Inner> = AsyncLockKp<
2693 Root,
2694 Lock,
2695 Inner,
2696 Inner,
2697 &'static Root,
2698 &'static Lock,
2699 &'static Inner,
2700 &'static Inner,
2701 &'static mut Root,
2702 &'static mut Lock,
2703 &'static mut Inner,
2704 &'static mut Inner,
2705 for<'b> fn(&'b Root) -> Option<&'b Lock>,
2706 for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
2707 TokioRwLockAccess<Inner>,
2708 for<'b> fn(&'b Inner) -> Option<&'b Inner>,
2709 for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
2710>;
2711
2712#[cfg(all(test, feature = "tokio"))]
2717mod tests {
2718 use super::*;
2719 use crate::KpType;
2720
2721 #[tokio::test]
2722 async fn test_async_lock_kp_tokio_mutex_basic() {
2723 use tokio::sync::Mutex;
2724
2725 #[derive(Clone)]
2726 struct Root {
2727 data: std::sync::Arc<Mutex<String>>,
2728 }
2729
2730 let root = Root {
2731 data: std::sync::Arc::new(Mutex::new("hello".to_string())),
2732 };
2733
2734 let lock_kp = {
2736 let prev: KpType<Root, std::sync::Arc<Mutex<String>>> =
2737 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2738 let next: KpType<String, String> =
2739 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
2740 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2741 };
2742
2743 let value = lock_kp.get(&root).await;
2745 assert!(value.is_some());
2746 assert_eq!(value.unwrap(), &"hello".to_string());
2747 }
2748
2749 #[tokio::test]
2750 async fn test_async_lock_kp_get_optional_or_else() {
2751 use tokio::sync::Mutex;
2752
2753 #[derive(Clone)]
2754 struct Root {
2755 data: std::sync::Arc<Mutex<i32>>,
2756 }
2757
2758 let mut root = Root {
2759 data: std::sync::Arc::new(Mutex::new(42)),
2760 };
2761
2762 let lock_kp = {
2763 let prev: KpType<Root, std::sync::Arc<Mutex<i32>>> =
2764 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2765 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2766 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2767 };
2768
2769 assert!(lock_kp.get_optional(None).await.is_none());
2771 assert_eq!(lock_kp.get_optional(Some(&root)).await, Some(&42));
2772
2773 assert!(lock_kp.get_mut_optional(None).await.is_none());
2775 if let Some(m) = lock_kp.get_mut_optional(Some(&mut root)).await {
2776 *m = 99;
2777 }
2778 assert_eq!(lock_kp.get(&root).await, Some(&99));
2779
2780 assert_eq!(*lock_kp.get_or_else(None, || &0).await, 0);
2782 assert_eq!(*lock_kp.get_or_else(Some(&root), || &0).await, 99);
2783
2784 let m = lock_kp
2786 .get_mut_or_else(Some(&mut root), || panic!("unexpected"))
2787 .await;
2788 *m = 100;
2789 assert_eq!(lock_kp.get(&root).await, Some(&100));
2790 }
2791
2792 #[tokio::test]
2793 async fn test_async_lock_kp_tokio_rwlock_basic() {
2794 use tokio::sync::RwLock;
2795
2796 #[derive(Clone)]
2797 struct Root {
2798 data: std::sync::Arc<RwLock<Vec<i32>>>,
2799 }
2800
2801 let root = Root {
2802 data: std::sync::Arc::new(RwLock::new(vec![1, 2, 3, 4, 5])),
2803 };
2804
2805 let lock_kp = {
2807 let prev: KpType<Root, std::sync::Arc<RwLock<Vec<i32>>>> =
2808 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2809 let next: KpType<Vec<i32>, Vec<i32>> =
2810 Kp::new(|v: &Vec<i32>| Some(v), |v: &mut Vec<i32>| Some(v));
2811 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
2812 };
2813
2814 let value = lock_kp.get(&root).await;
2816 assert!(value.is_some());
2817 assert_eq!(value.unwrap().len(), 5);
2818 }
2819
2820 #[tokio::test]
2821 async fn test_async_lock_kp_concurrent_reads() {
2822 use tokio::sync::RwLock;
2823
2824 #[derive(Clone)]
2825 struct Root {
2826 data: std::sync::Arc<RwLock<i32>>,
2827 }
2828
2829 let root = Root {
2830 data: std::sync::Arc::new(RwLock::new(42)),
2831 };
2832
2833 let lock_kp = {
2835 let prev: KpType<Root, std::sync::Arc<RwLock<i32>>> =
2836 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2837 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2838 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
2839 };
2840
2841 let lock_kp2 = {
2844 let prev: KpType<Root, std::sync::Arc<RwLock<i32>>> =
2845 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2846 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
2847 AsyncLockKp::new(prev, TokioRwLockAccess::new(), next)
2848 };
2849 let (a, b) = tokio::join!(lock_kp.get(&root), lock_kp2.get(&root));
2850 assert_eq!(a, Some(&42));
2851 assert_eq!(b, Some(&42));
2852
2853 let value = lock_kp.get(&root).await;
2855 assert_eq!(value, Some(&42));
2856 }
2857
2858 #[tokio::test]
2859 async fn test_async_lock_kp_panic_on_clone_proof() {
2860 use tokio::sync::Mutex;
2861
2862 struct PanicOnClone {
2864 data: String,
2865 }
2866
2867 impl Clone for PanicOnClone {
2868 fn clone(&self) -> Self {
2869 panic!("❌ ASYNC DEEP CLONE DETECTED! PanicOnClone was cloned!");
2870 }
2871 }
2872
2873 #[derive(Clone)]
2874 struct Root {
2875 level1: std::sync::Arc<Mutex<Level1>>,
2876 }
2877
2878 struct Level1 {
2879 panic_data: PanicOnClone,
2880 value: i32,
2881 }
2882
2883 impl Clone for Level1 {
2884 fn clone(&self) -> Self {
2885 panic!("❌ Level1 was deeply cloned in async context!");
2886 }
2887 }
2888
2889 let root = Root {
2891 level1: std::sync::Arc::new(Mutex::new(Level1 {
2892 panic_data: PanicOnClone {
2893 data: "test".to_string(),
2894 },
2895 value: 123,
2896 })),
2897 };
2898
2899 let lock_kp = {
2901 let prev: KpType<Root, std::sync::Arc<Mutex<Level1>>> = Kp::new(
2902 |r: &Root| Some(&r.level1),
2903 |r: &mut Root| Some(&mut r.level1),
2904 );
2905 let next: KpType<Level1, i32> = Kp::new(
2906 |l: &Level1| Some(&l.value),
2907 |l: &mut Level1| Some(&mut l.value),
2908 );
2909 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2910 };
2911
2912 let value = lock_kp.get(&root).await;
2914
2915 assert_eq!(value, Some(&123));
2917 }
2918
2919 #[tokio::test]
2920 async fn test_async_lock_kp_structure() {
2921 use tokio::sync::Mutex;
2922
2923 #[derive(Clone)]
2924 struct Root {
2925 data: std::sync::Arc<Mutex<String>>,
2926 }
2927
2928 let lock_kp = {
2929 let prev: KpType<Root, std::sync::Arc<Mutex<String>>> =
2930 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2931 let next: KpType<String, String> =
2932 Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
2933 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2934 };
2935
2936 let _ = &lock_kp.prev;
2938 let _ = &lock_kp.mid;
2939 let _ = &lock_kp.next;
2940 }
2941
2942 #[tokio::test]
2943 async fn test_async_kp_then() {
2944 use tokio::sync::Mutex;
2945
2946 #[derive(Clone)]
2947 struct Root {
2948 data: std::sync::Arc<Mutex<Inner>>,
2949 }
2950
2951 #[derive(Clone)]
2952 struct Inner {
2953 value: i32,
2954 }
2955
2956 let root = Root {
2957 data: std::sync::Arc::new(Mutex::new(Inner { value: 42 })),
2958 };
2959
2960 let async_kp = {
2962 let prev: KpType<Root, std::sync::Arc<Mutex<Inner>>> =
2963 Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2964 let next: KpType<Inner, Inner> = Kp::new(|i: &Inner| Some(i), |i: &mut Inner| Some(i));
2965 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
2966 };
2967
2968 let value_kp: KpType<Inner, i32> = Kp::new(
2970 |i: &Inner| Some(&i.value),
2971 |i: &mut Inner| Some(&mut i.value),
2972 );
2973
2974 let chained = async_kp.then(value_kp);
2975 let result = chained.get(&root).await;
2976 assert_eq!(result, Some(&42));
2977 }
2978
2979 #[tokio::test]
2980 async fn test_async_kp_later_then() {
2981 use tokio::sync::Mutex;
2982
2983 #[derive(Clone)]
2984 struct Root {
2985 lock1: std::sync::Arc<Mutex<Container>>,
2986 }
2987
2988 #[derive(Clone)]
2989 struct Container {
2990 lock2: std::sync::Arc<Mutex<i32>>,
2991 }
2992
2993 let root = Root {
2994 lock1: std::sync::Arc::new(Mutex::new(Container {
2995 lock2: std::sync::Arc::new(Mutex::new(999)),
2996 })),
2997 };
2998
2999 let async_kp1 = {
3001 let prev: KpType<Root, std::sync::Arc<Mutex<Container>>> =
3002 Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
3003 let next: KpType<Container, Container> =
3004 Kp::new(|c: &Container| Some(c), |c: &mut Container| Some(c));
3005 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
3006 };
3007
3008 let async_kp2 = {
3010 let prev: KpType<Container, std::sync::Arc<Mutex<i32>>> = Kp::new(
3011 |c: &Container| Some(&c.lock2),
3012 |c: &mut Container| Some(&mut c.lock2),
3013 );
3014 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
3015 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
3016 };
3017
3018 let chained = async_kp1.then_async(async_kp2);
3020 let result = chained.get(&root).await;
3021 assert_eq!(result, Some(&999));
3022 }
3023
3024 #[tokio::test]
3025 async fn test_async_kp_then_async_three_levels() {
3026 use tokio::sync::Mutex;
3027
3028 #[derive(Clone)]
3029 struct Root {
3030 a: std::sync::Arc<Mutex<Level1>>,
3031 }
3032 #[derive(Clone)]
3033 struct Level1 {
3034 b: std::sync::Arc<Mutex<Level2>>,
3035 }
3036 #[derive(Clone)]
3037 struct Level2 {
3038 c: std::sync::Arc<Mutex<i32>>,
3039 }
3040
3041 let root = Root {
3042 a: std::sync::Arc::new(Mutex::new(Level1 {
3043 b: std::sync::Arc::new(Mutex::new(Level2 {
3044 c: std::sync::Arc::new(Mutex::new(42)),
3045 })),
3046 })),
3047 };
3048
3049 let kp1 = {
3050 let prev: KpType<Root, std::sync::Arc<Mutex<Level1>>> =
3051 Kp::new(|r: &Root| Some(&r.a), |r: &mut Root| Some(&mut r.a));
3052 let next: KpType<Level1, Level1> =
3053 Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
3054 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
3055 };
3056 let kp2 = {
3057 let prev: KpType<Level1, std::sync::Arc<Mutex<Level2>>> =
3058 Kp::new(|l: &Level1| Some(&l.b), |l: &mut Level1| Some(&mut l.b));
3059 let next: KpType<Level2, Level2> =
3060 Kp::new(|l: &Level2| Some(l), |l: &mut Level2| Some(l));
3061 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
3062 };
3063 let kp3 = {
3064 let prev: KpType<Level2, std::sync::Arc<Mutex<i32>>> =
3065 Kp::new(|l: &Level2| Some(&l.c), |l: &mut Level2| Some(&mut l.c));
3066 let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
3067 AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
3068 };
3069
3070 let chained = kp1.then_async(kp2).then_async(kp3);
3071 let result = chained.get(&root).await;
3072 assert_eq!(result, Some(&42));
3073 }
3074}