1use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct OrderSummary {
10 pub price: String,
12 pub size: String,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct BookMessage {
19 pub event_type: String,
21 pub asset_id: String,
23 pub market: String,
25 pub timestamp: String,
27 pub hash: String,
29 pub bids: Vec<OrderSummary>,
31 pub asks: Vec<OrderSummary>,
33 pub last_trade_price: Option<String>,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct PriceChange {
40 pub asset_id: String,
42 pub price: String,
44 pub size: String,
46 pub side: String,
48 pub hash: String,
50 pub best_bid: Option<String>,
52 pub best_ask: Option<String>,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct PriceChangeMessage {
59 pub event_type: String,
61 pub market: String,
63 pub price_changes: Vec<PriceChange>,
65 pub timestamp: String,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct TickSizeChangeMessage {
72 pub event_type: String,
74 pub asset_id: String,
76 pub market: String,
78 pub old_tick_size: String,
80 pub new_tick_size: String,
82 pub side: String,
84 pub timestamp: String,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct LastTradePriceMessage {
91 pub event_type: String,
93 pub asset_id: String,
95 pub market: String,
97 pub price: String,
99 pub side: String,
101 pub size: String,
103 pub fee_rate_bps: Option<String>,
105 pub timestamp: String,
107}
108
109#[derive(Debug, Clone, Serialize)]
111#[serde(untagged)]
112pub enum MarketMessage {
113 Book(BookMessage),
115 PriceChange(PriceChangeMessage),
117 TickSizeChange(TickSizeChangeMessage),
119 LastTradePrice(LastTradePriceMessage),
121}
122
123impl MarketMessage {
124 pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
126 if json.starts_with('[') {
128 let books: Vec<BookMessage> = serde_json::from_str(json)?;
129 if let Some(book) = books.into_iter().next() {
130 return Ok(MarketMessage::Book(book));
131 }
132 return Err(serde::de::Error::custom("Empty book array"));
133 }
134
135 #[derive(Deserialize)]
136 struct RawMessage {
137 event_type: String,
138 }
139
140 let raw: RawMessage = serde_json::from_str(json)?;
141 match raw.event_type.as_str() {
142 "book" => Ok(MarketMessage::Book(serde_json::from_str(json)?)),
143 "price_change" => Ok(MarketMessage::PriceChange(serde_json::from_str(json)?)),
144 "tick_size_change" => Ok(MarketMessage::TickSizeChange(serde_json::from_str(json)?)),
145 "last_trade_price" => Ok(MarketMessage::LastTradePrice(serde_json::from_str(json)?)),
146 _ => Err(serde::de::Error::custom(format!(
147 "Unknown market event type: {}",
148 raw.event_type
149 ))),
150 }
151 }
152}