Skip to main content

rustrade_data/exchange/
subscription.rs

1use crate::{Identifier, subscription::Subscription};
2use rustrade_integration::subscription::SubscriptionId;
3use serde::Deserialize;
4use smol_str::format_smolstr;
5
6/// Defines an exchange specific market and channel combination used by an exchange
7/// [`Connector`](super::Connector) to build the
8/// [`WsMessage`](rustrade_integration::protocol::websocket::WsMessage) subscription payloads to
9/// send to the exchange server.
10///
11/// ### Examples
12/// #### Binance OrderBooksL2
13/// ```json
14/// ExchangeSub {
15///     channel: BinanceChannel("@depth@100ms"),
16///     market: BinanceMarket("btcusdt"),
17/// }
18/// ```
19/// #### Kraken PublicTrades
20/// ```json
21/// ExchangeSub {
22///     channel: KrakenChannel("trade"),
23///     market: KrakenChannel("BTC/USDT")
24/// }
25/// ```
26#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize)]
27pub struct ExchangeSub<Channel, Market> {
28    /// Type that defines how to translate a Barter [`Subscription`] into an exchange specific
29    /// channel to be subscribed to.
30    ///
31    /// ### Examples
32    /// - [`BinanceChannel("@depth@100ms")`](super::binance::channel::BinanceChannel)
33    /// - [`KrakenChannel("trade")`](super::kraken::channel::KrakenChannel)
34    pub channel: Channel,
35
36    /// Type that defines how to translate a Barter [`Subscription`] into an exchange specific
37    /// market that can be subscribed to.
38    ///
39    /// ### Examples
40    /// - [`BinanceMarket("btcusdt")`](super::binance::market::BinanceMarket)
41    /// - [`KrakenMarket("BTC/USDT")`](super::kraken::market::KrakenMarket)
42    pub market: Market,
43}
44
45impl<Channel, Market> Identifier<SubscriptionId> for ExchangeSub<Channel, Market>
46where
47    Channel: AsRef<str>,
48    Market: AsRef<str>,
49{
50    fn id(&self) -> SubscriptionId {
51        SubscriptionId(format_smolstr!(
52            "{}|{}",
53            self.channel.as_ref(),
54            self.market.as_ref()
55        ))
56    }
57}
58
59impl<Channel, Market> ExchangeSub<Channel, Market>
60where
61    Channel: AsRef<str>,
62    Market: AsRef<str>,
63{
64    /// Construct a new exchange specific [`Self`] with the Barter [`Subscription`] provided.
65    pub fn new<Exchange, Instrument, Kind>(sub: &Subscription<Exchange, Instrument, Kind>) -> Self
66    where
67        Subscription<Exchange, Instrument, Kind>: Identifier<Channel> + Identifier<Market>,
68    {
69        Self {
70            channel: sub.id(),
71            market: sub.id(),
72        }
73    }
74}
75
76impl<Channel, Market> From<(Channel, Market)> for ExchangeSub<Channel, Market>
77where
78    Channel: AsRef<str>,
79    Market: AsRef<str>,
80{
81    fn from((channel, market): (Channel, Market)) -> Self {
82        Self { channel, market }
83    }
84}