1use std::time::Duration;
2
3use thirtyfour::extensions::query::{ElementPollerWithTimeout, IntoElementPoller};
4use typed_builder::TypedBuilder;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TypedBuilder)]
8pub struct ElementQueryWaitConfig {
9 #[builder(setter(into))]
20 timeout: Duration,
21
22 #[builder(setter(into))]
33 interval: Duration,
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
38pub enum ElementQueryWaitConfigError {
39 #[error("Element query wait poll interval must be non-zero.")]
41 ZeroInterval,
42}
43
44impl ElementQueryWaitConfig {
45 #[must_use]
51 pub const fn new(timeout: Duration, interval: Duration) -> Self {
52 Self { timeout, interval }
53 }
54
55 pub fn try_new(
62 timeout: Duration,
63 interval: Duration,
64 ) -> Result<Self, ElementQueryWaitConfigError> {
65 if interval.is_zero() {
66 return Err(ElementQueryWaitConfigError::ZeroInterval);
67 }
68
69 Ok(Self { timeout, interval })
70 }
71
72 #[must_use]
74 pub const fn timeout(self) -> Duration {
75 self.timeout
76 }
77
78 #[must_use]
80 pub const fn interval(self) -> Duration {
81 self.interval
82 }
83
84 pub(crate) fn into_thirtyfour_poller(self) -> impl IntoElementPoller + Send + Sync {
85 ElementPollerWithTimeout::new(self.timeout, self.interval)
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92 use assertr::prelude::*;
93
94 #[test]
95 fn builder_preserves_timeout_and_interval() {
96 let wait = ElementQueryWaitConfig::builder()
97 .timeout(Duration::from_secs(10))
98 .interval(Duration::from_millis(250))
99 .build();
100
101 assert_that!(wait.timeout()).is_equal_to(Duration::from_secs(10));
102 assert_that!(wait.interval()).is_equal_to(Duration::from_millis(250));
103 }
104
105 #[test]
106 fn builder_preserves_zero_interval_for_trusted_callers() {
107 let wait = ElementQueryWaitConfig::builder()
108 .timeout(Duration::from_secs(10))
109 .interval(Duration::ZERO)
110 .build();
111
112 assert_that!(wait.interval()).is_equal_to(Duration::ZERO);
113 }
114
115 #[test]
116 fn try_new_accepts_non_zero_interval() {
117 let wait =
118 ElementQueryWaitConfig::try_new(Duration::from_secs(10), Duration::from_millis(250))
119 .expect("non-zero interval should be accepted");
120
121 assert_that!(wait.timeout()).is_equal_to(Duration::from_secs(10));
122 assert_that!(wait.interval()).is_equal_to(Duration::from_millis(250));
123 }
124
125 #[test]
126 fn try_new_rejects_zero_interval() {
127 let err = ElementQueryWaitConfig::try_new(Duration::from_secs(10), Duration::ZERO)
128 .expect_err("zero interval should be rejected");
129
130 assert_that!(err).is_equal_to(ElementQueryWaitConfigError::ZeroInterval);
131 }
132
133 #[test]
134 fn new_preserves_zero_interval_for_const_trusted_callers() {
135 const WAIT: ElementQueryWaitConfig =
136 ElementQueryWaitConfig::new(Duration::from_secs(10), Duration::ZERO);
137
138 assert_that!(WAIT.interval()).is_equal_to(Duration::ZERO);
139 }
140}