1use derive_builder::Builder;
2use reqwest::{Client, ClientBuilder};
3use std::collections::HashMap;
4use std::fmt;
5use std::sync::Arc;
6use tokio_tungstenite::Connector;
7
8use super::models::{ConfigBuildError, TimeUnit, WebsocketMode};
9use super::utils::{SignatureGenerator, build_client};
10
11#[derive(Clone)]
12pub struct AgentConnector(pub Connector);
13
14impl fmt::Debug for AgentConnector {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 write!(f, "Connector(…)")
17 }
18}
19
20#[derive(Clone)]
21pub struct HttpAgent(pub Arc<dyn Fn(ClientBuilder) -> ClientBuilder + Send + Sync>);
22
23impl fmt::Debug for HttpAgent {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 write!(f, "HttpAgent(<custom agent fn>)")
26 }
27}
28
29#[derive(Debug, Clone)]
30pub struct ProxyAuth {
31 pub username: String,
32 pub password: String,
33}
34
35#[derive(Debug, Clone)]
36pub struct ProxyConfig {
37 pub host: String,
38 pub port: u16,
39 pub protocol: Option<String>,
40 pub auth: Option<ProxyAuth>,
41}
42
43#[derive(Debug, Clone)]
44pub enum PrivateKey {
45 File(String),
46 Raw(Vec<u8>),
47}
48
49#[derive(Debug, Clone, Builder)]
50#[builder(
51 pattern = "owned",
52 build_fn(name = "try_build", error = "ConfigBuildError")
53)]
54pub struct ConfigurationRestApi {
55 #[builder(setter(into, strip_option), default)]
56 pub api_key: Option<String>,
57
58 #[builder(setter(into, strip_option), default)]
59 pub api_secret: Option<String>,
60
61 #[builder(setter(into, strip_option), default)]
62 pub base_path: Option<String>,
63
64 #[builder(default = "1000")]
65 pub timeout: u64,
66
67 #[builder(default = "true")]
68 pub keep_alive: bool,
69
70 #[builder(default = "true")]
71 pub compression: bool,
72
73 #[builder(default = "3")]
74 pub retries: u32,
75
76 #[builder(default = "1000")]
77 pub backoff: u64,
78
79 #[builder(setter(strip_option), default)]
80 pub proxy: Option<ProxyConfig>,
81
82 #[builder(setter(strip_option, into), default)]
83 pub custom_headers: Option<HashMap<String, String>>,
84
85 #[builder(setter(strip_option), default)]
86 pub agent: Option<HttpAgent>,
87
88 #[builder(setter(strip_option), default)]
89 pub private_key: Option<PrivateKey>,
90
91 #[builder(setter(strip_option), default)]
92 pub private_key_passphrase: Option<String>,
93
94 #[builder(setter(strip_option), default)]
95 pub time_unit: Option<TimeUnit>,
96
97 #[builder(setter(skip))]
98 pub(crate) client: Client,
99
100 #[builder(setter(skip))]
101 pub(crate) user_agent: String,
102
103 #[builder(setter(skip))]
104 pub(crate) signature_gen: SignatureGenerator,
105}
106
107impl ConfigurationRestApi {
108 #[must_use]
109 pub fn builder() -> ConfigurationRestApiBuilder {
110 ConfigurationRestApiBuilder::default()
111 }
112}
113
114impl ConfigurationRestApiBuilder {
115 pub fn build(self) -> Result<ConfigurationRestApi, ConfigBuildError> {
125 let mut cfg = self.try_build()?;
126 cfg.client = build_client(
127 cfg.timeout,
128 cfg.keep_alive,
129 cfg.proxy.as_ref(),
130 cfg.agent.clone(),
131 );
132 cfg.signature_gen = SignatureGenerator::new(
133 cfg.api_secret.clone(),
134 cfg.private_key.clone(),
135 cfg.private_key_passphrase.clone(),
136 );
137
138 Ok(cfg)
139 }
140}
141
142#[derive(Debug, Clone, Builder)]
143#[builder(
144 pattern = "owned",
145 build_fn(name = "try_build", error = "ConfigBuildError")
146)]
147pub struct ConfigurationWebsocketApi {
148 #[builder(setter(into, strip_option), default)]
149 pub api_key: Option<String>,
150
151 #[builder(setter(into, strip_option), default)]
152 pub api_secret: Option<String>,
153
154 #[builder(setter(into, strip_option), default)]
155 pub ws_url: Option<String>,
156
157 #[builder(default = "5000")]
158 pub timeout: u64,
159
160 #[builder(default = "5000")]
161 pub reconnect_delay: u64,
162
163 #[builder(default = "WebsocketMode::Single")]
164 pub mode: WebsocketMode,
165
166 #[builder(setter(strip_option), default)]
167 pub agent: Option<AgentConnector>,
168
169 #[builder(setter(strip_option), default)]
170 pub private_key: Option<PrivateKey>,
171
172 #[builder(setter(strip_option), default)]
173 pub private_key_passphrase: Option<String>,
174
175 #[builder(setter(strip_option), default)]
176 pub time_unit: Option<TimeUnit>,
177
178 #[builder(default = "true")]
179 pub auto_session_relogon: bool,
180
181 #[builder(setter(skip))]
182 pub(crate) user_agent: String,
183
184 #[builder(setter(skip))]
185 pub(crate) signature_gen: SignatureGenerator,
186}
187
188impl ConfigurationWebsocketApi {
189 #[must_use]
199 pub fn builder() -> ConfigurationWebsocketApiBuilder {
200 ConfigurationWebsocketApiBuilder::default()
201 }
202}
203
204impl ConfigurationWebsocketApiBuilder {
205 pub fn build(self) -> Result<ConfigurationWebsocketApi, ConfigBuildError> {
221 let mut cfg = self.try_build()?;
222 cfg.signature_gen = SignatureGenerator::new(
223 cfg.api_secret.clone(),
224 cfg.private_key.clone(),
225 cfg.private_key_passphrase.clone(),
226 );
227
228 Ok(cfg)
229 }
230}
231
232#[derive(Debug, Clone, Builder)]
233#[builder(pattern = "owned", build_fn(error = "ConfigBuildError"))]
234pub struct ConfigurationWebsocketStreams {
235 #[builder(setter(into, strip_option), default)]
236 pub ws_url: Option<String>,
237
238 #[builder(default = "5000")]
239 pub reconnect_delay: u64,
240
241 #[builder(default = "WebsocketMode::Single")]
242 pub mode: WebsocketMode,
243
244 #[builder(setter(strip_option), default)]
245 pub agent: Option<AgentConnector>,
246
247 #[builder(setter(strip_option), default)]
248 pub time_unit: Option<TimeUnit>,
249
250 #[builder(setter(skip))]
251 pub(crate) user_agent: String,
252}
253
254impl ConfigurationWebsocketStreams {
255 #[must_use]
256 pub fn builder() -> ConfigurationWebsocketStreamsBuilder {
262 ConfigurationWebsocketStreamsBuilder::default()
263 }
264}