rusty_feeder/provider/subscription.rs
1use smallvec::SmallVec;
2use smartstring::alias::String;
3use std::fmt::Debug;
4use uuid;
5
6/// Subscription type for WebSocket feeds
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum SubscriptionType {
9 /// Real-time trade data
10 Trade,
11
12 /// Order book / market depth data
13 OrderBook,
14
15 /// Ticker / price data
16 Ticker,
17
18 /// Kline / candlestick data
19 Kline,
20
21 /// User data (private feeds)
22 UserData,
23
24 /// Price index data (for futures/derivatives)
25 PriceIndex,
26
27 /// Liquidation event data (for futures/derivatives)
28 LiquidationEvent,
29}
30
31/// Cache-line aligned standardized subscription options
32/// Designed to work consistently across different exchange implementations
33#[derive(Debug, Clone)]
34#[repr(align(64))] // Cache-line alignment for better CPU cache efficiency
35pub struct SubscriptionOptions {
36 /// Unique identifier for the subscription
37 pub id: String,
38
39 /// List of symbols to subscribe to
40 pub symbols: SmallVec<[String; 8]>,
41
42 /// Type of subscription
43 pub subscription_type: SubscriptionType,
44
45 /// Optional request ID for tracking responses
46 pub request_id: Option<u64>,
47
48 /// Depth level for order book subscriptions
49 pub depth: Option<u32>,
50
51 /// Update speed in milliseconds (e.g., 100ms, 1000ms)
52 pub update_speed_ms: Option<u64>,
53
54 /// Whether to only send snapshot data (no real-time updates)
55 pub snapshot_only: bool,
56
57 /// Whether to only send real-time data (no initial snapshot)
58 pub realtime_only: bool,
59
60 /// Optional format specifier (e.g., "DEFAULT", "SIMPLE")
61 pub format: Option<String>,
62
63 /// Optional API key for authenticated streams
64 pub api_key: Option<String>,
65
66 /// Whether this is a test subscription
67 pub test: bool,
68
69 /// Interval for kline subscriptions (e.g., "1m", "1h", "1d")
70 pub interval: Option<String>,
71
72 /// Whether to use combined streams (for multiple symbols)
73 pub use_combined_streams: bool,
74}
75
76impl Default for SubscriptionOptions {
77 fn default() -> Self {
78 Self {
79 id: String::from(uuid::Uuid::new_v4().to_string()),
80 symbols: SmallVec::new(),
81 subscription_type: SubscriptionType::Trade,
82 request_id: None,
83 depth: None,
84 update_speed_ms: None,
85 snapshot_only: false,
86 realtime_only: false,
87 format: None,
88 api_key: None,
89 test: false,
90 interval: None,
91 use_combined_streams: true,
92 }
93 }
94}
95
96/// Generic trait for converting standardized subscription options to exchange-specific formats
97///
98/// This trait defines the interface that all exchange-specific subscription converters
99/// must implement to convert from the standardized SubscriptionOptions structure to
100/// the exchange's native format.
101pub trait SubscriptionConverter<T: Debug> {
102 /// Convert standardized SubscriptionOptions to exchange-specific format
103 ///
104 /// This method must be implemented by each exchange to convert the common
105 /// subscription options into a format that can be sent directly to the exchange's
106 /// WebSocket API.
107 ///
108 /// # Arguments
109 /// * `options` - The standardized subscription options
110 ///
111 /// # Returns
112 /// An exchange-specific subscription message/request of type T
113 fn convert(options: &SubscriptionOptions) -> T;
114
115 /// Create a trade subscription message for the specified symbols
116 ///
117 /// # Arguments
118 /// * `ticket` - A unique identifier for the subscription (correlation ID)
119 /// * `symbols` - List of symbols to subscribe to
120 /// * `is_snapshot_only` - Optional flag to only receive snapshot data
121 /// * `is_realtime_only` - Optional flag to only receive real-time updates
122 /// * `additional_params` - Optional additional parameters for the exchange
123 ///
124 /// # Returns
125 /// An exchange-specific subscription message/request
126 fn create_trade_subscription(
127 ticket: &str,
128 symbols: SmallVec<[String; 8]>,
129 is_snapshot_only: Option<bool>,
130 is_realtime_only: Option<bool>,
131 additional_params: Option<&[(&str, &str)]>,
132 ) -> T;
133
134 /// Create an orderbook subscription message for the specified symbols
135 ///
136 /// # Arguments
137 /// * `ticket` - A unique identifier for the subscription (correlation ID)
138 /// * `symbols` - List of symbols to subscribe to
139 /// * `depth` - Optional depth level
140 /// * `update_speed` - Optional update speed in milliseconds
141 /// * `is_snapshot_only` - Optional flag to only receive snapshot data
142 /// * `is_realtime_only` - Optional flag to only receive real-time updates
143 /// * `additional_params` - Optional additional parameters for the exchange
144 ///
145 /// # Returns
146 /// An exchange-specific subscription message/request
147 fn create_orderbook_subscription(
148 ticket: &str,
149 symbols: SmallVec<[String; 8]>,
150 depth: Option<u32>,
151 update_speed: Option<u64>,
152 is_snapshot_only: Option<bool>,
153 is_realtime_only: Option<bool>,
154 additional_params: Option<&[(&str, &str)]>,
155 ) -> T;
156
157 /// Create a ticker subscription message for the specified symbols
158 ///
159 /// # Arguments
160 /// * `ticket` - A unique identifier for the subscription (correlation ID)
161 /// * `symbols` - List of symbols to subscribe to
162 /// * `is_snapshot_only` - Optional flag to only receive snapshot data
163 /// * `is_realtime_only` - Optional flag to only receive real-time updates
164 /// * `additional_params` - Optional additional parameters for the exchange
165 ///
166 /// # Returns
167 /// An exchange-specific subscription message/request
168 fn create_ticker_subscription(
169 ticket: &str,
170 symbols: SmallVec<[String; 8]>,
171 is_snapshot_only: Option<bool>,
172 is_realtime_only: Option<bool>,
173 additional_params: Option<&[(&str, &str)]>,
174 ) -> T;
175
176 /// Create a kline/candlestick subscription message for the specified symbols
177 ///
178 /// # Arguments
179 /// * `ticket` - A unique identifier for the subscription (correlation ID)
180 /// * `symbols` - List of symbols to subscribe to
181 /// * `interval` - Time interval (e.g., "1m", "1h", "1d")
182 /// * `is_snapshot_only` - Optional flag to only receive snapshot data
183 /// * `is_realtime_only` - Optional flag to only receive real-time updates
184 /// * `additional_params` - Optional additional parameters for the exchange
185 ///
186 /// # Returns
187 /// An exchange-specific subscription message/request
188 fn create_kline_subscription(
189 ticket: &str,
190 symbols: SmallVec<[String; 8]>,
191 interval: &str,
192 is_snapshot_only: Option<bool>,
193 is_realtime_only: Option<bool>,
194 additional_params: Option<&[(&str, &str)]>,
195 ) -> T;
196}