Skip to main content

ccxt_exchanges/binance/ws/
parsers.rs

1//! Stream parsers for WebSocket message parsing
2//!
3//! This module provides the `StreamParser` trait and implementations for
4//! parsing different types of WebSocket messages from Binance.
5
6use crate::binance::parser;
7use ccxt_core::error::Result;
8use ccxt_core::types::{BidAsk, MarkPrice, Market, OHLCV, Ticker, Trade};
9use serde_json::Value;
10
11/// Trait for parsing WebSocket stream messages into typed data.
12///
13/// Implementations of this trait handle the conversion of raw JSON messages
14/// from Binance WebSocket streams into strongly-typed Rust structures.
15pub trait StreamParser {
16    /// The output type produced by this parser
17    type Output;
18
19    /// Parse a WebSocket message into the output type.
20    ///
21    /// # Arguments
22    /// * `message` - The raw JSON message from the WebSocket
23    /// * `market` - Optional market information for symbol resolution
24    ///
25    /// # Returns
26    /// The parsed data or an error if parsing fails
27    fn parse(message: &Value, market: Option<&Market>) -> Result<Self::Output>;
28}
29
30/// Parser for ticker stream messages.
31pub struct TickerParser;
32
33impl StreamParser for TickerParser {
34    type Output = Ticker;
35
36    fn parse(message: &Value, market: Option<&Market>) -> Result<Self::Output> {
37        parser::parse_ws_ticker(message, market)
38    }
39}
40
41/// Parser for trade stream messages.
42pub struct TradeParser;
43
44impl StreamParser for TradeParser {
45    type Output = Trade;
46
47    fn parse(message: &Value, market: Option<&Market>) -> Result<Self::Output> {
48        parser::parse_ws_trade(message, market)
49    }
50}
51
52/// Parser for OHLCV (kline) stream messages.
53pub struct OhlcvParser;
54
55impl StreamParser for OhlcvParser {
56    type Output = OHLCV;
57
58    fn parse(message: &Value, _market: Option<&Market>) -> Result<Self::Output> {
59        parser::parse_ws_ohlcv(message)
60    }
61}
62
63/// Parser for mark price stream messages.
64pub struct MarkPriceParser;
65
66impl StreamParser for MarkPriceParser {
67    type Output = MarkPrice;
68
69    fn parse(message: &Value, _market: Option<&Market>) -> Result<Self::Output> {
70        parser::parse_ws_mark_price(message)
71    }
72}
73
74/// Parser for bid/ask (book ticker) stream messages.
75pub struct BidAskParser;
76
77impl StreamParser for BidAskParser {
78    type Output = BidAsk;
79
80    fn parse(message: &Value, _market: Option<&Market>) -> Result<Self::Output> {
81        parser::parse_ws_bid_ask(message)
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88    use serde_json::json;
89
90    #[test]
91    fn test_ticker_parser() {
92        let message = json!({
93            "e": "24hrTicker",
94            "s": "BTCUSDT",
95            "c": "50000.00",
96            "o": "49000.00",
97            "h": "51000.00",
98            "l": "48000.00",
99            "v": "1000.00",
100            "q": "50000000.00",
101            "C": 1234567890000_i64
102        });
103
104        let result = TickerParser::parse(&message, None);
105        assert!(result.is_ok());
106        let ticker = result.unwrap();
107        assert_eq!(ticker.symbol, "BTCUSDT");
108    }
109
110    #[test]
111    fn test_bid_ask_parser() {
112        let message = json!({
113            "s": "BTCUSDT",
114            "b": "50000.00",
115            "B": "1.5",
116            "a": "50001.00",
117            "A": "2.0",
118            "E": 1234567890000_i64
119        });
120
121        let result = BidAskParser::parse(&message, None);
122        assert!(result.is_ok());
123        let bid_ask = result.unwrap();
124        assert_eq!(bid_ask.symbol, "BTCUSDT");
125    }
126}