qubit_http/options/
http_timeout_options.rs1use std::time::Duration;
12
13use qubit_config::{ConfigReader, ConfigResult};
14
15use super::HttpConfigError;
16use crate::constants::{
17 DEFAULT_CONNECT_TIMEOUT_SECS, DEFAULT_READ_TIMEOUT_SECS, DEFAULT_WRITE_TIMEOUT_SECS,
18};
19
20#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct HttpTimeoutOptions {
23 pub connect_timeout: Duration,
25 pub read_timeout: Duration,
27 pub write_timeout: Duration,
29 pub request_timeout: Option<Duration>,
31}
32
33impl Default for HttpTimeoutOptions {
34 fn default() -> Self {
42 Self {
43 connect_timeout: Duration::from_secs(DEFAULT_CONNECT_TIMEOUT_SECS),
44 read_timeout: Duration::from_secs(DEFAULT_READ_TIMEOUT_SECS),
45 write_timeout: Duration::from_secs(DEFAULT_WRITE_TIMEOUT_SECS),
46 request_timeout: None,
47 }
48 }
49}
50
51struct TimeoutConfigInput {
52 connect_timeout: Option<Duration>,
53 read_timeout: Option<Duration>,
54 write_timeout: Option<Duration>,
55 request_timeout: Option<Duration>,
56}
57
58fn read_timeout_config<R>(config: &R) -> ConfigResult<TimeoutConfigInput>
59where
60 R: ConfigReader + ?Sized,
61{
62 Ok(TimeoutConfigInput {
63 connect_timeout: config.get_optional("connect_timeout")?,
64 read_timeout: config.get_optional("read_timeout")?,
65 write_timeout: config.get_optional("write_timeout")?,
66 request_timeout: config.get_optional("request_timeout")?,
67 })
68}
69
70impl HttpTimeoutOptions {
71 pub fn validate(&self) -> Result<(), HttpConfigError> {
76 validate_positive_duration("connect_timeout", self.connect_timeout)?;
77 validate_positive_duration("read_timeout", self.read_timeout)?;
78 validate_positive_duration("write_timeout", self.write_timeout)?;
79 if let Some(request_timeout) = self.request_timeout {
80 validate_positive_duration("request_timeout", request_timeout)?;
81 }
82 Ok(())
83 }
84
85 pub fn from_config<R>(config: &R) -> Result<Self, HttpConfigError>
101 where
102 R: ConfigReader + ?Sized,
103 {
104 let raw = read_timeout_config(config).map_err(HttpConfigError::from)?;
105
106 let mut opts = HttpTimeoutOptions::default();
107 if let Some(d) = raw.connect_timeout {
108 opts.connect_timeout = d;
109 }
110 if let Some(d) = raw.read_timeout {
111 opts.read_timeout = d;
112 }
113 if let Some(d) = raw.write_timeout {
114 opts.write_timeout = d;
115 }
116 opts.request_timeout = raw.request_timeout;
117 opts.validate()?;
118 Ok(opts)
119 }
120}
121
122fn validate_positive_duration(path: &str, value: Duration) -> Result<(), HttpConfigError> {
123 if value.is_zero() {
124 return Err(HttpConfigError::invalid_value(
125 path,
126 "Timeout value must be greater than 0",
127 ));
128 }
129 Ok(())
130}