rusty_common/websocket/exchanges/
config.rs1use super::super::config::CompressionConfig;
7use smartstring::alias::String;
8
9#[derive(Debug, Clone)]
11pub struct ExchangeConfig {
12 pub exchange: String,
14 pub compression: CompressionConfig,
16 pub custom_ping_message: Option<String>,
18 pub custom_pong_response: Option<String>,
20 pub send_unsolicited_pongs: bool,
22 pub ping_interval_override: Option<u64>,
24}
25
26impl ExchangeConfig {
27 #[must_use]
31 pub fn binance() -> Self {
32 Self {
33 exchange: "binance".into(),
34 compression: CompressionConfig::disabled(),
35 custom_ping_message: None,
36 custom_pong_response: None,
37 send_unsolicited_pongs: true, ping_interval_override: Some(180_000), }
40 }
41
42 #[must_use]
46 pub fn binance_futures() -> Self {
47 Self {
48 exchange: "binance_futures".into(),
49 compression: CompressionConfig::disabled(), custom_ping_message: None,
51 custom_pong_response: None,
52 send_unsolicited_pongs: true,
53 ping_interval_override: Some(180_000), }
55 }
56
57 #[must_use]
59 pub fn coinbase() -> Self {
60 Self {
61 exchange: "coinbase".into(),
62 compression: CompressionConfig {
63 enabled: true,
64 client_max_window_bits: 15,
65 server_max_window_bits: 15,
66 client_no_context_takeover: false,
67 server_no_context_takeover: false,
68 },
69 custom_ping_message: None,
70 custom_pong_response: None,
71 send_unsolicited_pongs: false,
72 ping_interval_override: None,
73 }
74 }
75
76 #[must_use]
78 pub fn upbit() -> Self {
79 Self {
80 exchange: "upbit".into(),
81 compression: CompressionConfig {
82 enabled: true,
83 client_max_window_bits: 15,
84 server_max_window_bits: 15,
85 client_no_context_takeover: false,
86 server_no_context_takeover: false,
87 },
88 custom_ping_message: Some("PING".into()),
89 custom_pong_response: Some("{\"status\":\"UP\"}".into()),
90 send_unsolicited_pongs: false,
91 ping_interval_override: Some(60000), }
93 }
94
95 #[must_use]
99 pub fn bybit() -> Self {
100 Self {
101 exchange: "bybit".into(),
102 compression: CompressionConfig::disabled(), custom_ping_message: Some("{\"op\":\"ping\"}".into()),
104 custom_pong_response: Some("{\"op\":\"pong\"}".into()),
105 send_unsolicited_pongs: false,
106 ping_interval_override: Some(20000), }
108 }
109
110 #[must_use]
114 pub fn bithumb() -> Self {
115 Self {
116 exchange: "bithumb".into(),
117 compression: CompressionConfig::disabled(),
118 custom_ping_message: Some("{\"cmd\":\"ping\"}".into()),
119 custom_pong_response: Some("{\"code\":\"0\",\"msg\":\"pong\"}".into()),
120 send_unsolicited_pongs: false,
121 ping_interval_override: None,
122 }
123 }
124
125 #[must_use]
127 pub fn for_exchange(exchange: &str) -> Self {
128 match exchange.to_lowercase().as_str() {
129 "binance" => Self::binance(),
130 "binance_futures" => Self::binance_futures(),
131 "coinbase" => Self::coinbase(),
132 "upbit" => Self::upbit(),
133 "bybit" => Self::bybit(),
134 "bithumb" => Self::bithumb(),
135 _ => Self::default(),
136 }
137 }
138}
139
140impl Default for ExchangeConfig {
141 fn default() -> Self {
142 Self {
143 exchange: "generic".into(),
144 compression: CompressionConfig::disabled(), custom_ping_message: None,
146 custom_pong_response: None,
147 send_unsolicited_pongs: false,
148 ping_interval_override: None,
149 }
150 }
151}
152
153pub const fn get_compression_summary() -> &'static str {
163 "
164 | Exchange | Compression Support | Notes |
165 |----------|-------------------|-------|
166 | Binance | ❌ None | Streams already optimized; Futures has window_bits=15 bug |
167 | Coinbase | ✅ permessage-deflate | Standard support, no customization |
168 | Upbit | ✅ permessage-deflate | Full RFC 7692 support |
169 | Bybit | ❌ Disabled | Known buggy implementation, causes NegotiationError |
170 | Bithumb | ❌ None | No documented support in official API docs |
171 "
172}
173
174pub fn supports_websocket_compression(exchange: &str) -> bool {
176 matches!(exchange.to_lowercase().as_str(), "coinbase" | "upbit")
177}