devtime 0.2.0

Wrappers for real and fake time for use same code for fast time tests and for real time in production
Documentation
use std::collections::VecDeque;
use std::ops::Add;
use std::time::{Duration, Instant, SystemTime};

pub(crate) trait Signal {
    fn signal(&self);
}

pub(crate) struct Sleeper<S: Signal> {
    pub(crate) monotonic: Instant,
    pub(crate) signal: S,
}

pub(crate) struct SleepWaiter<S: Signal> {
    pub(crate) count: usize,
    pub(crate) signal: S,
}

pub(crate) struct FakeTimeState<S: Signal> {
    monotonic: Instant,
    real: SystemTime,
    sleepers: VecDeque<Sleeper<S>>,
    sleep_waiters: Vec<SleepWaiter<S>>,
}

impl<S: Signal> FakeTimeState<S> {
    pub(crate) fn monotonic(&self) -> Instant {
        return self.monotonic;
    }

    pub(crate) fn real(&self) -> SystemTime {
        return self.real;
    }

    pub(crate) fn add_sleeper(&mut self, waiter: Sleeper<S>) {
        match self
            .sleepers
            .binary_search_by(|item| item.monotonic.cmp(&waiter.monotonic))
        {
            Ok(index) | Err(index) => self.sleepers.insert(index, waiter),
        };
        self.fire_sleep_waiters();
        self.fire_sleepers();
    }

    pub(crate) fn add_sleep_waiter(&mut self, waiter: SleepWaiter<S>) {
        self.sleep_waiters.push(waiter);
        self.fire_sleep_waiters();
    }

    pub(crate) fn advance(&mut self, duration: Duration) {
        self.monotonic = self.monotonic.add(duration);
        self.real = self.real.add(duration);

        self.fire_sleepers();
    }

    fn fire_sleepers(&mut self) {
        loop {
            if let Some(earliest) = self.sleepers.front() {
                if earliest.monotonic <= self.monotonic {
                    earliest.signal.signal();
                    self.sleepers.pop_front();
                    self.fire_sleep_waiters();
                } else {
                    break;
                }
            } else {
                break;
            }
        }
    }

    fn fire_sleep_waiters(&mut self) {
        let sleepers_count = self.sleepers.len();
        let waiters_count = self.sleep_waiters.len();
        for k in 0..waiters_count {
            let index = waiters_count - k - 1;
            if self.sleep_waiters[index].count == sleepers_count {
                let waiter = self.sleep_waiters.remove(index);
                waiter.signal.signal();
            }
        }
    }
}

impl<S: Signal> Default for FakeTimeState<S> {
    fn default() -> Self {
        return FakeTimeState {
            monotonic: Instant::now(),
            real: SystemTime::UNIX_EPOCH,
            sleepers: Default::default(),
            sleep_waiters: Default::default(),
        };
    }
}