Skip to main content

aelf_client/
config.rs

1use http::{HeaderMap, HeaderName, HeaderValue};
2use std::time::Duration;
3
4/// HTTP basic authentication credentials.
5#[derive(Clone, Debug, PartialEq, Eq)]
6pub struct BasicAuth {
7    pub username: String,
8    pub password: String,
9}
10
11/// Retry policy for transient HTTP transport failures.
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13pub struct RetryPolicy {
14    pub max_retries: usize,
15    pub initial_backoff: Duration,
16}
17
18impl RetryPolicy {
19    /// Creates a retry policy using exponential backoff with the provided initial delay.
20    pub fn new(max_retries: usize, initial_backoff: Duration) -> Self {
21        Self {
22            max_retries,
23            initial_backoff,
24        }
25    }
26}
27
28impl Default for RetryPolicy {
29    fn default() -> Self {
30        Self {
31            max_retries: 2,
32            initial_backoff: Duration::from_millis(200),
33        }
34    }
35}
36
37/// Configuration used to build an `AElfClient` or `HttpProvider`.
38#[derive(Clone, Debug)]
39pub struct ClientConfig {
40    pub endpoint: String,
41    pub api_version: Option<String>,
42    pub basic_auth: Option<BasicAuth>,
43    pub timeout: Duration,
44    pub retry_policy: RetryPolicy,
45    pub headers: HeaderMap,
46}
47
48impl ClientConfig {
49    /// Creates a client configuration with sensible defaults for public AElf nodes.
50    pub fn new(endpoint: impl Into<String>) -> Self {
51        Self {
52            endpoint: endpoint.into(),
53            api_version: None,
54            basic_auth: None,
55            timeout: Duration::from_secs(15),
56            retry_policy: RetryPolicy::default(),
57            headers: HeaderMap::new(),
58        }
59    }
60
61    /// Sets the versioned `application/json;v=...` media type used in requests.
62    pub fn with_api_version(mut self, version: impl Into<String>) -> Self {
63        self.api_version = Some(version.into());
64        self
65    }
66
67    /// Configures HTTP basic authentication for node requests.
68    pub fn with_basic_auth(
69        mut self,
70        username: impl Into<String>,
71        password: impl Into<String>,
72    ) -> Self {
73        self.basic_auth = Some(BasicAuth {
74            username: username.into(),
75            password: password.into(),
76        });
77        self
78    }
79
80    /// Overrides the HTTP timeout for each request attempt.
81    pub fn with_timeout(mut self, timeout: Duration) -> Self {
82        self.timeout = timeout;
83        self
84    }
85
86    /// Overrides the retry policy used for transient transport failures.
87    pub fn with_retry_policy(mut self, retry_policy: RetryPolicy) -> Self {
88        self.retry_policy = retry_policy;
89        self
90    }
91
92    /// Disables automatic retries.
93    pub fn without_retries(mut self) -> Self {
94        self.retry_policy = RetryPolicy::new(0, Duration::ZERO);
95        self
96    }
97
98    /// Adds a custom HTTP header that will be attached to every request.
99    pub fn with_header(
100        mut self,
101        name: impl AsRef<str>,
102        value: impl AsRef<str>,
103    ) -> Result<Self, http::Error> {
104        let name = HeaderName::from_bytes(name.as_ref().as_bytes())?;
105        let value = HeaderValue::from_str(value.as_ref())?;
106        self.headers.insert(name, value);
107        Ok(self)
108    }
109}