timeout-trait 0.8.1

Traits used to wait and timeout.
Documentation
use crate::{
    fugit::{KilohertzU32, RateExtU32},
    *,
};
use std::time::{Duration, Instant};

#[derive(Clone)]
pub struct StdTickInstant(Instant);

impl TickInstant for StdTickInstant {
    #[inline]
    fn frequency() -> KilohertzU32 {
        1.MHz()
    }

    #[inline]
    fn now() -> Self {
        StdTickInstant(Instant::now())
    }

    #[inline]
    fn elapsed(&mut self) -> TickDuration<Self> {
        let ticks = Instant::now().duration_since(self.0).as_micros() as u64;
        TickDuration::from_ticks(ticks)
    }

    #[inline]
    fn move_forward(&mut self, dur: &TickDuration<Self>) {
        self.0 = self
            .0
            .checked_add(Duration::from_micros(dur.as_ticks()))
            .unwrap();
    }
}

#[cfg(test)]
mod tests {
    use crate::TickTimeout;

    use super::*;
    use std::{thread::sleep, time::Duration};

    struct UseTimeout<T: TickInstant> {
        interval: TickTimeout<T>,
    }

    fn test_timeout<T: TickInstant>() {
        let mut t = TickTimeout::<T>::millis(500);
        assert!(!t.timeout());
        sleep(Duration::from_millis(260));
        assert!(!t.timeout());
        sleep(Duration::from_millis(260));
        assert!(t.timeout());
        assert!(!t.timeout());

        t.restart();
        assert!(!t.timeout());
        sleep(Duration::from_millis(260));
        assert!(!t.timeout());
        sleep(Duration::from_millis(260));
        assert!(t.timeout());
        assert!(!t.timeout());

        let dur = TickDuration::<T>::nanos(100);
        assert!(T::now().timeout_with(&dur, || {
            sleep(Duration::from_nanos(1));
            true
        }));

        let mut u = UseTimeout {
            interval: TickTimeout::<T>::millis(1),
        };
        u.interval.timeout();
    }

    #[test]
    fn tick_timeout() {
        test_timeout::<StdTickInstant>();
    }

    #[test]
    fn tick_instant() {
        let mut now = StdTickInstant::now();
        sleep(Duration::from_millis(200));
        assert!(now.elapsed().as_ticks() - 200_000 < 1000);
    }
}