diff --git a/Cargo.toml b/Cargo.toml index 3190d22..7f1910b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ edition = "2018" [dependencies] pin-utils = "=0.1.0-alpha.4" +async-trait = "0.1.3" [dependencies.futures] version = "=0.3.0-alpha.17" diff --git a/examples/future.rs b/examples/future.rs index 6cbabc4..8f15eed 100644 --- a/examples/future.rs +++ b/examples/future.rs @@ -6,8 +6,8 @@ use futures::executor; fn main() { executor::block_on(async { let future = ready(Ok::(1)); - let future = and_then(future, |x| ready(Ok::(x + 3))); - let future = inspect(future, |x| { dbg!(x); }); + let future = future.and_then(|x| ready(Ok::(x + 3))); + let future = future.inspect(|x| { dbg!(x); }); assert_eq!(future.await, Ok(4)); }); } diff --git a/src/future.rs b/src/future.rs index f8d6f9a..90a4745 100644 --- a/src/future.rs +++ b/src/future.rs @@ -1,99 +1,122 @@ -use futures::future::Future; +use core::future::Future; use futures::stream::Stream; - use core::task::{Poll, Context}; +use async_trait::async_trait; pub async fn ready(value: T) -> T { value } -pub async fn map(future: Fut, f: F) -> U - where F: FnOnce(Fut::Output) -> U, - Fut: Future, -{ - f(future.await) -} +impl FutureExt for T where T: Future {} -pub async fn then(future: FutA, f: F) -> FutB::Output - where F: FnOnce(FutA::Output) -> FutB, - FutA: Future, - FutB: Future, -{ - let new_future = f(future.await); - new_future.await -} +#[async_trait] +pub trait FutureExt: Future { + async fn map(self, f: F) -> U + where F: FnOnce(Self::Output) -> U + Send, + Self: Sized, + { + f(self.await) + } -pub async fn and_then(future: FutA, f: F) -> Result - where F: FnOnce(T) -> FutB, - FutA: Future>, - FutB: Future>, -{ - match future.await { - Ok(ok) => { - let new_future = f(ok); - new_future.await - }, - Err(err) => Err(err), + async fn then(self, f: F) -> Fut::Output + where F: FnOnce(Self::Output) -> Fut + Send, + Fut: Future + Send, + Self: Sized, + { + let new_future = f(self.await); + new_future.await } -} -pub async fn or_else(future: FutA, f: F) -> Result - where F: FnOnce(E) -> FutB, - FutA: Future>, - FutB: Future>, -{ - match future.await { - Ok(ok) => Ok(ok), - Err(err) => { - let new_future = f(err); - new_future.await - }, + async fn flatten(self) -> ::Output + where Self::Output: Future + Send, + Self: Sized, + { + let nested_future = self.await; + nested_future.await } -} -pub async fn map_ok(future: Fut, f: F) -> Result - where F: FnOnce(T) -> U, - Fut: Future>, -{ - future.await.map(f) + async fn inspect(self, f: F) -> Self::Output + where F: FnOnce(&Self::Output) + Send, + Self: Sized, + { + let future_result = self.await; + f(&future_result); + future_result + } } -pub async fn map_err(future: Fut, f: F) -> Result - where F: FnOnce(E) -> U, - Fut: Future>, -{ - future.await.map_err(f) -} +impl TryFutureExt for Fut where Fut: Future> {} + +#[async_trait] +pub trait TryFutureExt: Future> { + + async fn and_then(self, f: F) -> Result + where F: FnOnce(T) -> FutB + Send, + FutB: Future> + Send, + Self: Sized, + T: Send + 'async_trait, + E: Send + 'async_trait, + { + match self.await { + Ok(ok) => { + let new_future = f(ok); + new_future.await + }, + Err(err) => Err(err), + } + } -pub async fn flatten(future: FutA) -> FutB::Output - where FutA: Future, - FutB: Future, -{ - let nested_future = future.await; - nested_future.await -} + async fn or_else(self, f: F) -> Result + where F: FnOnce(E) -> FutB + Send, + FutB: Future> + Send, + Self: Sized, + T: Send + 'async_trait, + E: Send + 'async_trait, + { + match self.await { + Ok(ok) => Ok(ok), + Err(err) => { + let new_future = f(err); + new_future.await + }, + } + } -pub async fn inspect(future: Fut, f: F) -> Fut::Output - where Fut: Future, - F: FnOnce(&Fut::Output), -{ - let future_result = future.await; - f(&future_result); - future_result -} + async fn map_ok(self, f: F) -> Result + where F: FnOnce(T) -> U + Send, + Self: Sized, + T: Send + 'async_trait, + E: Send + 'async_trait, + { + self.await.map(f) + } -pub async fn err_into(future: Fut) -> Result - where Fut: Future>, - E: Into, -{ - future.await.map_err(Into::into) -} + async fn map_err(self, f: F) -> Result + where F: FnOnce(E) -> U + Send, + Self: Sized, + T: Send + 'async_trait, + E: Send + 'async_trait, + { + self.await.map_err(f) + } -pub async fn unwrap_or_else(future: Fut, f: F) -> T - where Fut: Future>, - F: FnOnce(E) -> T, -{ - future.await.unwrap_or_else(f) + async fn err_into(self) -> Result + where E: Into, + Self: Sized, + T: Send + 'async_trait, + E: Send + 'async_trait, + { + self.await.map_err(Into::into) + } + + async fn unwrap_or_else(self, f: F) -> T + where F: FnOnce(E) -> T + Send, + Self: Sized, + T: Send + 'async_trait, + E: Send + 'async_trait, + { + self.await.unwrap_or_else(f) + } } pub fn flatten_stream(future: Fut) -> impl Stream @@ -165,7 +188,7 @@ mod tests { fn test_map() { executor::block_on(async { let future = ready(1); - let new_future = map(future, |x| x + 3); + let new_future = future.map(|x| x + 3); assert_eq!(new_future.await, 4); }); } @@ -174,7 +197,7 @@ mod tests { fn test_then() { executor::block_on(async { let future = ready(1); - let new_future = then(future, |x| ready(x + 3)); + let new_future = future.then(|x| ready(x + 3)); assert_eq!(new_future.await, 4); }); } @@ -183,7 +206,7 @@ mod tests { fn test_and_then_ok() { executor::block_on(async { let future = ready(Ok::(1)); - let new_future = and_then(future, |x| ready(Ok::(x + 3))); + let new_future = future.and_then(|x| ready(Ok::(x + 3))); assert_eq!(new_future.await, Ok(4)); }); } @@ -192,7 +215,7 @@ mod tests { fn test_and_then_err() { executor::block_on(async { let future = ready(Err::(1)); - let new_future = and_then(future, |x| ready(Ok::(x + 3))); + let new_future = future.and_then(|x| ready(Ok(x + 3))); assert_eq!(new_future.await, Err(1)); }); } @@ -201,7 +224,7 @@ mod tests { fn test_or_else() { executor::block_on(async { let future = ready(Err::(1)); - let new_future = or_else(future, |x| ready(Err::(x + 3))); + let new_future = future.or_else(|x| ready(Err(x + 3))); assert_eq!(new_future.await, Err(4)); }); } @@ -210,7 +233,7 @@ mod tests { fn test_map_ok() { executor::block_on(async { let future = ready(Ok::(1)); - let new_future = map_ok(future, |x| x + 3); + let new_future = future.map_ok(|x| x + 3); assert_eq!(new_future.await, Ok(4)); }); } @@ -219,7 +242,7 @@ mod tests { fn test_map_err() { executor::block_on(async { let future = ready(Err::(1)); - let new_future = map_err(future, |x| x + 3); + let new_future = future.map_err(|x| x + 3); assert_eq!(new_future.await, Err(4)); }); } @@ -228,7 +251,7 @@ mod tests { fn test_flatten() { executor::block_on(async { let nested_future = ready(ready(1)); - let future = flatten(nested_future); + let future = nested_future.flatten(); assert_eq!(future.await, 1); }); } @@ -237,7 +260,7 @@ mod tests { fn test_inspect() { executor::block_on(async { let future = ready(1); - let new_future = inspect(future, |&x| assert_eq!(x, 1)); + let new_future = future.inspect(|&x| assert_eq!(x, 1)); assert_eq!(new_future.await, 1); }); } @@ -246,7 +269,7 @@ mod tests { fn test_err_into() { executor::block_on(async { let future_err_u8 = ready(Err::<(), u8>(1)); - let future_err_i32 = err_into::<_, _, _, i32>(future_err_u8); + let future_err_i32 = future_err_u8.err_into(); assert_eq!(future_err_i32.await, Err::<(), i32>(1)); }); @@ -256,7 +279,7 @@ mod tests { fn test_unwrap_or_else() { executor::block_on(async { let future = ready(Err::<(), &str>("Boom!")); - let new_future = unwrap_or_else(future, |_| ()); + let new_future = future.unwrap_or_else(|_| ()); assert_eq!(new_future.await, ()); }); }