bybit_rust_api/ws/
messages.rs1use serde::{Deserialize, Serialize};
19
20#[derive(Debug, Clone, Serialize)]
22#[serde(rename_all = "lowercase")]
23pub enum WsOp {
24 Subscribe,
25 Unsubscribe,
26 Auth,
27 Ping,
28}
29
30#[derive(Debug, Clone, Serialize)]
32pub struct WsRequest {
33 pub op: WsOp,
34 pub args: Vec<serde_json::Value>,
35}
36
37impl WsRequest {
38 pub fn subscribe(topics: Vec<String>) -> Self {
39 WsRequest {
40 op: WsOp::Subscribe,
41 args: topics.into_iter().map(serde_json::Value::String).collect(),
42 }
43 }
44
45 pub fn unsubscribe(topics: Vec<String>) -> Self {
46 WsRequest {
47 op: WsOp::Unsubscribe,
48 args: topics.into_iter().map(serde_json::Value::String).collect(),
49 }
50 }
51
52 pub fn auth(api_key: &str, expires: u64, signature: &str) -> Self {
53 WsRequest {
54 op: WsOp::Auth,
55 args: vec![
56 serde_json::Value::String(api_key.to_string()),
57 serde_json::Value::Number(serde_json::Number::from(expires)),
58 serde_json::Value::String(signature.to_string()),
59 ],
60 }
61 }
62
63 pub fn ping() -> Self {
64 WsRequest {
65 op: WsOp::Ping,
66 args: vec![],
67 }
68 }
69}
70
71#[derive(Debug, Clone, Deserialize)]
73pub struct WsResponse {
74 #[serde(default)]
76 pub topic: Option<String>,
77 #[serde(rename = "type")]
79 #[serde(default)]
80 pub msg_type: Option<String>,
81 #[serde(default)]
83 pub ts: Option<i64>,
84 #[serde(default)]
86 pub data: Option<serde_json::Value>,
87}
88
89#[derive(Debug, Clone, Deserialize)]
91pub struct WsOpResponse {
92 #[serde(default)]
94 pub op: Option<String>,
95 #[serde(default)]
97 pub success: Option<bool>,
98 #[serde(default)]
100 pub ret_msg: Option<String>,
101 #[serde(default)]
103 pub conn_id: Option<String>,
104 #[serde(default)]
106 pub req_id: Option<String>,
107}
108
109#[derive(Debug, Clone, Deserialize)]
111#[serde(untagged)]
112pub enum WsMessage {
113 Data(WsResponse),
115 Op(WsOpResponse),
117}
118
119impl WsMessage {
120 pub fn is_subscribe_success(&self) -> bool {
122 matches!(self, WsMessage::Op(WsOpResponse {
123 op: Some(op),
124 success: Some(true),
125 ..
126 }) if op == "subscribe")
127 }
128
129 pub fn is_auth_success(&self) -> bool {
131 matches!(self, WsMessage::Op(WsOpResponse {
132 op: Some(op),
133 success: Some(true),
134 ..
135 }) if op == "auth")
136 }
137
138 pub fn is_pong(&self) -> bool {
140 matches!(self, WsMessage::Op(WsOpResponse {
141 op: Some(op),
142 ..
143 }) if op == "pong")
144 }
145
146 pub fn topic(&self) -> Option<&str> {
148 match self {
149 WsMessage::Data(r) => r.topic.as_deref(),
150 _ => None,
151 }
152 }
153
154 pub fn msg_type(&self) -> Option<&str> {
156 match self {
157 WsMessage::Data(r) => r.msg_type.as_deref(),
158 _ => None,
159 }
160 }
161}
162
163pub mod topics {
165 pub fn orderbook(depth: u16, symbol: &str) -> String {
167 format!("orderbook.{}.{}", depth, symbol)
168 }
169
170 pub fn trade(symbol: &str) -> String {
172 format!("publicTrade.{}", symbol)
173 }
174
175 pub mod ticker {
177 pub fn linear(symbol: &str) -> String {
178 format!("tickers.{}", symbol)
179 }
180 pub fn inverse(symbol: &str) -> String {
181 format!("tickers.{}", symbol)
182 }
183 pub fn spot(symbol: &str) -> String {
184 format!("tickers.{}", symbol)
185 }
186 pub fn option(symbol: &str) -> String {
187 format!("tickers.{}", symbol)
188 }
189 }
190
191 pub fn kline(interval: &str, symbol: &str) -> String {
193 format!("kline.{}.{}", symbol, interval)
194 }
195
196 pub fn liquidation(symbol: &str) -> String {
198 format!("liquidation.{}", symbol)
199 }
200
201 pub mod position {
205 pub fn all() -> String {
206 "position".to_string()
207 }
208 pub fn linear() -> String {
209 "position.linear".to_string()
210 }
211 pub fn inverse() -> String {
212 "position.inverse".to_string()
213 }
214 pub fn option() -> String {
215 "position.option".to_string()
216 }
217 }
218
219 pub mod execution {
221 pub fn all() -> String {
222 "execution".to_string()
223 }
224 pub fn linear() -> String {
225 "execution.linear".to_string()
226 }
227 }
228
229 pub mod order {
231 pub fn all() -> String {
232 "order".to_string()
233 }
234 pub fn linear() -> String {
235 "order.linear".to_string()
236 }
237 }
238
239 pub mod wallet {
241 pub fn all() -> String {
242 "wallet".to_string()
243 }
244 pub fn linear() -> String {
245 "wallet.linear".to_string()
246 }
247 }
248}