wasi_common/
clocks.rs

1use crate::{Error, ErrorExt};
2use cap_std::time::{Duration, Instant, SystemTime};
3
4pub enum SystemTimeSpec {
5    SymbolicNow,
6    Absolute(SystemTime),
7}
8
9pub trait WasiSystemClock: Send + Sync {
10    fn resolution(&self) -> Duration;
11    fn now(&self, precision: Duration) -> SystemTime;
12}
13
14pub trait WasiMonotonicClock: Send + Sync {
15    fn resolution(&self) -> Duration;
16    fn now(&self, precision: Duration) -> Instant;
17}
18
19pub struct WasiMonotonicOffsetClock {
20    pub creation_time: cap_std::time::Instant,
21    pub abs_clock: Box<dyn WasiMonotonicClock>,
22}
23
24impl WasiMonotonicOffsetClock {
25    pub fn new(clock: impl 'static + WasiMonotonicClock) -> Self {
26        Self {
27            creation_time: clock.now(clock.resolution()),
28            abs_clock: Box::new(clock),
29        }
30    }
31}
32
33pub struct WasiClocks {
34    pub system: Option<Box<dyn WasiSystemClock>>,
35    pub monotonic: Option<WasiMonotonicOffsetClock>,
36}
37
38impl WasiClocks {
39    pub fn new() -> Self {
40        Self {
41            system: None,
42            monotonic: None,
43        }
44    }
45
46    pub fn with_system(mut self, clock: impl 'static + WasiSystemClock) -> Self {
47        self.system = Some(Box::new(clock));
48        self
49    }
50
51    pub fn with_monotonic(mut self, clock: impl 'static + WasiMonotonicClock) -> Self {
52        self.monotonic = Some(WasiMonotonicOffsetClock::new(clock));
53        self
54    }
55
56    pub fn system(&self) -> Result<&dyn WasiSystemClock, Error> {
57        self.system
58            .as_deref()
59            .ok_or_else(|| Error::badf().context("system clock is not supported"))
60    }
61
62    pub fn monotonic(&self) -> Result<&WasiMonotonicOffsetClock, Error> {
63        self.monotonic
64            .as_ref()
65            .ok_or_else(|| Error::badf().context("monotonic clock is not supported"))
66    }
67}