1use super::super::QotRightData;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4pub struct QotRightReconnectToken(pub(in crate::qot_right) u64);
5
6impl QotRightReconnectToken {
7 #[must_use]
8 pub const fn value(self) -> u64 {
9 self.0
10 }
11}
12
13#[derive(Debug, Clone, Default, PartialEq, Eq)]
14pub struct QotRightReconnectAccumulator {
15 pub requested_highest: bool,
16 pub highest_changed_quote_types: Vec<i32>,
17 pub external_changed_quote_types: Vec<i32>,
18 pub latest_pushed_notify_version: Option<u64>,
19}
20
21impl QotRightReconnectAccumulator {
22 #[must_use]
23 pub fn highest(changed_quote_types: &[i32]) -> Self {
24 let mut value = Self {
25 requested_highest: true,
26 highest_changed_quote_types: changed_quote_types.to_vec(),
27 ..Self::default()
28 };
29 value.canonicalize();
30 value
31 }
32
33 #[must_use]
34 pub fn external(changed_quote_types: &[i32], pushed_notify_version: u64) -> Self {
35 let mut value = Self {
36 external_changed_quote_types: changed_quote_types.to_vec(),
37 latest_pushed_notify_version: Some(pushed_notify_version),
38 ..Self::default()
39 };
40 value.canonicalize();
41 value
42 }
43
44 pub(in crate::qot_right) fn merge(&mut self, other: &Self) {
45 self.requested_highest |= other.requested_highest;
46 self.highest_changed_quote_types
47 .extend_from_slice(&other.highest_changed_quote_types);
48 self.external_changed_quote_types
49 .extend_from_slice(&other.external_changed_quote_types);
50 self.latest_pushed_notify_version = match (
51 self.latest_pushed_notify_version,
52 other.latest_pushed_notify_version,
53 ) {
54 (Some(left), Some(right)) => Some(left.max(right)),
55 (left, right) => left.or(right),
56 };
57 self.canonicalize();
58 }
59
60 fn canonicalize(&mut self) {
61 canonicalize_reconnect_quote_types(&mut self.highest_changed_quote_types);
62 canonicalize_reconnect_quote_types(&mut self.external_changed_quote_types);
63 }
64
65 #[must_use]
66 pub fn effective_exclusion_quote_types(&self) -> Vec<i32> {
67 if !self.requested_highest {
68 return Vec::new();
69 }
70 let mut values = self.highest_changed_quote_types.clone();
71 values.extend_from_slice(&self.external_changed_quote_types);
72 canonicalize_reconnect_quote_types(&mut values);
73 values
74 }
75
76 #[must_use]
77 pub fn is_empty(&self) -> bool {
78 !self.requested_highest
79 && self.highest_changed_quote_types.is_empty()
80 && self.external_changed_quote_types.is_empty()
81 && self.latest_pushed_notify_version.is_none()
82 }
83}
84
85fn canonicalize_reconnect_quote_types(values: &mut Vec<i32>) {
86 const CPP_PARSE_ORDER: &[i32] = &[
90 1, 5, 4, 17, 8, 19, 11, 30, 31, 32, 33, 16, 40, 41, 38, 37, 36, 39, 20, 29,
91 ];
92 values.sort_by_key(|value| {
93 CPP_PARSE_ORDER
94 .iter()
95 .position(|candidate| candidate == value)
96 .map_or((usize::MAX, *value), |rank| (rank, 0))
97 });
98 values.dedup();
99}
100
101#[derive(Debug, Clone, Default, PartialEq, Eq)]
102pub enum QotRightReconnectLifecycle {
103 #[default]
104 Idle,
105 Deferred {
106 token: QotRightReconnectToken,
107 generation: u64,
108 accumulator: QotRightReconnectAccumulator,
109 dispatch_admitted: bool,
110 },
111 Pending {
112 token: QotRightReconnectToken,
113 generation: u64,
114 accumulator: QotRightReconnectAccumulator,
115 },
116 InFlight {
117 token: QotRightReconnectToken,
118 generation: u64,
119 serving: QotRightReconnectAccumulator,
120 follow_up: QotRightReconnectAccumulator,
121 },
122}
123
124#[derive(Debug, Clone, PartialEq, Eq)]
125pub enum QotRightReconnectClaimKind {
126 OrdinaryHighest,
127 Entitlement(QotRightReconnectAccumulator),
128}
129
130#[derive(Debug, Clone, PartialEq, Eq)]
131pub struct QotRightReconnectClaim {
132 pub token: QotRightReconnectToken,
133 pub source_generation: u64,
134 pub active_generation: u64,
135 pub kind: QotRightReconnectClaimKind,
136}
137
138#[derive(Debug, Clone, Copy, PartialEq, Eq)]
139pub struct QotRightReconnectRegistration {
140 pub token: QotRightReconnectToken,
141 pub owns_deferred: bool,
142 pub should_disconnect: bool,
143}
144
145#[derive(Debug, Clone, Copy, PartialEq, Eq)]
146pub struct QotRightReconnectHandoff {
147 pub token: QotRightReconnectToken,
148 pub source_generation: u64,
149}
150
151#[derive(Debug, Clone, PartialEq, Eq)]
152pub(in crate::qot_right) struct QotRightPublicSnapshot {
153 hk_qot_right: i32,
154 api_us_qot_right: i32,
155 sh_qot_right: i32,
156 sz_qot_right: i32,
157 hk_option_qot_right: i32,
158 hk_future_qot_right: i32,
159 has_us_option_qot_right: bool,
160 us_option_qot_right: i32,
161 us_index_qot_right: i32,
162 us_otc_qot_right: i32,
163 us_cme_future_qot_right: i32,
164 us_cbot_future_qot_right: i32,
165 us_nymex_future_qot_right: i32,
166 us_comex_future_qot_right: i32,
167 us_cboe_future_qot_right: i32,
168 sg_future_qot_right: i32,
169 jp_future_qot_right: i32,
170 sg_stock_qot_right: i32,
171 my_stock_qot_right: i32,
172 jp_stock_qot_right: i32,
173 cc_qot_right: i32,
174 event_contract_qot_right: i32,
175}
176
177impl From<&QotRightData> for QotRightPublicSnapshot {
178 fn from(data: &QotRightData) -> Self {
179 Self {
180 hk_qot_right: data.hk_qot_right,
181 api_us_qot_right: data.api_us_qot_right,
182 sh_qot_right: data.sh_qot_right,
183 sz_qot_right: data.sz_qot_right,
184 hk_option_qot_right: data.hk_option_qot_right,
185 hk_future_qot_right: data.hk_future_qot_right,
186 has_us_option_qot_right: data.has_us_option_qot_right,
187 us_option_qot_right: data.us_option_qot_right,
188 us_index_qot_right: data.us_index_qot_right,
189 us_otc_qot_right: data.us_otc_qot_right,
190 us_cme_future_qot_right: data.us_cme_future_qot_right,
191 us_cbot_future_qot_right: data.us_cbot_future_qot_right,
192 us_nymex_future_qot_right: data.us_nymex_future_qot_right,
193 us_comex_future_qot_right: data.us_comex_future_qot_right,
194 us_cboe_future_qot_right: data.us_cboe_future_qot_right,
195 sg_future_qot_right: data.sg_future_qot_right,
196 jp_future_qot_right: data.jp_future_qot_right,
197 sg_stock_qot_right: data.sg_stock_qot_right,
198 my_stock_qot_right: data.my_stock_qot_right,
199 jp_stock_qot_right: data.jp_stock_qot_right,
200 cc_qot_right: data.cc_qot_right,
201 event_contract_qot_right: data.event_contract_qot_right,
202 }
203 }
204}
205
206#[derive(Debug, Clone, Copy, PartialEq, Eq)]
207pub(in crate::qot_right) struct QotRightReconnectSnapshot {
208 hk_qot_right: i32,
209 hk_option_qot_right: i32,
210 hk_future_qot_right: i32,
211 us_qot_right: i32,
212 us_own_qot_right: i32,
213 us_option_qot_right: i32,
214 us_cme_future_qot_right: i32,
215 us_cbot_future_qot_right: i32,
216 us_nymex_future_qot_right: i32,
217 us_comex_future_qot_right: i32,
218 us_cboe_future_qot_right: i32,
219 sh_qot_right: i32,
220 sz_qot_right: i32,
221 us_index_qot_right: i32,
222 us_otc_qot_right: i32,
223 sg_future_qot_right: i32,
224 jp_future_qot_right: i32,
225 sg_stock_qot_right: i32,
226 jp_stock_qot_right: i32,
227}
228
229impl From<&QotRightData> for QotRightReconnectSnapshot {
230 fn from(data: &QotRightData) -> Self {
231 Self {
232 hk_qot_right: data.hk_qot_right,
233 hk_option_qot_right: data.hk_option_qot_right,
234 hk_future_qot_right: data.hk_future_qot_right,
235 us_qot_right: data.us_qot_right,
236 us_own_qot_right: data.us_own_qot_right,
237 us_option_qot_right: data.us_option_qot_right,
238 us_cme_future_qot_right: data.us_cme_future_qot_right,
239 us_cbot_future_qot_right: data.us_cbot_future_qot_right,
240 us_nymex_future_qot_right: data.us_nymex_future_qot_right,
241 us_comex_future_qot_right: data.us_comex_future_qot_right,
242 us_cboe_future_qot_right: data.us_cboe_future_qot_right,
243 sh_qot_right: data.sh_qot_right,
244 sz_qot_right: data.sz_qot_right,
245 us_index_qot_right: data.us_index_qot_right,
246 us_otc_qot_right: data.us_otc_qot_right,
247 sg_future_qot_right: data.sg_future_qot_right,
248 jp_future_qot_right: data.jp_future_qot_right,
249 sg_stock_qot_right: data.sg_stock_qot_right,
250 jp_stock_qot_right: data.jp_stock_qot_right,
251 }
252 }
253}
254
255impl QotRightReconnectSnapshot {
256 pub(in crate::qot_right) fn changed_quote_types(self, after: &QotRightData) -> Vec<i32> {
257 let mut changed = Vec::new();
258 push_if_changed(&mut changed, 1, self.hk_qot_right, after.hk_qot_right);
259 push_if_changed(
260 &mut changed,
261 5,
262 self.hk_option_qot_right,
263 after.hk_option_qot_right,
264 );
265 push_if_changed(
266 &mut changed,
267 4,
268 self.hk_future_qot_right,
269 after.hk_future_qot_right,
270 );
271 if self.us_qot_right != after.us_qot_right
272 || self.us_own_qot_right != after.us_own_qot_right
273 {
274 changed.push(17);
275 }
276 push_if_changed(
277 &mut changed,
278 11,
279 self.us_option_qot_right,
280 after.us_option_qot_right,
281 );
282 push_if_changed(
283 &mut changed,
284 30,
285 self.us_cme_future_qot_right,
286 after.us_cme_future_qot_right,
287 );
288 push_if_changed(
289 &mut changed,
290 31,
291 self.us_cbot_future_qot_right,
292 after.us_cbot_future_qot_right,
293 );
294 push_if_changed(
295 &mut changed,
296 32,
297 self.us_nymex_future_qot_right,
298 after.us_nymex_future_qot_right,
299 );
300 push_if_changed(
301 &mut changed,
302 33,
303 self.us_comex_future_qot_right,
304 after.us_comex_future_qot_right,
305 );
306 push_if_changed(
307 &mut changed,
308 16,
309 self.us_cboe_future_qot_right,
310 after.us_cboe_future_qot_right,
311 );
312 if self.sh_qot_right != after.sh_qot_right || self.sz_qot_right != after.sz_qot_right {
313 changed.extend([40, 41]);
314 }
315 push_if_changed(
316 &mut changed,
317 38,
318 self.us_index_qot_right,
319 after.us_index_qot_right,
320 );
321 push_if_changed(
322 &mut changed,
323 37,
324 self.us_otc_qot_right,
325 after.us_otc_qot_right,
326 );
327 push_if_changed(
328 &mut changed,
329 36,
330 self.sg_future_qot_right,
331 after.sg_future_qot_right,
332 );
333 push_if_changed(
334 &mut changed,
335 39,
336 self.jp_future_qot_right,
337 after.jp_future_qot_right,
338 );
339 push_if_changed(
340 &mut changed,
341 20,
342 self.sg_stock_qot_right,
343 after.sg_stock_qot_right,
344 );
345 push_if_changed(
346 &mut changed,
347 29,
348 self.jp_stock_qot_right,
349 after.jp_stock_qot_right,
350 );
351 changed
352 }
353}
354
355fn push_if_changed(changed: &mut Vec<i32>, quote_type: i32, before: i32, after: i32) {
356 if before != after {
357 changed.push(quote_type);
358 }
359}