ccxt_exchanges/bitget/
builder.rs1use super::{Bitget, BitgetOptions};
7use ccxt_core::config::{ProxyConfig, RetryPolicy};
8use ccxt_core::types::default_type::{DefaultSubType, DefaultType};
9use ccxt_core::{ExchangeConfig, Result};
10use serde_json::Value;
11use std::collections::HashMap;
12use std::time::Duration;
13
14#[derive(Debug, Clone)]
34pub struct BitgetBuilder {
35 config: ExchangeConfig,
37 options: BitgetOptions,
39}
40
41impl Default for BitgetBuilder {
42 fn default() -> Self {
43 Self::new()
44 }
45}
46
47impl BitgetBuilder {
48 pub fn new() -> Self {
58 Self {
59 config: ExchangeConfig {
60 id: "bitget".to_string(),
61 name: "Bitget".to_string(),
62 ..Default::default()
63 },
64 options: BitgetOptions::default(),
65 }
66 }
67
68 pub fn api_key(mut self, key: impl Into<String>) -> Self {
74 self.config.api_key = Some(ccxt_core::SecretString::new(key));
75 self
76 }
77
78 pub fn secret(mut self, secret: impl Into<String>) -> Self {
84 self.config.secret = Some(ccxt_core::SecretString::new(secret));
85 self
86 }
87
88 pub fn passphrase(mut self, passphrase: impl Into<String>) -> Self {
96 self.config.password = Some(ccxt_core::SecretString::new(passphrase));
97 self
98 }
99
100 pub fn sandbox(mut self, enabled: bool) -> Self {
109 self.config.sandbox = enabled;
110 self.options.testnet = enabled;
111 self
112 }
113
114 pub fn product_type(mut self, product_type: impl Into<String>) -> Self {
125 self.options.product_type = product_type.into();
126 self
127 }
128
129 pub fn default_type(mut self, default_type: impl Into<DefaultType>) -> Self {
155 self.options.default_type = default_type.into();
156 self
157 }
158
159 pub fn default_sub_type(mut self, sub_type: DefaultSubType) -> Self {
184 self.options.default_sub_type = Some(sub_type);
185 self
186 }
187
188 pub fn timeout(mut self, timeout: Duration) -> Self {
190 self.config.timeout = timeout;
191 self
192 }
193
194 pub fn timeout_secs(mut self, seconds: u64) -> Self {
196 self.config.timeout = Duration::from_secs(seconds);
197 self
198 }
199
200 pub fn connect_timeout(mut self, timeout: Duration) -> Self {
206 self.config.connect_timeout = timeout;
207 self
208 }
209
210 pub fn connect_timeout_secs(mut self, seconds: u64) -> Self {
216 self.config.connect_timeout = Duration::from_secs(seconds);
217 self
218 }
219
220 pub fn retry_policy(mut self, policy: RetryPolicy) -> Self {
222 self.config.retry_policy = Some(policy);
223 self
224 }
225
226 pub fn recv_window(mut self, millis: u64) -> Self {
235 self.options.recv_window = millis;
236 self
237 }
238
239 pub fn enable_rate_limit(mut self, enabled: bool) -> Self {
245 self.config.enable_rate_limit = enabled;
246 self
247 }
248
249 pub fn proxy(mut self, proxy: ProxyConfig) -> Self {
251 self.config.proxy = Some(proxy);
252 self
253 }
254
255 pub fn proxy_url(mut self, url: impl Into<String>) -> Self {
257 self.config.proxy = Some(ProxyConfig::new(url));
258 self
259 }
260
261 pub fn verbose(mut self, enabled: bool) -> Self {
267 self.config.verbose = enabled;
268 self
269 }
270
271 pub fn option(mut self, key: impl Into<String>, value: Value) -> Self {
278 self.config.options.insert(key.into(), value);
279 self
280 }
281
282 pub fn options(mut self, options: HashMap<String, Value>) -> Self {
288 self.config.options.extend(options);
289 self
290 }
291
292 #[cfg(test)]
294 pub fn get_config(&self) -> &ExchangeConfig {
295 &self.config
296 }
297
298 #[cfg(test)]
300 pub fn get_options(&self) -> &BitgetOptions {
301 &self.options
302 }
303
304 pub fn build(self) -> Result<Bitget> {
314 Bitget::new_with_options(self.config, self.options)
315 }
316}
317
318#[cfg(test)]
319mod tests {
320 use super::*;
321
322 #[test]
323 fn test_builder_default() {
324 let builder = BitgetBuilder::new();
325 assert_eq!(builder.config.id, "bitget");
326 assert_eq!(builder.config.name, "Bitget");
327 assert!(!builder.config.sandbox);
328 assert_eq!(builder.options.product_type, "spot");
329 }
330
331 #[test]
332 fn test_builder_api_key() {
333 let builder = BitgetBuilder::new().api_key("test-key");
334 assert_eq!(
335 builder.config.api_key.as_ref().map(|s| s.expose_secret()),
336 Some("test-key")
337 );
338 }
339
340 #[test]
341 fn test_builder_secret() {
342 let builder = BitgetBuilder::new().secret("test-secret");
343 assert_eq!(
344 builder.config.secret.as_ref().map(|s| s.expose_secret()),
345 Some("test-secret")
346 );
347 }
348
349 #[test]
350 fn test_builder_passphrase() {
351 let builder = BitgetBuilder::new().passphrase("test-passphrase");
352 assert_eq!(
353 builder.config.password.as_ref().map(|s| s.expose_secret()),
354 Some("test-passphrase")
355 );
356 }
357
358 #[test]
359 fn test_builder_sandbox() {
360 let builder = BitgetBuilder::new().sandbox(true);
361 assert!(builder.config.sandbox);
362 assert!(builder.options.testnet);
363 }
364
365 #[test]
366 fn test_builder_product_type() {
367 let builder = BitgetBuilder::new().product_type("umcbl");
368 assert_eq!(builder.options.product_type, "umcbl");
369 }
370
371 #[test]
372 fn test_builder_default_type() {
373 let builder = BitgetBuilder::new().default_type(DefaultType::Swap);
374 assert_eq!(builder.options.default_type, DefaultType::Swap);
375 }
376
377 #[test]
378 fn test_builder_default_type_from_string() {
379 let builder = BitgetBuilder::new().default_type("futures");
380 assert_eq!(builder.options.default_type, DefaultType::Futures);
381 }
382
383 #[test]
384 fn test_builder_default_sub_type() {
385 let builder = BitgetBuilder::new().default_sub_type(DefaultSubType::Inverse);
386 assert_eq!(
387 builder.options.default_sub_type,
388 Some(DefaultSubType::Inverse)
389 );
390 }
391
392 #[test]
393 fn test_builder_default_type_and_sub_type() {
394 let builder = BitgetBuilder::new()
395 .default_type(DefaultType::Swap)
396 .default_sub_type(DefaultSubType::Linear);
397 assert_eq!(builder.options.default_type, DefaultType::Swap);
398 assert_eq!(
399 builder.options.default_sub_type,
400 Some(DefaultSubType::Linear)
401 );
402 }
403
404 #[test]
405 fn test_builder_timeout() {
406 let builder = BitgetBuilder::new().timeout(Duration::from_secs(60));
407 assert_eq!(builder.config.timeout, Duration::from_secs(60));
408 }
409
410 #[test]
411 fn test_builder_connect_timeout() {
412 let builder = BitgetBuilder::new().connect_timeout(Duration::from_secs(15));
413 assert_eq!(builder.config.connect_timeout, Duration::from_secs(15));
414 }
415
416 #[test]
417 fn test_builder_connect_timeout_secs() {
418 let builder = BitgetBuilder::new().connect_timeout_secs(20);
419 assert_eq!(builder.config.connect_timeout, Duration::from_secs(20));
420 }
421
422 #[test]
423 fn test_builder_recv_window() {
424 let builder = BitgetBuilder::new().recv_window(10000);
425 assert_eq!(builder.options.recv_window, 10000);
426 }
427
428 #[test]
429 fn test_builder_chaining() {
430 let builder = BitgetBuilder::new()
431 .api_key("key")
432 .secret("secret")
433 .passphrase("pass")
434 .sandbox(true)
435 .timeout(Duration::from_secs(30))
436 .recv_window(5000)
437 .product_type("spot")
438 .default_type(DefaultType::Swap)
439 .default_sub_type(DefaultSubType::Linear);
440
441 assert_eq!(
442 builder.config.api_key.as_ref().map(|s| s.expose_secret()),
443 Some("key")
444 );
445 assert_eq!(
446 builder.config.secret.as_ref().map(|s| s.expose_secret()),
447 Some("secret")
448 );
449 assert_eq!(
450 builder.config.password.as_ref().map(|s| s.expose_secret()),
451 Some("pass")
452 );
453 assert!(builder.config.sandbox);
454 assert_eq!(builder.config.timeout, Duration::from_secs(30));
455 assert_eq!(builder.options.recv_window, 5000);
456 assert_eq!(builder.options.product_type, "spot");
457 assert_eq!(builder.options.default_type, DefaultType::Swap);
458 assert_eq!(
459 builder.options.default_sub_type,
460 Some(DefaultSubType::Linear)
461 );
462 }
463
464 #[test]
465 fn test_builder_build() {
466 let result = BitgetBuilder::new().build();
467 assert!(result.is_ok());
468
469 let bitget = result.unwrap();
470 assert_eq!(bitget.id(), "bitget");
471 assert_eq!(bitget.name(), "Bitget");
472 }
473
474 #[test]
475 fn test_builder_build_with_credentials() {
476 let result = BitgetBuilder::new()
477 .api_key("test-key")
478 .secret("test-secret")
479 .passphrase("test-passphrase")
480 .build();
481
482 assert!(result.is_ok());
483 }
484}