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