borrow_owned/
asynchronous.rs1use std::{
2 future::Future,
3 ops::{Deref, DerefMut},
4 pin::Pin,
5 task::{Context, Poll},
6};
7
8use futures_channel::oneshot::{self, Receiver, Sender};
9
10#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
12pub trait AsyncBorrowOwned: Sized {
13 fn async_borrow_owned(self) -> (AsyncBorrowed<Self>, AsyncReturn<Self>);
20}
21
22impl<T> AsyncBorrowOwned for T
23where
24 T: Sized,
25{
26 fn async_borrow_owned(self) -> (AsyncBorrowed<Self>, AsyncReturn<Self>) {
27 let (tx, rx) = oneshot::channel();
28
29 let borrowed = AsyncBorrowed {
30 inner: Some((self, tx)),
31 };
32 let ret = AsyncReturn { rx };
33
34 (borrowed, ret)
35 }
36}
37
38#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
40pub struct AsyncReturn<T> {
41 rx: Receiver<T>,
42}
43
44impl<T> Future for AsyncReturn<T> {
45 type Output = T;
46
47 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
48 let rx = Pin::new(&mut self.rx);
49
50 if let Poll::Ready(res) = rx.poll(cx) {
51 Poll::Ready(res.unwrap())
52 } else {
53 Poll::Pending
54 }
55 }
56}
57
58#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
60pub struct AsyncBorrowed<T> {
61 inner: Option<(T, Sender<T>)>,
62}
63
64impl<T> Drop for AsyncBorrowed<T> {
65 fn drop(&mut self) {
66 if let Some((val, tx)) = self.inner.take() {
67 tx.send(val).unwrap_or_default();
68 }
69 }
70}
71
72impl<T> Deref for AsyncBorrowed<T> {
73 type Target = T;
74
75 fn deref(&self) -> &Self::Target {
76 self.inner.as_ref().map(|(val, _)| val).unwrap()
77 }
78}
79
80impl<T> DerefMut for AsyncBorrowed<T> {
81 fn deref_mut(&mut self) -> &mut Self::Target {
82 self.inner.as_mut().map(|(val, _)| val).unwrap()
83 }
84}