smol-rs / futures-lite

Futures, streams, and async I/O combinators.
Apache License 2.0
439 stars 25 forks source link

future::Either or something similar? #33

Closed keepsimple1 closed 3 years ago

keepsimple1 commented 3 years ago

This is rather just a question: does this crate support future::Either (here) or something similar? Thanks.

mmstick commented 3 years ago

Use the either crate, and then you can emulate a futures::future::select with:

async fn select<F1, F2, L, R>(future1, future2) -> Either<L, R>
where
    F1: Future<Output = L>,
    F2: Future<Output = R>
{
    let future1 = async move {
        Either::Left(future1.await)
    };

    let future2 = async move {
        Either::Right(future2.await)
    };

    future1.or(future2).await
}
jssblck commented 5 months ago

I came here looking for this functionality so that I could implement something like this:

/// Given an fallible async function that returns a stream where
/// the stream has the same error type as the function that created it,
/// this function "submerges" the fallible function's error (if it occurs)
/// into the stream itself.
///
/// The intention is that this simplifies caller logic: it only has to check for errors in one place.
pub async fn submerge<T, E>(
    result: impl Future<Output = Result<impl Stream<Item = Result<T, E>>, E>>,
) -> impl Stream<Item = Result<T, E>> {
    match result.await {
        Err(err) => stream::once(async { Err(err) }).right_stream(),
        Ok(stream) => stream.left_stream(),
    }
}

Unfortunately, the either crate doesn't type erase in the same way. Is there a nicer way to do this, or am I forced to use futures? A bit unfortunate to have to depend on both that and futures_lite.