use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrderSummary {
pub price: String,
pub size: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BookMessage {
pub event_type: String,
pub asset_id: String,
pub market: String,
pub timestamp: String,
pub hash: String,
pub bids: Vec<OrderSummary>,
pub asks: Vec<OrderSummary>,
pub last_trade_price: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PriceChange {
pub asset_id: String,
pub price: String,
pub size: String,
pub side: String,
pub hash: String,
pub best_bid: Option<String>,
pub best_ask: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PriceChangeMessage {
pub event_type: String,
pub market: String,
pub price_changes: Vec<PriceChange>,
pub timestamp: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TickSizeChangeMessage {
pub event_type: String,
pub asset_id: String,
pub market: String,
pub old_tick_size: String,
pub new_tick_size: String,
pub side: String,
pub timestamp: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LastTradePriceMessage {
pub event_type: String,
pub asset_id: String,
pub market: String,
pub price: String,
pub side: String,
pub size: String,
pub fee_rate_bps: Option<String>,
pub timestamp: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub enum MarketMessage {
Book(BookMessage),
PriceChange(PriceChangeMessage),
TickSizeChange(TickSizeChangeMessage),
LastTradePrice(LastTradePriceMessage),
}
impl MarketMessage {
pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
if json.starts_with('[') {
let books: Vec<BookMessage> = serde_json::from_str(json)?;
if let Some(book) = books.into_iter().next() {
return Ok(MarketMessage::Book(book));
}
return Err(serde::de::Error::custom("Empty book array"));
}
#[derive(Deserialize)]
struct RawMessage {
event_type: String,
}
let raw: RawMessage = serde_json::from_str(json)?;
match raw.event_type.as_str() {
"book" => Ok(MarketMessage::Book(serde_json::from_str(json)?)),
"price_change" => Ok(MarketMessage::PriceChange(serde_json::from_str(json)?)),
"tick_size_change" => Ok(MarketMessage::TickSizeChange(serde_json::from_str(json)?)),
"last_trade_price" => Ok(MarketMessage::LastTradePrice(serde_json::from_str(json)?)),
_ => Err(serde::de::Error::custom(format!(
"Unknown market event type: {}",
raw.event_type
))),
}
}
}