use crate::utils::get_env_with_prefix;
use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TimeoutConfig {
#[serde(default = "default_enabled")]
pub enabled: bool,
#[serde(default = "default_timeout_seconds")]
pub timeout_seconds: u64,
}
impl Default for TimeoutConfig {
fn default() -> Self {
Self {
enabled: default_enabled(),
timeout_seconds: default_timeout_seconds(),
}
}
}
impl TimeoutConfig {
pub fn builder() -> TimeoutConfigBuilder {
TimeoutConfigBuilder::new()
}
pub fn duration(&self) -> Duration {
Duration::from_secs(self.timeout_seconds)
}
pub fn from_env() -> Self {
let mut config = Self::default();
if let Some(enabled) = get_env_with_prefix("TIMEOUT_ENABLED") {
match enabled.parse() {
Ok(value) => config.enabled = value,
Err(_) => {
tracing::warn!(
value = %enabled,
"Invalid TIMEOUT_ENABLED (expected true/false), using default ({})",
default_enabled()
);
}
}
}
if let Some(seconds) = get_env_with_prefix("TIMEOUT_SECONDS") {
match seconds.parse() {
Ok(s) => config.timeout_seconds = s,
Err(_) => tracing::warn!(
value = %seconds,
"Invalid TIMEOUT_SECONDS (expected integer), using default ({})",
default_timeout_seconds()
),
}
}
config
}
}
#[must_use = "builder does nothing until you call build()"]
pub struct TimeoutConfigBuilder {
config: TimeoutConfig,
}
impl TimeoutConfigBuilder {
pub fn new() -> Self {
Self {
config: TimeoutConfig::default(),
}
}
pub fn enabled(mut self, enabled: bool) -> Self {
self.config.enabled = enabled;
self
}
pub fn timeout_seconds(mut self, seconds: u64) -> Self {
self.config.timeout_seconds = seconds;
self
}
pub fn timeout(mut self, duration: Duration) -> Self {
self.config.timeout_seconds = duration.as_secs();
self
}
pub fn build(self) -> TimeoutConfig {
self.config
}
}
impl Default for TimeoutConfigBuilder {
fn default() -> Self {
Self::new()
}
}
fn default_enabled() -> bool {
true
}
fn default_timeout_seconds() -> u64 {
30 }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = TimeoutConfig::default();
assert!(config.enabled);
assert_eq!(config.timeout_seconds, 30);
assert_eq!(config.duration(), Duration::from_secs(30));
}
#[test]
fn test_builder() {
let config = TimeoutConfig::builder().timeout_seconds(60).build();
assert_eq!(config.timeout_seconds, 60);
assert_eq!(config.duration(), Duration::from_secs(60));
}
#[test]
fn test_duration() {
let config = TimeoutConfig::builder()
.timeout(Duration::from_secs(45))
.build();
assert_eq!(config.timeout_seconds, 45);
}
}