use super::{Binance, futures::BinanceFuturesUsdMarket, spot::BinanceSpot};
use crate::{
Identifier,
subscription::{
Subscription,
book::{OrderBooksL1, OrderBooksL2},
candle::{CandleInterval, Candles},
liquidation::Liquidations,
trade::PublicTrades,
},
};
use serde::Serialize;
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Serialize)]
pub struct BinanceChannel(pub &'static str);
impl BinanceChannel {
pub const TRADES: Self = Self("@trade");
pub const ORDER_BOOK_L1: Self = Self("@bookTicker");
pub const ORDER_BOOK_L2: Self = Self("@depth@100ms");
pub const LIQUIDATIONS: Self = Self("@forceOrder");
#[must_use]
pub const fn spot_candle(interval: CandleInterval) -> Self {
match interval {
CandleInterval::Sec1 => Self("@kline_1s"),
CandleInterval::Min1 => Self("@kline_1m"),
CandleInterval::Min3 => Self("@kline_3m"),
CandleInterval::Min5 => Self("@kline_5m"),
CandleInterval::Min15 => Self("@kline_15m"),
CandleInterval::Min30 => Self("@kline_30m"),
CandleInterval::Hour1 => Self("@kline_1h"),
CandleInterval::Hour2 => Self("@kline_2h"),
CandleInterval::Hour4 => Self("@kline_4h"),
CandleInterval::Hour6 => Self("@kline_6h"),
CandleInterval::Hour8 => Self("@kline_8h"),
CandleInterval::Hour12 => Self("@kline_12h"),
CandleInterval::Day1 => Self("@kline_1d"),
CandleInterval::Day3 => Self("@kline_3d"),
CandleInterval::Week1 => Self("@kline_1w"),
CandleInterval::Month1 => Self("@kline_1M"),
}
}
#[must_use]
pub const fn futures_candle(interval: CandleInterval) -> Self {
match interval {
CandleInterval::Sec1 => Self("_perpetual@continuousKline_1s"),
CandleInterval::Min1 => Self("_perpetual@continuousKline_1m"),
CandleInterval::Min3 => Self("_perpetual@continuousKline_3m"),
CandleInterval::Min5 => Self("_perpetual@continuousKline_5m"),
CandleInterval::Min15 => Self("_perpetual@continuousKline_15m"),
CandleInterval::Min30 => Self("_perpetual@continuousKline_30m"),
CandleInterval::Hour1 => Self("_perpetual@continuousKline_1h"),
CandleInterval::Hour2 => Self("_perpetual@continuousKline_2h"),
CandleInterval::Hour4 => Self("_perpetual@continuousKline_4h"),
CandleInterval::Hour6 => Self("_perpetual@continuousKline_6h"),
CandleInterval::Hour8 => Self("_perpetual@continuousKline_8h"),
CandleInterval::Hour12 => Self("_perpetual@continuousKline_12h"),
CandleInterval::Day1 => Self("_perpetual@continuousKline_1d"),
CandleInterval::Day3 => Self("_perpetual@continuousKline_3d"),
CandleInterval::Week1 => Self("_perpetual@continuousKline_1w"),
CandleInterval::Month1 => Self("_perpetual@continuousKline_1M"),
}
}
}
impl<Server, Instrument> Identifier<BinanceChannel>
for Subscription<Binance<Server>, Instrument, PublicTrades>
{
fn id(&self) -> BinanceChannel {
BinanceChannel::TRADES
}
}
impl<Server, Instrument> Identifier<BinanceChannel>
for Subscription<Binance<Server>, Instrument, OrderBooksL1>
{
fn id(&self) -> BinanceChannel {
BinanceChannel::ORDER_BOOK_L1
}
}
impl<Server, Instrument> Identifier<BinanceChannel>
for Subscription<Binance<Server>, Instrument, OrderBooksL2>
{
fn id(&self) -> BinanceChannel {
BinanceChannel::ORDER_BOOK_L2
}
}
impl<Instrument> Identifier<BinanceChannel>
for Subscription<BinanceFuturesUsdMarket, Instrument, Liquidations>
{
fn id(&self) -> BinanceChannel {
BinanceChannel::LIQUIDATIONS
}
}
impl<Instrument> Identifier<BinanceChannel> for Subscription<BinanceSpot, Instrument, Candles> {
fn id(&self) -> BinanceChannel {
BinanceChannel::spot_candle(self.kind.interval)
}
}
impl<Instrument> Identifier<BinanceChannel>
for Subscription<BinanceFuturesUsdMarket, Instrument, Candles>
{
fn id(&self) -> BinanceChannel {
BinanceChannel::futures_candle(self.kind.interval)
}
}
impl AsRef<str> for BinanceChannel {
fn as_ref(&self) -> &str {
self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn spot_candle_channel_suffix_matches_interval() {
for interval in CandleInterval::ALL {
let channel = BinanceChannel::spot_candle(interval).0;
assert_eq!(
channel,
format!("@kline_{}", interval.as_str()),
"spot channel drifted for {interval:?}"
);
}
}
#[test]
fn futures_candle_channel_suffix_matches_interval() {
for interval in CandleInterval::ALL {
let channel = BinanceChannel::futures_candle(interval).0;
assert_eq!(
channel,
format!("_perpetual@continuousKline_{}", interval.as_str()),
"futures channel drifted for {interval:?}"
);
}
}
}