asynkit 0.1.0

Abstractions for runtime-independent crates
Documentation
use std::{
    pin::pin,
    time::{Duration, Instant},
};

use futures::FutureExt;

pub trait Time {
    fn sleep(duration: Duration) -> impl Future<Output = ()> + Send;

    fn timeout_at<F: Future>(
        deadline: Instant,
        fut: F,
    ) -> impl Future<Output = Result<F::Output, TimedOut>> {
        let duration = deadline.saturating_duration_since(Instant::now());
        Self::timeout(duration, fut)
    }

    fn timeout<F: Future>(
        duration: Duration,
        fut: F,
    ) -> impl Future<Output = Result<F::Output, TimedOut>> {
        async move {
            let mut sleep = pin!(Self::sleep(duration).fuse());
            let mut fut = pin!(fut.fuse());
            futures::select_biased! {
                result = fut => {
                    Ok(result)
                }
                _ = sleep => {
                    Err(TimedOut {})
                }
            }
        }
    }
}

pub struct TimedOut {}