Skip to content

Commit 5191cdb

Browse files
committed
turn combinators into async trait methods
1 parent 0896eeb commit 5191cdb

File tree

3 files changed

+114
-90
lines changed

3 files changed

+114
-90
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ edition = "2018"
1212

1313
[dependencies]
1414
pin-utils = "=0.1.0-alpha.4"
15+
async-trait = "0.1.3"
1516

1617
[dependencies.futures]
1718
version = "=0.3.0-alpha.17"

examples/future.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use futures::executor;
66
fn main() {
77
executor::block_on(async {
88
let future = ready(Ok::<i32, i32>(1));
9-
let future = and_then(future, |x| ready(Ok::<i32, i32>(x + 3)));
10-
let future = inspect(future, |x| { dbg!(x); });
9+
let future = future.and_then(|x| ready(Ok::<i32, i32>(x + 3)));
10+
let future = future.inspect(|x| { dbg!(x); });
1111
assert_eq!(future.await, Ok(4));
1212
});
1313
}

src/future.rs

+111-88
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,122 @@
1-
use futures::future::Future;
1+
use core::future::Future;
22
use futures::stream::Stream;
3-
43
use core::task::{Poll, Context};
4+
use async_trait::async_trait;
55

66
pub async fn ready<T>(value: T) -> T {
77
value
88
}
99

10-
pub async fn map<Fut, U, F>(future: Fut, f: F) -> U
11-
where F: FnOnce(Fut::Output) -> U,
12-
Fut: Future,
13-
{
14-
f(future.await)
15-
}
10+
impl<T: ?Sized> FutureExt for T where T: Future {}
1611

