libp2p_mdns/behaviour/
timer.rs1use std::time::{Duration, Instant};
22
23#[derive(Debug)]
25#[cfg(any(feature = "async-io", feature = "tokio"))]
26pub struct Timer<T> {
27 inner: T,
28}
29
30#[allow(unreachable_pub)] pub trait Builder: Send + Unpin + 'static {
33 fn at(instant: Instant) -> Self;
35
36 fn interval(duration: Duration) -> Self;
38
39 fn interval_at(start: Instant, duration: Duration) -> Self;
41}
42
43#[cfg(feature = "async-io")]
44pub(crate) mod asio {
45 use std::{
46 pin::Pin,
47 task::{Context, Poll},
48 };
49
50 use async_io::Timer as AsioTimer;
51 use futures::Stream;
52
53 use super::*;
54
55 pub(crate) type AsyncTimer = Timer<AsioTimer>;
57 impl Builder for AsyncTimer {
58 fn at(instant: Instant) -> Self {
59 Self {
60 inner: AsioTimer::at(instant),
61 }
62 }
63
64 fn interval(duration: Duration) -> Self {
65 Self {
66 inner: AsioTimer::interval(duration),
67 }
68 }
69
70 fn interval_at(start: Instant, duration: Duration) -> Self {
71 Self {
72 inner: AsioTimer::interval_at(start, duration),
73 }
74 }
75 }
76
77 impl Stream for AsyncTimer {
78 type Item = Instant;
79
80 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
81 Pin::new(&mut self.inner).poll_next(cx)
82 }
83 }
84}
85
86#[cfg(feature = "tokio")]
87pub(crate) mod tokio {
88 use std::{
89 pin::Pin,
90 task::{Context, Poll},
91 };
92
93 use ::tokio::time::{self, Instant as TokioInstant, Interval, MissedTickBehavior};
94 use futures::Stream;
95
96 use super::*;
97
98 pub(crate) type TokioTimer = Timer<Interval>;
100 impl Builder for TokioTimer {
101 fn at(instant: Instant) -> Self {
102 let mut inner = time::interval_at(
104 TokioInstant::from_std(instant),
105 Duration::new(u64::MAX, 1_000_000_000 - 1),
106 );
107 inner.set_missed_tick_behavior(MissedTickBehavior::Skip);
108 Self { inner }
109 }
110
111 fn interval(duration: Duration) -> Self {
112 let mut inner = time::interval_at(TokioInstant::now() + duration, duration);
113 inner.set_missed_tick_behavior(MissedTickBehavior::Skip);
114 Self { inner }
115 }
116
117 fn interval_at(start: Instant, duration: Duration) -> Self {
118 let mut inner = time::interval_at(TokioInstant::from_std(start), duration);
119 inner.set_missed_tick_behavior(MissedTickBehavior::Skip);
120 Self { inner }
121 }
122 }
123
124 impl Stream for TokioTimer {
125 type Item = TokioInstant;
126
127 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
128 self.inner.poll_tick(cx).map(Some)
129 }
130
131 fn size_hint(&self) -> (usize, Option<usize>) {
132 (usize::MAX, None)
133 }
134 }
135}