omaha_client_fuchsia/
timer.rs1use fuchsia_async as fasync;
6use futures::future::BoxFuture;
7use futures::prelude::*;
8use omaha_client::time::{PartialComplexTime, Timer};
9use std::cmp::min;
10use std::time::{Duration, Instant, SystemTime};
11
12pub struct FuchsiaTimer;
13impl FuchsiaTimer {
14 #[allow(clippy::or_fun_call)]
17 fn duration_until_system_time(system: SystemTime) -> Duration {
18 system.duration_since(SystemTime::now()).ok().unwrap_or(Duration::from_secs(0))
19 }
20
21 #[allow(clippy::or_fun_call)]
24 fn duration_until_instant(instant: Instant) -> Duration {
25 instant.checked_duration_since(Instant::now()).unwrap_or(Duration::from_secs(0))
26 }
27
28 fn determine_wait_until(time: PartialComplexTime) -> Duration {
29 match time {
30 PartialComplexTime::Wall(w) => Self::duration_until_system_time(w),
31 PartialComplexTime::Monotonic(m) => Self::duration_until_instant(m),
32 PartialComplexTime::Complex(c) => {
33 min(Self::duration_until_system_time(c.wall), Self::duration_until_instant(c.mono))
34 }
35 }
36 }
37}
38impl Timer for FuchsiaTimer {
39 fn wait_until(&mut self, time: impl Into<PartialComplexTime>) -> BoxFuture<'static, ()> {
41 fasync::Timer::new(Self::determine_wait_until(time.into())).boxed()
42 }
43
44 fn wait_for(&mut self, duration: Duration) -> BoxFuture<'static, ()> {
46 fasync::Timer::new(duration).boxed()
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 use fuchsia_async::TestExecutor;
54 use std::task::Poll;
55
56 #[fuchsia::test(allow_stalls = false)]
57 async fn test_timer() {
58 let start_time = fasync::MonotonicInstant::now();
59
60 let mut timer = FuchsiaTimer;
61 let mut future = timer.wait_for(Duration::from_secs(1234));
62 assert_eq!(Poll::Pending, TestExecutor::poll_until_stalled(&mut future).await);
63
64 let future_time = TestExecutor::next_timer().unwrap();
65 TestExecutor::advance_to(future_time).await;
66 assert_eq!(1234, (future_time - start_time).into_seconds());
67
68 let () = future.await;
69 }
70}