1use crate::Condition;
2
3#[derive(Debug)]
4pub struct WaitOptions {
5 pub duration: std::time::Duration,
6 pub poll_frecuency: std::time::Duration,
7}
8
9impl From<u64> for WaitOptions {
10 fn from(seconds: u64) -> Self {
11 let millis = seconds * 1000;
12 Self {
13 duration: std::time::Duration::from_millis(millis),
14 poll_frecuency: std::time::Duration::from_millis(millis / 50),
15 }
16 }
17}
18
19impl From<(u64, u64)> for WaitOptions {
20 fn from((seconds, poll_frecuency): (u64, u64)) -> Self {
21 Self {
22 duration: std::time::Duration::from_secs(seconds),
23 poll_frecuency: std::time::Duration::from_secs(poll_frecuency),
24 }
25 }
26}
27
28impl From<f64> for WaitOptions {
29 fn from(seconds: f64) -> Self {
30 let millis = (seconds * 1000.0).round() as u64;
31 Self {
32 duration: std::time::Duration::from_millis(millis),
33 poll_frecuency: std::time::Duration::from_millis(millis / 50),
34 }
35 }
36}
37
38impl From<(f64, f64)> for WaitOptions {
39 fn from((seconds, poll_frecuency): (f64, f64)) -> Self {
40 let millis = (seconds * 1000.0).round() as u64;
41 let poll_millis = (poll_frecuency * 1000.0).round() as u64;
42 Self {
43 duration: std::time::Duration::from_millis(millis),
44 poll_frecuency: std::time::Duration::from_millis(poll_millis),
45 }
46 }
47}
48
49impl From<std::time::Duration> for WaitOptions {
50 fn from(duration: std::time::Duration) -> Self {
51 Self {
52 duration,
53 poll_frecuency: std::time::Duration::from_millis(
54 (duration.as_millis() / 20).try_into().unwrap(),
55 ),
56 }
57 }
58}
59
60impl From<(std::time::Duration, std::time::Duration)> for WaitOptions {
61 fn from((duration, poll_frecuency): (std::time::Duration, std::time::Duration)) -> Self {
62 Self {
63 duration,
64 poll_frecuency,
65 }
66 }
67}
68
69#[allow(non_snake_case)]
70pub fn Wait<T>(options: T) -> Wait
71where
72 T: Into<WaitOptions>,
73{
74 Wait {
75 options: options.into(),
76 }
77}
78
79#[doc(hidden)]
80#[derive(Debug)]
81pub struct Wait {
82 pub(crate) options: WaitOptions,
83}
84
85impl Wait {
86 #[allow(ungated_async_fn_track_caller)]
89 #[track_caller]
90 #[allow(private_bounds)]
91 pub async fn until(self, condition: impl Into<Condition>) {
92 crate::until_impl(
93 condition.into(),
94 self,
95 #[cfg(feature = "nightly")]
96 std::panic::Location::caller(),
97 )
98 .await;
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn waiter_from_seconds() {
108 let waiter = Wait(10);
109
110 assert_eq!(waiter.options.duration.as_millis(), 10000);
111 assert_eq!(waiter.options.poll_frecuency.as_millis(), 200);
112
113 let waiter = Wait(2);
114
115 assert_eq!(waiter.options.duration.as_millis(), 2000);
116 assert_eq!(waiter.options.poll_frecuency.as_millis(), 40);
117 }
118
119 #[test]
120 fn waiter_from_tuple() {
121 let waiter = Wait((10, 2));
122
123 assert_eq!(waiter.options.duration.as_millis(), 10000);
124 assert_eq!(waiter.options.poll_frecuency.as_millis(), 2000);
125
126 let waiter = Wait((2, 1));
127
128 assert_eq!(waiter.options.duration.as_millis(), 2000);
129 assert_eq!(waiter.options.poll_frecuency.as_millis(), 1000);
130 }
131}