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