Documentation
pub use fake::{FakeClock, FakeMonotonicClock};

use std::{
    fmt::Debug,
    time::{Instant, SystemTime},
};

mod fake;

/// Simple clock.
#[derive(Debug, Clone)]
pub enum Clock {
    System,
    Fake(FakeClock),
}

impl Default for Clock {
    fn default() -> Self {
        Self::System
    }
}

impl Clock {
    /// Returns the current time.
    pub fn now(&self) -> SystemTime {
        match self {
            Self::System => SystemTime::now(),
            Self::Fake(clock) => clock.now(),
        }
    }
}

impl From<FakeClock> for Clock {
    fn from(value: FakeClock) -> Self {
        Self::Fake(value)
    }
}

/// Monotonic clock.
#[derive(Debug, Clone)]
pub enum MonotonicClock {
    System,
    Fake(FakeMonotonicClock),
}

impl Default for MonotonicClock {
    fn default() -> Self {
        Self::System
    }
}

impl MonotonicClock {
    pub fn now(&self) -> Instant {
        match self {
            Self::System => Instant::now(),
            Self::Fake(clock) => clock.now(),
        }
    }
}

impl From<FakeMonotonicClock> for MonotonicClock {
    fn from(value: FakeMonotonicClock) -> Self {
        Self::Fake(value)
    }
}