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