binance_api_client/
config.rs1use std::time::Duration;
2
3pub const REST_API_ENDPOINT: &str = "https://api.binance.com";
5
6pub const WS_ENDPOINT: &str = "wss://stream.binance.com:9443";
8
9pub const TESTNET_REST_API_ENDPOINT: &str = "https://testnet.binance.vision";
11
12pub const TESTNET_WS_ENDPOINT: &str = "wss://testnet.binance.vision";
14
15pub const BINANCE_US_REST_API_ENDPOINT: &str = "https://api.binance.us";
17
18pub const BINANCE_US_WS_ENDPOINT: &str = "wss://stream.binance.us:9443";
20
21pub const DEFAULT_RECV_WINDOW: u64 = 5000;
23
24#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct Config {
27 pub rest_api_endpoint: String,
29
30 pub ws_endpoint: String,
32
33 pub recv_window: u64,
37
38 pub timeout: Option<Duration>,
40
41 pub binance_us: bool,
43}
44
45impl Config {
46 pub fn builder() -> ConfigBuilder {
48 ConfigBuilder::default()
49 }
50
51 pub fn testnet() -> Self {
53 Config {
54 rest_api_endpoint: TESTNET_REST_API_ENDPOINT.to_string(),
55 ws_endpoint: TESTNET_WS_ENDPOINT.to_string(),
56 recv_window: DEFAULT_RECV_WINDOW,
57 timeout: None,
58 binance_us: false,
59 }
60 }
61
62 pub fn binance_us() -> Self {
64 Config {
65 rest_api_endpoint: BINANCE_US_REST_API_ENDPOINT.to_string(),
66 ws_endpoint: BINANCE_US_WS_ENDPOINT.to_string(),
67 recv_window: DEFAULT_RECV_WINDOW,
68 timeout: None,
69 binance_us: true,
70 }
71 }
72}
73
74impl Default for Config {
75 fn default() -> Self {
77 Config {
78 rest_api_endpoint: REST_API_ENDPOINT.to_string(),
79 ws_endpoint: WS_ENDPOINT.to_string(),
80 recv_window: DEFAULT_RECV_WINDOW,
81 timeout: None,
82 binance_us: false,
83 }
84 }
85}
86
87#[derive(Clone, Debug, Default)]
89pub struct ConfigBuilder {
90 rest_api_endpoint: Option<String>,
91 ws_endpoint: Option<String>,
92 recv_window: Option<u64>,
93 timeout: Option<Duration>,
94 binance_us: bool,
95}
96
97impl ConfigBuilder {
98 pub fn rest_api_endpoint(mut self, endpoint: impl Into<String>) -> Self {
100 self.rest_api_endpoint = Some(endpoint.into());
101 self
102 }
103
104 pub fn ws_endpoint(mut self, endpoint: impl Into<String>) -> Self {
106 self.ws_endpoint = Some(endpoint.into());
107 self
108 }
109
110 pub fn recv_window(mut self, recv_window: u64) -> Self {
112 self.recv_window = Some(recv_window);
113 self
114 }
115
116 pub fn timeout(mut self, timeout: Duration) -> Self {
118 self.timeout = Some(timeout);
119 self
120 }
121
122 pub fn timeout_secs(self, secs: u64) -> Self {
124 self.timeout(Duration::from_secs(secs))
125 }
126
127 pub fn binance_us(mut self, is_binance_us: bool) -> Self {
129 self.binance_us = is_binance_us;
130 self
131 }
132
133 pub fn build(self) -> Config {
135 let (default_rest, default_ws) = if self.binance_us {
136 (BINANCE_US_REST_API_ENDPOINT, BINANCE_US_WS_ENDPOINT)
137 } else {
138 (REST_API_ENDPOINT, WS_ENDPOINT)
139 };
140
141 Config {
142 rest_api_endpoint: self
143 .rest_api_endpoint
144 .unwrap_or_else(|| default_rest.to_string()),
145 ws_endpoint: self.ws_endpoint.unwrap_or_else(|| default_ws.to_string()),
146 recv_window: self.recv_window.unwrap_or(DEFAULT_RECV_WINDOW),
147 timeout: self.timeout,
148 binance_us: self.binance_us,
149 }
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156
157 #[test]
158 fn test_default_config() {
159 let config = Config::default();
160 assert_eq!(config.rest_api_endpoint, REST_API_ENDPOINT);
161 assert_eq!(config.ws_endpoint, WS_ENDPOINT);
162 assert_eq!(config.recv_window, DEFAULT_RECV_WINDOW);
163 assert!(config.timeout.is_none());
164 assert!(!config.binance_us);
165 }
166
167 #[test]
168 fn test_testnet_config() {
169 let config = Config::testnet();
170 assert_eq!(config.rest_api_endpoint, TESTNET_REST_API_ENDPOINT);
171 assert_eq!(config.ws_endpoint, TESTNET_WS_ENDPOINT);
172 assert_eq!(config.recv_window, DEFAULT_RECV_WINDOW);
173 assert!(!config.binance_us);
174 }
175
176 #[test]
177 fn test_binance_us_config() {
178 let config = Config::binance_us();
179 assert_eq!(config.rest_api_endpoint, BINANCE_US_REST_API_ENDPOINT);
180 assert_eq!(config.ws_endpoint, BINANCE_US_WS_ENDPOINT);
181 assert!(config.binance_us);
182 }
183
184 #[test]
185 fn test_config_builder() {
186 let config = Config::builder()
187 .rest_api_endpoint("https://custom.api.com")
188 .ws_endpoint("wss://custom.ws.com")
189 .recv_window(3000)
190 .timeout_secs(30)
191 .build();
192
193 assert_eq!(config.rest_api_endpoint, "https://custom.api.com");
194 assert_eq!(config.ws_endpoint, "wss://custom.ws.com");
195 assert_eq!(config.recv_window, 3000);
196 assert_eq!(config.timeout, Some(Duration::from_secs(30)));
197 }
198
199 #[test]
200 fn test_config_builder_binance_us_defaults() {
201 let config = Config::builder().binance_us(true).build();
202
203 assert_eq!(config.rest_api_endpoint, BINANCE_US_REST_API_ENDPOINT);
204 assert_eq!(config.ws_endpoint, BINANCE_US_WS_ENDPOINT);
205 assert!(config.binance_us);
206 }
207}