mexc_rs/spot/ws/message/
orderbook_update.rs

1use rust_decimal::Decimal;
2
3use crate::spot::v3::depth::PriceAndQuantity;
4
5use super::{RawChannelMessage, RawChannelMessageData, RawEventChannelMessageData};
6
7#[allow(non_snake_case)]
8#[derive(Debug, Clone, Copy, serde::Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub(crate) struct RawOrderData {
11    #[serde(rename = "p")]
12    pub price: Decimal,
13    #[serde(rename = "v")]
14    pub quantity: Decimal,
15}
16
17#[derive(Debug)]
18pub struct OrderbookUpdateMessage {
19    pub symbol: String,
20    pub version: u64,
21    pub asks: Vec<PriceAndQuantity>,
22    pub bids: Vec<PriceAndQuantity>,
23}
24
25#[derive(Debug, thiserror::Error)]
26pub enum ChannelMessageToOrderbookUpdateMessageError {
27    #[error("No orderbook update message")]
28    NoOrderbookUpdateMessage,
29}
30
31pub(crate) fn channel_message_to_spot_orderbook_update_message(
32    channel_message: &RawChannelMessage,
33) -> Result<OrderbookUpdateMessage, ChannelMessageToOrderbookUpdateMessageError> {
34    let Some(symbol) = &channel_message.symbol else {
35        return Err(ChannelMessageToOrderbookUpdateMessageError::NoOrderbookUpdateMessage);
36    };
37    let RawChannelMessageData::Event(event) = &channel_message.data else {
38        return Err(ChannelMessageToOrderbookUpdateMessageError::NoOrderbookUpdateMessage);
39    };
40    let RawEventChannelMessageData::OrdersUpdate {
41        asks,
42        bids,
43        version,
44        ..
45    } = &event
46    else {
47        return Err(ChannelMessageToOrderbookUpdateMessageError::NoOrderbookUpdateMessage);
48    };
49
50    let message = OrderbookUpdateMessage {
51        symbol: symbol.clone(),
52        version: version
53            .parse()
54            .map_err(|_| ChannelMessageToOrderbookUpdateMessageError::NoOrderbookUpdateMessage)?,
55        asks: match asks {
56            Some(asks) => asks
57                .iter()
58                .map(|raw| PriceAndQuantity {
59                    price: raw.price,
60                    quantity: raw.quantity,
61                })
62                .collect(),
63            None => vec![],
64        },
65        bids: match bids {
66            Some(bids) => bids
67                .iter()
68                .map(|raw| PriceAndQuantity {
69                    price: raw.price,
70                    quantity: raw.quantity,
71                })
72                .collect(),
73            None => vec![],
74        },
75    };
76    Ok(message)
77}