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