rustrade_data/subscriber/
mod.rs1use self::{
2 mapper::{SubscriptionMapper, WebSocketSubMapper},
3 validator::SubscriptionValidator,
4};
5use crate::{
6 Identifier,
7 exchange::Connector,
8 instrument::InstrumentData,
9 subscription::{Map, Subscription, SubscriptionKind, SubscriptionMeta},
10};
11use futures::SinkExt;
12use rustrade_integration::{
13 error::SocketError,
14 protocol::websocket::{WebSocket, WsMessage, connect},
15};
16use serde::{Deserialize, Serialize};
17use std::{fmt::Debug, future::Future};
18use tracing::debug;
19
20pub mod mapper;
23
24pub mod validator;
27
28#[cfg(any(feature = "alpaca", feature = "lse", feature = "massive"))]
31pub(crate) mod shared;
32
33#[cfg(any(feature = "alpaca", feature = "lse", feature = "massive"))]
35pub mod shared_stream;
36
37pub trait Subscriber: Clone + Send + Sync {
43 type SubMapper: SubscriptionMapper;
44
45 type Transport: Send;
54
55 fn subscribe<Exchange, Instrument, Kind>(
56 &self,
57 subscriptions: &[Subscription<Exchange, Instrument, Kind>],
58 ) -> impl Future<Output = Result<Subscribed<Instrument::Key, Self::Transport>, SocketError>> + Send
59 where
60 Exchange: Connector + Send + Sync,
61 Kind: SubscriptionKind + Send + Sync,
62 Instrument: InstrumentData,
63 Subscription<Exchange, Instrument, Kind>:
64 Identifier<Exchange::Channel> + Identifier<Exchange::Market>;
65}
66
67#[derive(Debug)]
69pub struct Subscribed<InstrumentKey, Transport = WebSocket> {
70 pub transport: Transport,
72 pub map: Map<InstrumentKey>,
74 pub buffered_websocket_events: Vec<WsMessage>,
81}
82
83#[derive(
87 Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Deserialize, Serialize,
88)]
89pub struct WebSocketSubscriber;
90
91impl Subscriber for WebSocketSubscriber {
92 type SubMapper = WebSocketSubMapper;
93 type Transport = WebSocket;
94
95 async fn subscribe<Exchange, Instrument, Kind>(
96 &self,
97 subscriptions: &[Subscription<Exchange, Instrument, Kind>],
98 ) -> Result<Subscribed<Instrument::Key, Self::Transport>, SocketError>
99 where
100 Exchange: Connector + Send + Sync,
101 Kind: SubscriptionKind + Send + Sync,
102 Instrument: InstrumentData,
103 Subscription<Exchange, Instrument, Kind>:
104 Identifier<Exchange::Channel> + Identifier<Exchange::Market>,
105 {
106 let exchange = Exchange::ID;
108 let url = Exchange::url()?;
109 debug!(%exchange, %url, ?subscriptions, "subscribing to WebSocket");
110
111 let mut websocket = connect(url).await?;
113 debug!(%exchange, ?subscriptions, "connected to WebSocket");
114
115 let SubscriptionMeta {
117 instrument_map,
118 ws_subscriptions,
119 } = Self::SubMapper::map::<Exchange, Instrument, Kind>(subscriptions);
120
121 for subscription in ws_subscriptions {
123 debug!(%exchange, payload = ?subscription, "sending exchange subscription");
124 websocket
125 .send(subscription)
126 .await
127 .map_err(|error| SocketError::WebSocket(Box::new(error)))?;
128 }
129
130 let (map, buffered_websocket_events) = Exchange::SubValidator::validate::<
132 Exchange,
133 Instrument::Key,
134 Kind,
135 >(instrument_map, &mut websocket)
136 .await?;
137
138 debug!(%exchange, "successfully initialised WebSocket stream with confirmed Subscriptions");
139 Ok(Subscribed {
140 transport: websocket,
141 map,
142 buffered_websocket_events,
143 })
144 }
145}