1use std::future::Future;
2use std::pin::Pin;
3use std::task::{Context, Poll};
4
5pub trait FuturesExt: Future {
6 fn transpose(self) -> Transpose<Self>
7 where
8 Self: Sized,
9 {
10 Transpose { future: self }
11 }
12
13 fn cloned(self) -> Cloned<Self>
14 where
15 Self: Sized,
16 {
17 Cloned { future: self }
18 }
19}
20
21impl<F: Future> FuturesExt for F {}
22
23pub struct Transpose<F> {
24 future: F,
25}
26
27impl<F, T, E> Future for Transpose<F>
28where
29 F: Future<Output = Result<Option<T>, E>>,
30{
31 type Output = Option<Result<T, E>>;
32
33 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
34 let future = unsafe { self.map_unchecked_mut(|s| &mut s.future) };
36
37 match future.poll(cx) {
38 Poll::Ready(Ok(Some(val))) => Poll::Ready(Some(Ok(val))),
39 Poll::Ready(Ok(None)) => Poll::Ready(None),
40 Poll::Ready(Err(err)) => Poll::Ready(Some(Err(err))),
41 Poll::Pending => Poll::Pending,
42 }
43 }
44}
45
46pub struct Cloned<F> {
47 future: F,
48}
49
50impl<F, T> Future for Cloned<F>
51where
52 F: Future<Output = T>,
53 T: Clone,
54{
55 type Output = T;
56
57 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
58 let future = unsafe { self.map_unchecked_mut(|s| &mut s.future) };
60
61 match future.poll(cx) {
62 Poll::Ready(val) => Poll::Ready(val.clone()),
63 Poll::Pending => Poll::Pending,
64 }
65 }
66}