bybit_rust_api/ws/public/
orderbook.rs1use serde::Deserialize;
16
17#[derive(Debug, Clone, Deserialize)]
19pub struct OrderBookLevel {
20 #[serde(rename = "0")]
22 pub price: String,
23 #[serde(rename = "1")]
25 pub size: String,
26}
27
28#[derive(Debug, Clone, Deserialize)]
30pub struct OrderBookData {
31 #[serde(rename = "s")]
33 pub symbol: String,
34 #[serde(rename = "b")]
36 pub bids: Vec<OrderBookLevel>,
37 #[serde(rename = "a")]
39 pub asks: Vec<OrderBookLevel>,
40 #[serde(rename = "u")]
42 pub update_id: u64,
43 #[serde(rename = "seq")]
45 #[serde(default)]
46 pub seq: Option<u64>,
47 #[serde(rename = "cts")]
49 #[serde(default)]
50 pub cts: Option<u64>,
51 #[serde(rename = "type")]
53 pub msg_type: String,
54}
55
56pub struct OrderBookStream;
64
65impl OrderBookStream {
66 pub fn parse(data: &serde_json::Value) -> serde_json::Result<OrderBookData> {
68 serde_json::from_value(data.clone())
69 }
70
71 pub fn matches_topic(topic: &str) -> bool {
73 topic.starts_with("orderbook.")
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_parse_snapshot() {
83 let json = serde_json::json!({
84 "s": "BTCUSDT",
85 "b": [["50000.00", "1.5"], ["49900.00", "2.0"]],
86 "a": [["50100.00", "1.0"], ["50200.00", "0.5"]],
87 "u": 1,
88 "seq": 100,
89 "type": "snapshot"
90 });
91
92 let data: OrderBookData = serde_json::from_value(json).unwrap();
93 assert_eq!(data.symbol, "BTCUSDT");
94 assert_eq!(data.bids.len(), 2);
95 assert_eq!(data.asks.len(), 2);
96 assert_eq!(data.bids[0].price, "50000.00");
97 assert_eq!(data.bids[0].size, "1.5");
98 assert_eq!(data.msg_type, "snapshot");
99 }
100
101 #[test]
102 fn test_parse_delta() {
103 let json = serde_json::json!({
104 "s": "ETHUSDT",
105 "b": [],
106 "a": [["3000.00", "0.1"]],
107 "u": 105,
108 "seq": 105,
109 "type": "delta"
110 });
111
112 let data: OrderBookData = serde_json::from_value(json).unwrap();
113 assert_eq!(data.symbol, "ETHUSDT");
114 assert_eq!(data.asks.len(), 1);
115 assert_eq!(data.msg_type, "delta");
116 }
117
118 #[test]
119 fn test_matches_topic() {
120 assert!(OrderBookStream::matches_topic("orderbook.1.BTCUSDT"));
121 assert!(OrderBookStream::matches_topic("orderbook.50.ETHUSDT"));
122 assert!(!OrderBookStream::matches_topic("publicTrade.BTCUSDT"));
123 }
124}