object_rainbow/
nested_mut.rs1use std::{
2 ops::{Deref, DerefMut},
3 pin::Pin,
4 task::{Context, Poll, ready},
5};
6
7use futures_channel::oneshot;
8use futures_util::{FutureExt, future::BoxFuture};
9
10struct NestedGuard<'a, T> {
11 original: &'a mut T,
12 returned: oneshot::Receiver<T>,
13}
14
15impl<T> Drop for NestedGuard<'_, T> {
16 fn drop(&mut self) {
17 if let Ok(Some(returned)) = self.returned.try_recv() {
18 *self.original = returned;
19 }
20 }
21}
22
23struct Lent<T> {
24 value: T,
25 return_to: oneshot::Sender<T>,
26}
27
28impl<T> Deref for Lent<T> {
29 type Target = T;
30
31 fn deref(&self) -> &Self::Target {
32 &self.value
33 }
34}
35
36impl<T> DerefMut for Lent<T> {
37 fn deref_mut(&mut self) -> &mut Self::Target {
38 &mut self.value
39 }
40}
41
42impl<T> Lent<T> {
43 fn finish(self) {
44 self.return_to.send(self.value).ok();
45 }
46}
47
48pub struct Borrower<T>(oneshot::Sender<Lent<T>>);
49
50impl<'a, T: Clone> NestedGuard<'a, T> {
51 fn new(original: &'a mut T, borrower: Borrower<T>) -> Self {
52 let (return_to, returned) = oneshot::channel();
53 borrower
54 .0
55 .send(Lent {
56 value: original.clone(),
57 return_to,
58 })
59 .ok();
60 Self { original, returned }
61 }
62}
63
64pub trait LendTo: Clone {
65 fn lend_to<T>(&mut self, borrower: Borrower<Self>) -> impl Future<Output = T> {
66 async move {
67 let _guard = NestedGuard::new(self, borrower);
68 std::future::pending().await
69 }
70 }
71}
72
73impl<T: Clone> LendTo for T {}
74
75pub struct NestedMut<'a, T> {
76 lent: Option<Lent<T>>,
77 _guard: oneshot::Receiver<BoxFuture<'a, object_rainbow::Result<()>>>,
78}
79
80impl<T> Deref for NestedMut<'_, T> {
81 type Target = T;
82
83 fn deref(&self) -> &Self::Target {
84 self.lent.as_ref().expect("invalid state")
85 }
86}
87
88impl<T> DerefMut for NestedMut<'_, T> {
89 fn deref_mut(&mut self) -> &mut Self::Target {
90 self.lent.as_mut().expect("invalid state")
91 }
92}
93
94impl<T> Drop for NestedMut<'_, T> {
95 fn drop(&mut self) {
96 self.lent.take().expect("invalid state").finish();
97 }
98}
99
100struct WaitingLease<'a, T> {
101 borrowing: oneshot::Receiver<Lent<T>>,
102 future: Option<BoxFuture<'a, object_rainbow::Result<()>>>,
103}
104
105impl<'a, T> Future for WaitingLease<'a, T> {
106 type Output = object_rainbow::Result<Option<NestedMut<'a, T>>>;
107
108 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
109 let this = self.get_mut();
110 if this
111 .future
112 .as_mut()
113 .expect("invalid state")
114 .poll_unpin(cx)?
115 .is_ready()
116 {
117 Poll::Ready(Ok(None))
118 } else {
119 let Ok(lent) = ready!(this.borrowing.poll_unpin(cx)) else {
120 return Poll::Ready(Ok(None));
121 };
122 Poll::Ready(Ok(Some(NestedMut::new(
123 lent,
124 this.future.take().expect("invalid state"),
125 ))))
126 }
127 }
128}
129
130impl<'a, T> NestedMut<'a, T> {
131 fn new(lent: Lent<T>, future: BoxFuture<'a, object_rainbow::Result<()>>) -> Self {
132 let (send, recv) = oneshot::channel();
133 send.send(future).ok();
134 Self {
135 lent: Some(lent),
136 _guard: recv,
137 }
138 }
139
140 pub async fn from_fn<F: 'a + Send + Future<Output = object_rainbow::Result<()>>>(
141 f: impl FnOnce(Borrower<T>) -> F,
142 ) -> object_rainbow::Result<Option<Self>> {
143 let (lending, borrowing) = oneshot::channel();
144 let future = f(Borrower(lending)).boxed();
145 WaitingLease {
146 borrowing,
147 future: Some(future),
148 }
149 .await
150 }
151}