web_async/
futures.rs

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		// Frankly I have no idea if this is correct; I hate Pin
35		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		// Frankly I have no idea if this is correct; I hate Pin
59		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}