use std::time::Duration; use serde::{Deserialize, Serialize}; use crate::duration::{deserialize_opt_std_duration, deserialize_std_duration}; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(default)] pub struct WebhookConfig { pub max_attempts: u32, #[serde(default, deserialize_with = "deserialize_std_duration")] pub base_delay: Duration, #[serde(default, deserialize_with = "deserialize_std_duration")] pub max_delay: Duration, #[serde(default, deserialize_with = "deserialize_std_duration")] pub request_timeout: Duration, #[serde(default, deserialize_with = "deserialize_opt_std_duration")] pub connect_timeout: Option, pub pool_max_idle_per_host: usize, #[serde(default, deserialize_with = "deserialize_opt_std_duration")] pub pool_idle_timeout: Option, pub follow_redirects: bool, pub max_concurrent_dispatches: usize, } impl Default for WebhookConfig { fn default() -> Self { Self { max_attempts: 5, base_delay: Duration::from_millis(500), max_delay: Duration::from_secs(30), request_timeout: Duration::from_secs(10), connect_timeout: Some(Duration::from_secs(2)), pool_max_idle_per_host: 8, pool_idle_timeout: Some(Duration::from_secs(90)), follow_redirects: true, max_concurrent_dispatches: 32, } } } impl WebhookConfig { pub fn is_valid(&self) -> Result<(), String> { if self.max_attempts == 0 { return Err("webhook.max_attempts must be >= 1".into()); } if self.base_delay.is_zero() { return Err("webhook.base_delay must be > 0".into()); } if self.max_delay < self.base_delay { return Err(format!( "webhook.max_delay ({:?}) must be >= webhook.base_delay ({:?})", self.max_delay, self.base_delay )); } if self.request_timeout.is_zero() { return Err("webhook.request_timeout must be > 0".into()); } if let Some(t) = self.connect_timeout && t.is_zero() { return Err("webhook.connect_timeout, if set, must be > 0".into()); } if self.pool_max_idle_per_host == 0 { return Err("webhook.pool_max_idle_per_host must be >= 1".into()); } if self.max_concurrent_dispatches == 0 { return Err("webhook.max_concurrent_dispatches must be >= 1".into()); } Ok(()) } }