use serde::{Deserialize, Serialize};
fn deserialize_number<'de, D>(deserializer: D) -> Result<f64, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::{self, Visitor};
struct NumberVisitor;
impl<'de> Visitor<'de> for NumberVisitor {
type Value = f64;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a number or string representation of a number")
}
fn visit_f64<E>(self, value: f64) -> Result<f64, E> {
Ok(value)
}
fn visit_i64<E>(self, value: i64) -> Result<f64, E> {
Ok(value as f64)
}
fn visit_u64<E>(self, value: u64) -> Result<f64, E> {
Ok(value as f64)
}
fn visit_str<E>(self, value: &str) -> Result<f64, E>
where
E: de::Error,
{
value.parse::<f64>().map_err(de::Error::custom)
}
}
deserializer.deserialize_any(NumberVisitor)
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum TradeSide {
Buy,
Sell,
}
impl std::fmt::Display for TradeSide {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TradeSide::Buy => write!(f, "buy"),
TradeSide::Sell => write!(f, "sell"),
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum TradeOrderType {
Market,
Limit,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Trade {
pub symbol: String,
pub side: TradeSide,
pub price: f64,
pub qty: f64,
pub ord_type: TradeOrderType,
pub trade_id: i64,
pub timestamp: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeDataRaw {
pub symbol: String,
pub side: TradeSide,
#[serde(deserialize_with = "deserialize_number")]
pub price: f64,
#[serde(deserialize_with = "deserialize_number")]
pub qty: f64,
pub ord_type: TradeOrderType,
pub trade_id: i64,
pub timestamp: String,
}
impl TradeDataRaw {
pub fn to_trade(&self) -> Trade {
Trade {
symbol: self.symbol.clone(),
side: self.side,
price: self.price,
qty: self.qty,
ord_type: self.ord_type,
trade_id: self.trade_id,
timestamp: self.timestamp.clone(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradeUpdate {
#[serde(default)]
pub channel: String,
#[serde(rename = "type")]
pub update_type: String,
pub data: Vec<TradeDataRaw>,
}