17-
pub async fn then<FutA, FutB, F>(future: FutA, f: F) -> FutB::Output
18-
where F: FnOnce(FutA::Output) -> FutB,
19-
FutA: Future,
20-
FutB: Future,
21-
{
22-
let new_future = f(future.await);
23-
new_future.await
24-
}
12+
#[async_trait]
13+
pub trait FutureExt: Future {
14+
async fn map<U, F>(self, f: F) -> U
15+
where F: FnOnce(Self::Output) -> U + Send,
16+
Self: Sized,
17+
{
18+
f(self.await)
19+
}
2520

26-
pub async fn and_then<FutA, FutB, F, T, U, E>(future: FutA, f: F) -> Result<U, E>
27-
where F: FnOnce(T) -> FutB,
28-
FutA: Future<Output = Result<T,E>>,
29-
FutB: Future<Output = Result<U,E>>,
30-
{
31-
match future.await {
32-
Ok(ok) => {
33-
let new_future = f(ok);
34-
new_future.await
35-
},
36-
Err(err) => Err(err),
21+
async fn then<Fut, F>(self, f: F) -> Fut::Output
22+
where F: FnOnce(Self::Output) -> Fut + Send,
23+
Fut: Future + Send,
24+
Self: Sized,
25+
{
26+
let new_future = f(self.await);
27+
new_future.await
3728
}
38-
}
3929

40-
pub async fn or_else<FutA, FutB, F, T, E, U>(future: FutA, f: F) -> Result<T, U>
41-
where F: FnOnce(E) -> FutB,
42-
FutA: Future<Output = Result<T,E>>,
43-
FutB: Future<Output = Result<T,U>>,
44-
{
45-
match future.await {
46-
Ok(ok) => Ok(ok),
47-
Err(err) => {
48-
let new_future = f(err);
49-
new_future.await
50-
},
30+
async fn flatten(self) -> <Self::Output as Future>::Output
31+
where Self::Output: Future + Send,
32+
Self: Sized,
33+
{
34+
let nested_future = self.await;
35+
nested_future.await
5136
}
52-
}
5337

54-
pub async fn map_ok<Fut, F, T, U, E>(future: Fut, f: F) -> Result<U, E>
55-
where F: FnOnce(T) -> U,
56-
Fut: Future<Output = Result<T,E>>,
57-
{
58-
future.await.map(f)
38+
async fn inspect<F>(self, f: F) -> Self::Output
39+
where F: FnOnce(&Self::Output) + Send,
40+
Self: Sized,
41+
{
42+
let future_result = self.await;
43+
f(&future_result);
44+
future_result
45+
}
5946
}
6047

61-
pub async fn map_err<Fut, F, T, E, U>(future: Fut, f: F) -> Result<T, U>
62-
where F: FnOnce(E) -> U,
63-
Fut: Future<Output = Result<T,E>>,
64-
{
65-
future.await.map_err(f)
66-
}
48+
impl<T, E, Fut: ?Sized> TryFutureExt<T, E> for Fut where Fut: Future<Output = Result<T, E>> {}
49+
50+
#[async_trait]
51+
pub trait TryFutureExt<T, E>: Future<Output = Result<T, E>> {
52+
53+
async fn and_then<U, F, FutB>(self, f: F) -> Result<U, E>
54+
where F: FnOnce(T) -> FutB + Send,
55+
FutB: Future<Output = Result<U, E>> + Send,
56+
Self: Sized,
57+
T: Send + 'async_trait,
58+
E: Send + 'async_trait,
59+
{
60+
match self.await {
61+
Ok(ok) => {
62+
let new_future = f(ok);
63+
new_future.await
64+
},
65+
Err(err) => Err(err),
66+
}
67+
}
6768

68-
pub async fn flatten<FutA, FutB>(future: FutA) -> FutB::Output
69-
where FutA: Future<Output = FutB>,
70-
FutB: Future,
71-
{
72-
let nested_future = future.await;
73-
nested_future.await
74-
}
69+
async fn or_else<U, F, FutB>(self, f: F) -> Result<T, U>
70+
where F: FnOnce(E) -> FutB + Send,
71+
FutB: Future<Output = Result<T, U>> + Send,
72+
Self: Sized,
73+
T: Send + 'async_trait,
74+
E: Send + 'async_trait,
75+
{
76+
match self.await {
77+
Ok(ok) => Ok(ok),
78+
Err(err) => {
79+
let new_future = f(err);
80+
new_future.await
81+
},
82+
}
83+
}
7584

76-
pub async fn inspect<Fut, F>(future: Fut, f: F) -> Fut::Output
77-
where Fut: Future,
78-
F: FnOnce(&Fut::Output),
79-
{
80-
let future_result = future.await;
81-
f(&future_result);
82-
future_result
83-
}
85+
async fn map_ok<U, F>(self, f: F) -> Result<U, E>
86+
where F: FnOnce(T) -> U + Send,
87+
Self: Sized,
88+
T: Send + 'async_trait,
89+
E: Send + 'async_trait,
90+
{
91+
self.await.map(f)
92+
}
8493

85-
pub async fn err_into<Fut, T, E, U>(future: Fut) -> Result<T,U>
86-
where Fut: Future<Output = Result<T,E>>,
87-
E: Into<U>,
88-
{
89-
future.await.map_err(Into::into)
90-
}
94+
async fn map_err<U, F>(self, f: F) -> Result<T, U>
95+
where F: FnOnce(E) -> U + Send,
96+
Self: Sized,
97+
T: Send + 'async_trait,
98+
E: Send + 'async_trait,
99+
{
100+
self.await.map_err(f)
101+
}
91102

92-
pub async fn unwrap_or_else<Fut, T, E, F>(future: Fut, f: F) -> T
93-
where Fut: Future<Output = Result<T,E>>,
94-
F: FnOnce(E) -> T,
95-
{
96-
future.await.unwrap_or_else(f)
103+
async fn err_into<U>(self) -> Result<T, U>
104+
where E: Into<U>,
105+
Self: Sized,
106+
T: Send + 'async_trait,
107+
E: Send + 'async_trait,
108+
{
109+
self.await.map_err(Into::into)
110+
}
111+
112+
async fn unwrap_or_else<F>(self, f: F) -> T
113+
where F: FnOnce(E) -> T + Send,
114+
Self: Sized,
115+
T: Send + 'async_trait,
116+
E: Send + 'async_trait,
117+
{
118+
self.await.unwrap_or_else(f)
119+
}
97120
}
98121

99122
pub fn flatten_stream<Fut, St, T>(future: Fut) -> impl Stream<Item = T>
@@ -165,7 +188,7 @@ mod tests {
165188
fn test_map() {
166189
executor::block_on(async {
167190
let future = ready(1);
168-
let new_future = map(future, |x| x + 3);
191+
let new_future = future.map(|x| x + 3);
169192
assert_eq!(new_future.await, 4);
170193
});
171194
}
@@ -174,7 +197,7 @@ mod tests {
174197
fn test_then() {
175198
executor::block_on(async {
176199
let future = ready(1);
177-
let new_future = then(future, |x| ready(x + 3));
200+
let new_future = future.then(|x| ready(x + 3));
178201
assert_eq!(new_future.await, 4);
179202
});
180203
}
@@ -183,7 +206,7 @@ mod tests {
183206
fn test_and_then_ok() {
184207
executor::block_on(async {
185208
let future = ready(Ok::<i32, i32>(1));
186-
let new_future = and_then(future, |x| ready(Ok::<i32, i32>(x + 3)));
209+
let new_future = future.and_then(|x| ready(Ok::<i32, i32>(x + 3)));
187210
assert_eq!(new_future.await, Ok(4));
188211
});
189212
}
@@ -192,7 +215,7 @@ mod tests {
192215
fn test_and_then_err() {
193216
executor::block_on(async {
194217
let future = ready(Err::<i32, i32>(1));
195-
let new_future = and_then(future, |x| ready(Ok::<i32, i32>(x + 3)));
218+
let new_future = future.and_then(|x| ready(Ok(x + 3)));
196219
assert_eq!(new_future.await, Err(1));
197220
});
198221
}
@@ -201,7 +224,7 @@ mod tests {
201224
fn test_or_else() {
202225
executor::block_on(async {
203226
let future = ready(Err::<i32, i32>(1));
204-
let new_future = or_else(future, |x| ready(Err::<i32, i32>(x + 3)));
227+
let new_future = future.or_else(|x| ready(Err(x + 3)));
205228
assert_eq!(new_future.await, Err(4));
206229
});
207230
}
@@ -210,7 +233,7 @@ mod tests {
210233
fn test_map_ok() {
211234
executor::block_on(async {
212235
let future = ready(Ok::<i32, i32>(1));
213-
let new_future = map_ok(future, |x| x + 3);
236+
let new_future = future.map_ok(|x| x + 3);
214237
assert_eq!(new_future.await, Ok(4));
215238
});
216239
}
@@ -219,7 +242,7 @@ mod tests {
219242
fn test_map_err() {
220243
executor::block_on(async {
221244
let future = ready(Err::<i32, i32>(1));
222-
let new_future = map_err(future, |x| x + 3);
245+
let new_future = future.map_err(|x| x + 3);
223246
assert_eq!(new_future.await, Err(4));
224247
});
225248
}
@@ -228,7 +251,7 @@ mod tests {
228251
fn test_flatten() {
229252
executor::block_on(async {
230253
let nested_future = ready(ready(1));
231-
let future = flatten(nested_future);
254+
let future = nested_future.flatten();
232255
assert_eq!(future.await, 1);
233256
});
234257
}
@@ -237,7 +260,7 @@ mod tests {
237260
fn test_inspect() {
238261
executor::block_on(async {
239262
let future = ready(1);
240-
let new_future = inspect(future, |&x| assert_eq!(x, 1));
263+
let new_future = future.inspect(|&x| assert_eq!(x, 1));
241264
assert_eq!(new_future.await, 1);
242265
});
243266
}
@@ -246,7 +269,7 @@ mod tests {
246269
fn test_err_into() {
247270
executor::block_on(async {
248271
let future_err_u8 = ready(Err::<(), u8>(1));
249-
let future_err_i32 = err_into::<_, _, _, i32>(future_err_u8);
272+
let future_err_i32 = future_err_u8.err_into();
250273

251274
assert_eq!(future_err_i32.await, Err::<(), i32>(1));
252275
});
@@ -256,7 +279,7 @@ mod tests {
256279
fn test_unwrap_or_else() {
257280
executor::block_on(async {
258281
let future = ready(Err::<(), &str>("Boom!"));
259-
let new_future = unwrap_or_else(future, |_| ());
282+
let new_future = future.unwrap_or_else(|_| ());
260283
assert_eq!(new_future.await, ());
261284
});
262285
}

0 commit comments

Comments
 (0)