async_time_mock_smol/
lib.rs1#![doc = include_str!("../README.md")]
2
3use std::future::Future;
4use std::time::{Duration, SystemTime};
5
6mod instant;
7pub use instant::Instant;
8
9mod timer;
10pub use timer::Timer;
11
12#[cfg(feature = "mock")]
13pub use async_time_mock_core as core;
14
15#[derive(Clone)]
16pub enum MockableClock {
17 Real,
18 #[cfg(feature = "mock")]
19 Mock(std::sync::Arc<async_time_mock_core::TimerRegistry>),
20}
21
22pub enum TimeHandlerGuard {
23 Real,
24 #[cfg(feature = "mock")]
25 Mock(async_time_mock_core::TimeHandlerGuard),
26}
27
28#[cfg(feature = "mock")]
29impl From<async_time_mock_core::TimeHandlerGuard> for TimeHandlerGuard {
30 fn from(guard: async_time_mock_core::TimeHandlerGuard) -> Self {
31 Self::Mock(guard)
32 }
33}
34
35impl MockableClock {
36 #[cfg(feature = "mock")]
37 pub fn mock() -> (Self, std::sync::Arc<async_time_mock_core::TimerRegistry>) {
38 let timer_registry = std::sync::Arc::new(async_time_mock_core::TimerRegistry::default());
39 (Self::Mock(timer_registry.clone()), timer_registry)
40 }
41
42 pub fn now(&self) -> Instant {
43 use MockableClock::*;
44 match self {
45 Real => std::time::Instant::now().into(),
46 #[cfg(feature = "mock")]
47 Mock(registry) => registry.now().into(),
48 }
49 }
50
51 pub fn system_time(&self) -> SystemTime {
52 use MockableClock::*;
53 match self {
54 Real => SystemTime::now(),
55 #[cfg(feature = "mock")]
56 Mock(registry) => registry.system_time(),
57 }
58 }
59
60 pub fn sleep(&self, duration: Duration) -> impl Future<Output = TimeHandlerGuard> + Send + 'static {
61 let clock = self.clone();
62 async move {
63 use MockableClock::*;
64 match clock {
65 Real => {
66 async_io::Timer::after(duration).await;
67 TimeHandlerGuard::Real
68 }
69 #[cfg(feature = "mock")]
70 Mock(registry) => registry.sleep(duration).await.into(),
71 }
72 }
73 }
74
75 pub fn sleep_until(&self, until: Instant) -> impl Future<Output = TimeHandlerGuard> + Send + 'static {
76 let clock = self.clone();
77 async move {
78 match (clock, until) {
79 (MockableClock::Real, Instant::Real(until)) => {
80 async_io::Timer::at(until).await;
81 TimeHandlerGuard::Real
82 }
83 #[cfg(feature = "mock")]
84 (MockableClock::Mock(registry), Instant::Mock(until)) => registry.sleep_until(until).await.into(),
85 #[cfg(feature = "mock")]
86 _ => panic!("Clock and instant weren't compatible, both need to be either real or mocked"),
87 }
88 }
89 }
90
91 pub fn interval(&self, period: Duration) -> Timer {
92 use MockableClock::*;
93 match self {
94 Real => async_io::Timer::interval(period).into(),
95 #[cfg(feature = "mock")]
96 Mock(registry) => registry.interval(period).into(),
97 }
98 }
99
100 pub fn interval_at(&self, start: Instant, period: Duration) -> Timer {
101 match (self, start) {
102 (MockableClock::Real, Instant::Real(start)) => async_io::Timer::interval_at(start, period).into(),
103 #[cfg(feature = "mock")]
104 (MockableClock::Mock(registry), Instant::Mock(start)) => registry.interval_at(start, period).into(),
105 #[cfg(feature = "mock")]
106 _ => panic!("Clock and instant weren't compatible, both need to be either real or mocked"),
107 }
108 }
109
110 }