async_time_mock_async_std/
lib.rs

1#![doc = include_str!("../README.md")]
2use async_std::task::sleep;
3use std::future::Future;
4use std::time::{Duration, SystemTime};
5
6mod instant;
7pub use instant::Instant;
8mod timeout_error;
9pub use timeout_error::TimeoutError;
10
11#[cfg(feature = "mock")]
12pub use async_time_mock_core as core;
13
14#[cfg(feature = "interval")]
15mod interval;
16#[cfg(feature = "interval")]
17pub use interval::Interval;
18
19#[derive(Clone)]
20pub enum MockableClock {
21	Real,
22	#[cfg(feature = "mock")]
23	Mock(std::sync::Arc<async_time_mock_core::TimerRegistry>),
24}
25
26pub enum TimeHandlerGuard {
27	Real,
28	#[cfg(feature = "mock")]
29	Mock(async_time_mock_core::TimeHandlerGuard),
30}
31
32#[cfg(feature = "mock")]
33impl From<async_time_mock_core::TimeHandlerGuard> for TimeHandlerGuard {
34	fn from(guard: async_time_mock_core::TimeHandlerGuard) -> Self {
35		Self::Mock(guard)
36	}
37}
38
39impl MockableClock {
40	#[cfg(feature = "mock")]
41	pub fn mock() -> (Self, std::sync::Arc<async_time_mock_core::TimerRegistry>) {
42		let timer_registry = std::sync::Arc::new(async_time_mock_core::TimerRegistry::default());
43		(Self::Mock(timer_registry.clone()), timer_registry)
44	}
45
46	pub fn now(&self) -> Instant {
47		use MockableClock::*;
48		match self {
49			Real => std::time::Instant::now().into(),
50			#[cfg(feature = "mock")]
51			Mock(registry) => registry.now().into(),
52		}
53	}
54
55	pub fn system_time(&self) -> SystemTime {
56		use MockableClock::*;
57		match self {
58			Real => SystemTime::now(),
59			#[cfg(feature = "mock")]
60			Mock(registry) => registry.system_time(),
61		}
62	}
63
64	pub fn sleep(&self, duration: Duration) -> impl Future<Output = TimeHandlerGuard> + Send + 'static {
65		let clock = self.clone();
66		async move {
67			use MockableClock::*;
68			match clock {
69				Real => {
70					sleep(duration).await;
71					TimeHandlerGuard::Real
72				}
73				#[cfg(feature = "mock")]
74				Mock(registry) => registry.sleep(duration).await.into(),
75			}
76		}
77	}
78
79	// AFAIK, async-std doesn't have any functionality equivalent to sleep_until
80
81	#[cfg(feature = "interval")]
82	pub fn interval(&self, period: Duration) -> Interval {
83		use MockableClock::*;
84		match self {
85			Real => async_std::stream::interval(period).into(),
86			#[cfg(feature = "mock")]
87			Mock(registry) => registry.interval(period).into(),
88		}
89	}
90
91	// NOTE: Can't currently transform to -> impl Future because whether it needs to implement `Send` or not depends on the future
92	//       that is passed in.
93	pub async fn timeout<F, T>(&self, duration: Duration, future: F) -> Result<T, TimeoutError>
94	where
95		F: Future<Output = T>,
96	{
97		use MockableClock::*;
98		match self {
99			Real => async_std::future::timeout(duration, future).await.map_err(Into::into),
100			#[cfg(feature = "mock")]
101			Mock(registry) => registry.timeout(duration, future).await.map_err(Into::into),
102		}
103	}
104
105	// AFAIK, async-std doesn't have any functionality equivalent to timeout_at
106}