barter_data/subscriber/
mapper.rs

1use crate::{
2    Identifier,
3    exchange::{Connector, subscription::ExchangeSub},
4    instrument::InstrumentData,
5    subscription::{Map, Subscription, SubscriptionKind, SubscriptionMeta},
6};
7use barter_integration::subscription::SubscriptionId;
8use fnv::FnvHashMap;
9use serde::{Deserialize, Serialize};
10
11/// Defines how to map a collection of Barter [`Subscription`]s into exchange specific
12/// [`SubscriptionMeta`], containing subscription payloads that are sent to the exchange.
13pub trait SubscriptionMapper {
14    fn map<Exchange, Instrument, Kind>(
15        subscriptions: &[Subscription<Exchange, Instrument, Kind>],
16    ) -> SubscriptionMeta<Instrument::Key>
17    where
18        Exchange: Connector,
19        Instrument: InstrumentData,
20        Kind: SubscriptionKind,
21        Subscription<Exchange, Instrument, Kind>:
22            Identifier<Exchange::Channel> + Identifier<Exchange::Market>;
23}
24
25/// Standard [`SubscriptionMapper`] for
26/// [`WebSocket`](barter_integration::protocol::websocket::WebSocket)s suitable for most exchanges.
27#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, Serialize)]
28pub struct WebSocketSubMapper;
29
30impl SubscriptionMapper for WebSocketSubMapper {
31    fn map<Exchange, Instrument, Kind>(
32        subscriptions: &[Subscription<Exchange, Instrument, Kind>],
33    ) -> SubscriptionMeta<Instrument::Key>
34    where
35        Exchange: Connector,
36        Instrument: InstrumentData,
37        Kind: SubscriptionKind,
38        Subscription<Exchange, Instrument, Kind>:
39            Identifier<Exchange::Channel> + Identifier<Exchange::Market>,
40        ExchangeSub<Exchange::Channel, Exchange::Market>: Identifier<SubscriptionId>,
41    {
42        // Allocate SubscriptionIds HashMap to track identifiers for each actioned Subscription
43        let mut instrument_map = Map(FnvHashMap::with_capacity_and_hasher(
44            subscriptions.len(),
45            Default::default(),
46        ));
47
48        // Map Barter Subscriptions to exchange specific subscriptions
49        let exchange_subs = subscriptions
50            .iter()
51            .map(|subscription| {
52                // Translate Barter Subscription to exchange specific subscription
53                let exchange_sub = ExchangeSub::new(subscription);
54
55                // Determine the SubscriptionId associated with this exchange specific subscription
56                let subscription_id = exchange_sub.id();
57
58                // Use ExchangeSub SubscriptionId as the manager to this Barter Subscription
59                instrument_map
60                    .0
61                    .insert(subscription_id, subscription.instrument.key().clone());
62
63                exchange_sub
64            })
65            .collect::<Vec<ExchangeSub<Exchange::Channel, Exchange::Market>>>();
66
67        // Construct WebSocket message subscriptions requests
68        let ws_subscriptions = Exchange::requests(exchange_subs);
69
70        SubscriptionMeta {
71            instrument_map,
72            ws_subscriptions,
73        }
74    }
75}