use serde::{Deserialize, Deserializer};
use crate::live::frame::fields::blank;
use crate::utils::{Dec, MarketId};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
pub struct Level {
pub price: Dec,
pub size: Dec,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BookUpdate {
pub market: MarketId,
pub asks: Vec<Level>,
pub bids: Vec<Level>,
pub nonce: u64,
pub begin_nonce: u64,
pub offset: u64,
pub last_updated_at: u64,
pub timestamp: u64,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Ticker {
pub market: MarketId,
pub symbol: String,
pub ask: Option<Level>,
pub bid: Option<Level>,
pub nonce: u64,
pub last_updated_at: u64,
pub timestamp: u64,
}
impl Ticker {
#[must_use]
pub fn mid(&self) -> Option<Dec> {
halfway(self.bid?.price, self.ask?.price)
}
}
pub(crate) fn halfway(a: Dec, b: Dec) -> Option<Dec> {
a.checked_add(b)?.checked_mul(Dec::lit::<1>(5))
}
pub(crate) fn side<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Option<Level>, D::Error> {
#[derive(Deserialize)]
struct Raw {
#[serde(default, deserialize_with = "blank")]
price: Option<Dec>,
#[serde(default, deserialize_with = "blank")]
size: Option<Dec>,
}
let raw: Option<Raw> = Option::deserialize(deserializer)?;
Ok(raw.and_then(|raw| Some(Level { price: raw.price?, size: raw.size.unwrap_or(Dec::ZERO) })))
}