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