use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
pub struct TickerData {
#[serde(rename = "symbol")]
#[serde(default)]
pub symbol: Option<String>,
#[serde(rename = "lastPrice")]
#[serde(default)]
pub last_price: Option<String>,
#[serde(rename = "highPrice24h")]
#[serde(default)]
pub high_price_24h: Option<String>,
#[serde(rename = "lowPrice24h")]
#[serde(default)]
pub low_price_24h: Option<String>,
#[serde(rename = "prevPrice24h")]
#[serde(default)]
pub prev_price_24h: Option<String>,
#[serde(rename = "price24hPcnt")]
#[serde(default)]
pub price_24h_pcnt: Option<String>,
#[serde(rename = "volume24h")]
#[serde(default)]
pub volume_24h: Option<String>,
#[serde(rename = "turnover24h")]
#[serde(default)]
pub turnover_24h: Option<String>,
#[serde(rename = "openInterest")]
#[serde(default)]
pub open_interest: Option<String>,
#[serde(rename = "openInterestValue")]
#[serde(default)]
pub open_interest_value: Option<String>,
#[serde(rename = "indexPrice")]
#[serde(default)]
pub index_price: Option<String>,
#[serde(rename = "markPrice")]
#[serde(default)]
pub mark_price: Option<String>,
#[serde(rename = "fundingRate")]
#[serde(default)]
pub funding_rate: Option<String>,
#[serde(rename = "nextFundingTime")]
#[serde(default)]
pub next_funding_time: Option<String>,
#[serde(rename = "bid1Price")]
#[serde(default)]
pub bid1_price: Option<String>,
#[serde(rename = "ask1Price")]
#[serde(default)]
pub ask1_price: Option<String>,
#[serde(rename = "category")]
#[serde(default)]
pub category: Option<String>,
}
pub struct TickerStream;
impl TickerStream {
pub fn parse(data: &serde_json::Value) -> serde_json::Result<TickerData> {
serde_json::from_value(data.clone())
}
pub fn matches_topic(topic: &str) -> bool {
topic.starts_with("tickers.")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_ticker() {
let json = serde_json::json!({
"symbol": "BTCUSDT",
"lastPrice": "50000.00",
"highPrice24h": "51000.00",
"lowPrice24h": "49000.00",
"volume24h": "15000.5",
"turnover24h": "750000000.00",
"price24hPcnt": "0.025",
"category": "linear"
});
let ticker = TickerStream::parse(&json).unwrap();
assert_eq!(ticker.symbol.as_deref(), Some("BTCUSDT"));
assert_eq!(ticker.last_price.as_deref(), Some("50000.00"));
assert_eq!(ticker.category.as_deref(), Some("linear"));
}
#[test]
fn test_matches_topic() {
assert!(TickerStream::matches_topic("tickers.BTCUSDT"));
assert!(!TickerStream::matches_topic("orderbook.1.BTCUSDT"));
}
}