use std::time::Duration as StdDuration;
use chrono::{
DateTime,
Utc,
};
use crate::sleep::MockSleeper;
use crate::{
ControllableClock,
MockClock,
MockTimeError,
MockTimeline,
};
#[derive(Debug, Clone)]
pub struct MockTime {
timeline: MockTimeline,
clock: MockClock,
sleeper: MockSleeper,
}
impl MockTime {
#[must_use]
pub fn at(start: DateTime<Utc>) -> Self {
let timeline = MockTimeline::new();
let clock = MockClock::with_timeline(start, timeline.clone());
let sleeper = MockSleeper::with_timeline(timeline.clone());
Self {
timeline,
clock,
sleeper,
}
}
#[must_use]
pub fn unix_epoch() -> Self {
Self::at(DateTime::<Utc>::UNIX_EPOCH)
}
#[inline]
pub fn timeline(&self) -> MockTimeline {
self.timeline.clone()
}
#[inline]
pub fn clock(&self) -> MockClock {
self.clock.clone()
}
#[inline]
pub fn sleeper(&self) -> MockSleeper {
self.sleeper.clone()
}
#[inline]
pub fn elapsed(&self) -> StdDuration {
self.timeline.elapsed()
}
#[inline]
pub fn advance(&self, duration: StdDuration) {
self.timeline.advance(duration);
}
#[inline]
pub fn set_time(&self, instant: DateTime<Utc>) {
self.clock.set_time(instant);
}
pub fn reset(&self) -> Result<(), MockTimeError> {
self.timeline.reset()?;
self.clock.reset_wall_anchor();
Ok(())
}
}