square_api_client/http/client/
http_client_configuration.rs

1//! Configuration for HTTP client settings
2
3use package_info::PackageInfo;
4use std::default::Default;
5use std::env;
6use std::time::Duration;
7
8use crate::{config::CargoPackageInfo, http::Headers};
9
10const DEFAULT_TIMEOUT: u32 = 60;
11
12/// Configuration for HTTP client settings
13#[derive(Clone, Debug)]
14pub struct HttpClientConfiguration {
15    /// Timeout for HTTP connections
16    pub timeout: u32,
17    /// User Agent to use for requests
18    pub user_agent: String,
19    /// Headers to send with each request
20    pub default_headers: Headers,
21    /// Retry mechanism configuration
22    pub retry_configuration: RetryConfiguration,
23}
24
25#[derive(Clone, Debug, Eq, PartialEq)]
26pub struct RetryConfiguration {
27    /// How many times client should call same request in case of failure.
28    pub retries_count: u32,
29    /// Minimum waiting time between two retry attempts (it can end up being lower due to jittering).
30    pub min_retry_interval: Duration,
31    /// Maximum waiting time between two retry attempts.
32    pub max_retry_interval: Duration,
33    /// Growing factor governing how fast the retry interval increases with respect to the number
34    /// of failed attempts. If set to 3:
35    /// - first retry: 3^0 = 1
36    /// - second retry: 3^1 = 3
37    /// - third retry: 3^2 = 9
38    pub backoff_exponent: u32,
39}
40
41impl Default for RetryConfiguration {
42    fn default() -> Self {
43        Self {
44            retries_count: 0,
45            min_retry_interval: Duration::from_secs(1),
46            max_retry_interval: Duration::from_secs(30 * 60),
47            backoff_exponent: 3,
48        }
49    }
50}
51
52impl HttpClientConfiguration {
53    /// Instantiates a new `HttpClientConfiguration` based on the specified settings.
54    /// If the User Agent is not included in the default headers, it'll be added.
55    pub fn new(timeout: u32, user_agent: String, mut default_headers: Headers) -> Self {
56        if !default_headers.has_user_agent() {
57            default_headers.set_user_agent(&user_agent);
58        }
59        Self {
60            timeout,
61            user_agent,
62            default_headers,
63            retry_configuration: Default::default(),
64        }
65    }
66
67    /// Provides the library/crate's default User Agent
68    pub(crate) fn default_user_agent() -> String {
69        let sdk_version = CargoPackageInfo::version().unwrap_or_default();
70        let engine = "Rust";
71        let rust_version = rustc_version_runtime::version();
72        let os = env::consts::OS;
73        format!(
74            "Rust Square API Client Lib/0.1.0 ({}) {}/{} ({})",
75            sdk_version, engine, rust_version, os
76        )
77    }
78}
79
80impl Default for HttpClientConfiguration {
81    /// The default HTTP client settings
82    fn default() -> Self {
83        Self {
84            timeout: DEFAULT_TIMEOUT,
85            user_agent: Self::default_user_agent(),
86            default_headers: Default::default(),
87            retry_configuration: Default::default(),
88        }
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use crate::http::client::{HttpClientConfiguration, RetryConfiguration};
95    use crate::http::Headers;
96
97    #[test]
98    fn http_client_configuration_new_with_default_headers() {
99        let http_client_configuration =
100            HttpClientConfiguration::new(15, String::from("some_user_agent"), Headers::default());
101        assert_eq!(15, http_client_configuration.timeout);
102        assert_eq!(String::from("some_user_agent"), http_client_configuration.user_agent);
103        assert_eq!(Headers::default(), http_client_configuration.default_headers);
104        assert_eq!(RetryConfiguration::default(), http_client_configuration.retry_configuration);
105    }
106
107    #[test]
108    fn http_client_configuration_new_with_different_user_agent_in_headers() {
109        // Headers::
110        let http_client_configuration =
111            HttpClientConfiguration::new(15, String::from("some_user_agent"), Headers::default());
112        assert_eq!(15, http_client_configuration.timeout);
113        assert_eq!(String::from("some_user_agent"), http_client_configuration.user_agent);
114        assert_eq!(Headers::default(), http_client_configuration.default_headers);
115        assert_eq!(RetryConfiguration::default(), http_client_configuration.retry_configuration);
116    }
117}