Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
kpp committed Jul 24, 2019
1 parent bde6922 commit 1191ca4
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 54 deletions.
2 changes: 1 addition & 1 deletion examples/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use futures::executor;
fn main() {
executor::block_on(async {
let future = ready(Ok::<i32, i32>(1));
let future = and_then(future, |x| ready(Ok::<i32, i32>(x + 3)));
let future = future.and_then(|x| ready(Ok::<i32, i32>(x + 3)));
let future = future.inspect(|x| { dbg!(x); });
assert_eq!(future.await, Ok(4));
});
Expand Down
148 changes: 95 additions & 53 deletions src/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,60 +45,102 @@ pub trait FutureExt: Future {
}
}

pub async fn and_then<FutA, FutB, F, T, U, E>(future: FutA, f: F) -> Result<U, E>
where F: FnOnce(T) -> FutB,
FutA: Future<Output = Result<T,E>>,
FutB: Future<Output = Result<U,E>>,
{
match future.await {
Ok(ok) => {
let new_future = f(ok);
new_future.await
},
Err(err) => Err(err),
}
#[async_trait]
pub trait TryFuture: Future {
type Ok;
type Error;

async fn and_then<U, F, FutB>(self, f: F) -> Result<U, Self::Error>
where F: FnOnce(Self::Ok) -> FutB + Send,
FutB: Future<Output = Result<U, Self::Error>> + Send,
Self: Sized;

async fn or_else<U, F, FutB>(self, f: F) -> Result<Self::Ok, U>
where F: FnOnce(Self::Error) -> FutB + Send,
FutB: Future<Output = Result<Self::Ok, U>> + Send,
Self: Sized;

async fn map_ok<U, F>(self, f: F) -> Result<U, Self::Error>
where F: FnOnce(Self::Ok) -> U + Send,
Self: Sized;

async fn map_err<U, F>(self, f: F) -> Result<Self::Ok, U>
where F: FnOnce(Self::Error) -> U + Send,
Self: Sized;

async fn err_into<U>(self) -> Result<Self::Ok, U>
where Self::Error: Into<U>,
Self: Sized;

async fn unwrap_or_else<F>(self, f: F) -> Self::Ok
where F: FnOnce(Self::Error) -> Self::Ok + Send,
Self: Sized;
}

pub async fn or_else<FutA, FutB, F, T, E, U>(future: FutA, f: F) -> Result<T, U>
where F: FnOnce(E) -> FutB,
FutA: Future<Output = Result<T,E>>,
FutB: Future<Output = Result<T,U>>,
#[async_trait]
impl<T, E, Fut> TryFuture for Fut
where Fut: ?Sized + Future<Output = Result<T, E>> + Send,
T: Send + 'static,
E: Send + 'static,
{
match future.await {
Ok(ok) => Ok(ok),
Err(err) => {
let new_future = f(err);
new_future.await
},
type Ok = T;
type Error = E;

async fn and_then<U, F, FutB>(self, f: F) -> Result<U, Self::Error>
where F: FnOnce(Self::Ok) -> FutB + Send,
FutB: Future<Output = Result<U, Self::Error>> + Send,
Self: Sized
{
match self.await {
Ok(ok) => {
let new_future = f(ok);
new_future.await
},
Err(err) => Err(err),
}
}
}

pub async fn map_ok<Fut, F, T, U, E>(future: Fut, f: F) -> Result<U, E>
where F: FnOnce(T) -> U,
Fut: Future<Output = Result<T,E>>,
{
future.await.map(f)
}
async fn or_else<U, F, FutB>(self, f: F) -> Result<Self::Ok, U>
where F: FnOnce(Self::Error) -> FutB + Send,
FutB: Future<Output = Result<Self::Ok, U>> + Send,
Self: Sized,
{
match self.await {
Ok(ok) => Ok(ok),
Err(err) => {
let new_future = f(err);
new_future.await
},
}
}

pub async fn map_err<Fut, F, T, E, U>(future: Fut, f: F) -> Result<T, U>
where F: FnOnce(E) -> U,
Fut: Future<Output = Result<T,E>>,
{
future.await.map_err(f)
}
async fn map_ok<U, F>(self, f: F) -> Result<U, Self::Error>
where F: FnOnce(Self::Ok) -> U + Send,
Self: Sized
{
self.await.map(f)
}

pub async fn err_into<Fut, T, E, U>(future: Fut) -> Result<T,U>
where Fut: Future<Output = Result<T,E>>,
E: Into<U>,
{
future.await.map_err(Into::into)
}
async fn map_err<U, F>(self, f: F) -> Result<Self::Ok, U>
where F: FnOnce(Self::Error) -> U + Send,
Self: Sized,
{
self.await.map_err(f)
}

pub async fn unwrap_or_else<Fut, T, E, F>(future: Fut, f: F) -> T
where Fut: Future<Output = Result<T,E>>,
F: FnOnce(E) -> T,
{
future.await.unwrap_or_else(f)
async fn err_into<U>(self) -> Result<Self::Ok, U>
where Self::Error: Into<U>,
Self: Sized,
{
self.await.map_err(Into::into)
}

async fn unwrap_or_else<F>(self, f: F) -> Self::Ok
where F: FnOnce(Self::Error) -> Self::Ok + Send,
Self: Sized,
{
self.await.unwrap_or_else(f)
}
}

pub fn flatten_stream<Fut, St, T>(future: Fut) -> impl Stream<Item = T>
Expand Down Expand Up @@ -188,7 +230,7 @@ mod tests {
fn test_and_then_ok() {
executor::block_on(async {
let future = ready(Ok::<i32, i32>(1));
let new_future = and_then(future, |x| ready(Ok::<i32, i32>(x + 3)));
let new_future = future.and_then(|x| ready(Ok::<i32, i32>(x + 3)));
assert_eq!(new_future.await, Ok(4));
});
}
Expand All @@ -197,7 +239,7 @@ mod tests {
fn test_and_then_err() {
executor::block_on(async {
let future = ready(Err::<i32, i32>(1));
let new_future = and_then(future, |x| ready(Ok::<i32, i32>(x + 3)));
let new_future = future.and_then(|x| ready(Ok(x + 3)));
assert_eq!(new_future.await, Err(1));
});
}
Expand All @@ -206,7 +248,7 @@ mod tests {
fn test_or_else() {
executor::block_on(async {
let future = ready(Err::<i32, i32>(1));
let new_future = or_else(future, |x| ready(Err::<i32, i32>(x + 3)));
let new_future = future.or_else(|x| ready(Err(x + 3)));
assert_eq!(new_future.await, Err(4));
});
}
Expand All @@ -215,7 +257,7 @@ mod tests {
fn test_map_ok() {
executor::block_on(async {
let future = ready(Ok::<i32, i32>(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));
});
}
Expand All @@ -224,7 +266,7 @@ mod tests {
fn test_map_err() {
executor::block_on(async {
let future = ready(Err::<i32, i32>(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));
});
}
Expand All @@ -251,7 +293,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));
});
Expand All @@ -261,7 +303,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, ());
});
}
Expand Down

0 comments on commit 1191ca4

Please sign in to comment.