use core::time::Duration;
use tokio_util::sync::CancellationToken;
use crate::types::WaitConfig;
impl WaitConfig {
#[must_use]
#[inline]
pub fn builder() -> WaitConfigBuilder {
WaitConfigBuilder::default()
}
}
#[derive(Debug, Clone, Default)]
pub struct WaitConfigBuilder {
config: WaitConfig,
}
impl WaitConfigBuilder {
#[must_use]
#[inline]
pub const fn timeout(mut self, timeout: Duration) -> Self {
self.config.timeout = timeout;
self
}
#[must_use]
#[inline]
pub const fn interval(mut self, interval: Duration) -> Self {
self.config.initial_interval = interval;
self
}
#[must_use]
#[inline]
pub const fn max_interval(mut self, max_interval: Duration) -> Self {
self.config.max_interval = max_interval;
self
}
#[must_use]
#[inline]
pub const fn wait_for_any(mut self, wait_for_any: bool) -> Self {
self.config.wait_for_any = wait_for_any;
self
}
#[must_use]
#[inline]
pub const fn max_retries(mut self, max_retries: Option<u32>) -> Self {
self.config.max_retries = max_retries;
self
}
#[must_use]
#[inline]
pub const fn connection_timeout(mut self, timeout: Duration) -> Self {
self.config.connection_timeout = timeout;
self
}
#[must_use]
#[inline]
pub fn cancellation_token(mut self, token: CancellationToken) -> Self {
self.config.cancellation_token = Some(token);
self
}
#[inline]
pub fn with_cancellation(mut self) -> (Self, CancellationToken) {
let token = CancellationToken::new();
self.config.cancellation_token = Some(token.clone());
(self, token)
}
#[must_use]
#[inline]
pub fn security_validator(mut self, validator: crate::security::SecurityValidator) -> Self {
self.config.security_validator = Some(validator);
self
}
#[must_use]
#[inline]
pub fn rate_limiter(mut self, limiter: crate::security::RateLimiter) -> Self {
self.config.rate_limiter = Some(limiter);
self
}
#[must_use]
#[inline]
pub fn production_security(mut self) -> Self {
self.config.security_validator = Some(crate::security::SecurityValidator::production());
self.config.rate_limiter = Some(crate::security::RateLimiter::new(30)); self
}
#[must_use]
#[inline]
pub fn development_security(mut self) -> Self {
self.config.security_validator = Some(crate::security::SecurityValidator::development());
self.config.rate_limiter = Some(crate::security::RateLimiter::new(120)); self
}
#[inline]
pub fn build(self) -> WaitConfig {
self.config
}
}
#[cfg(test)]
#[expect(clippy::unwrap_used, reason = "test code where panics are acceptable")]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn wait_config_builder_defaults() {
let config = WaitConfig::builder().build();
assert_eq!(config.timeout, Duration::from_secs(30));
assert_eq!(config.initial_interval, Duration::from_secs(1));
assert_eq!(config.max_interval, Duration::from_secs(30));
assert_eq!(config.connection_timeout, Duration::from_secs(10));
assert!(!config.wait_for_any);
assert_eq!(config.max_retries, None);
assert!(config.cancellation_token.is_none());
}
#[test]
fn wait_config_builder_custom_values() {
let config = WaitConfig::builder()
.timeout(Duration::from_secs(120))
.interval(Duration::from_secs(2))
.max_interval(Duration::from_secs(60))
.connection_timeout(Duration::from_secs(20))
.wait_for_any(true)
.max_retries(Some(10))
.build();
assert_eq!(config.timeout, Duration::from_secs(120));
assert_eq!(config.initial_interval, Duration::from_secs(2));
assert_eq!(config.max_interval, Duration::from_secs(60));
assert_eq!(config.connection_timeout, Duration::from_secs(20));
assert!(config.wait_for_any);
assert_eq!(config.max_retries, Some(10));
}
#[test]
fn wait_config_with_cancellation() {
let (builder, token) = WaitConfig::builder()
.timeout(Duration::from_secs(30))
.with_cancellation();
let config = builder.build();
assert_eq!(config.timeout, Duration::from_secs(30));
assert!(config.cancellation_token.is_some());
assert!(!token.is_cancelled());
token.cancel();
assert!(token.is_cancelled());
}
#[test]
fn wait_config_security_presets() {
let config = WaitConfig::builder().production_security().build();
assert!(config.security_validator.is_some());
assert!(config.rate_limiter.is_some());
let config = WaitConfig::builder().development_security().build();
assert!(config.security_validator.is_some());
assert!(config.rate_limiter.is_some());
}
#[test]
fn wait_config_custom_security() {
use crate::security::{RateLimiter, SecurityValidator};
let validator = SecurityValidator::new();
let limiter = RateLimiter::new(100);
let config = WaitConfig::builder()
.security_validator(validator)
.rate_limiter(limiter)
.build();
assert!(config.security_validator.is_some());
assert!(config.rate_limiter.is_some());
}
#[test]
fn wait_config_builder_chaining() {
let config = WaitConfig::builder()
.timeout(Duration::from_secs(30))
.interval(Duration::from_millis(100))
.max_interval(Duration::from_secs(10))
.connection_timeout(Duration::from_secs(5))
.wait_for_any(false)
.max_retries(Some(5))
.production_security()
.build();
assert_eq!(config.timeout, Duration::from_secs(30));
assert_eq!(config.initial_interval, Duration::from_millis(100));
assert_eq!(config.max_interval, Duration::from_secs(10));
assert_eq!(config.connection_timeout, Duration::from_secs(5));
assert!(!config.wait_for_any);
assert_eq!(config.max_retries, Some(5));
}
}