1use super::*;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct QotRightData {
10 pub hk_own_qot_right: i32,
12 pub hk_qot_right: i32,
13 pub us_own_qot_right: i32,
15 pub us_qot_right: i32,
16 pub api_us_qot_right: i32,
18 pub has_us_utp: bool,
20 pub has_us_overnight: bool,
22 pub sh_qot_right: i32,
23 pub sz_qot_right: i32,
24 pub hk_option_qot_right: i32,
25 pub hk_future_qot_right: i32,
26 pub has_us_option_qot_right: bool,
27 pub us_option_qot_right: i32,
28 pub us_index_qot_right: i32,
29 pub us_otc_qot_right: i32,
30 pub us_cme_future_qot_right: i32,
31 pub us_cbot_future_qot_right: i32,
32 pub us_nymex_future_qot_right: i32,
33 pub us_comex_future_qot_right: i32,
34 pub us_cboe_future_qot_right: i32,
35 pub sg_future_qot_right: i32,
36 pub jp_future_qot_right: i32,
37 pub sg_stock_qot_right: i32,
38 pub my_stock_qot_right: i32,
39 pub jp_stock_qot_right: i32,
40 pub cc_qot_right: i32,
41 pub has_digital_future_auth: bool,
43 pub cc_pt_orderbook_qot_right: i32,
44 pub event_contract_qot_right: i32,
45 pub event_contract_prohibited_category_ids: Vec<u32>,
46 pub us_lv2_arca_qot_right: bool,
47 pub us_lv2_nyse_qot_right: bool,
48 pub us_lv2_nasdaq_totalview_qot_right: bool,
49 pub sub_quota: i32,
50 pub history_kl_quota: i32,
51 pub hk_option_orderbook_depth: Option<u32>,
53 pub hk_future_orderbook_depth: Option<u32>,
54}
55
56impl Default for QotRightData {
57 fn default() -> Self {
58 const UNKNOWN: i32 = 0;
59 Self {
60 hk_own_qot_right: UNKNOWN,
61 hk_qot_right: UNKNOWN,
62 us_own_qot_right: UNKNOWN,
63 us_qot_right: UNKNOWN,
64 api_us_qot_right: UNKNOWN,
65 has_us_utp: false,
66 has_us_overnight: false,
67 sh_qot_right: UNKNOWN,
68 sz_qot_right: UNKNOWN,
69 hk_option_qot_right: UNKNOWN,
70 hk_future_qot_right: UNKNOWN,
71 has_us_option_qot_right: false,
74 us_option_qot_right: UNKNOWN,
75 us_index_qot_right: UNKNOWN,
76 us_otc_qot_right: UNKNOWN,
77 us_cme_future_qot_right: UNKNOWN,
78 us_cbot_future_qot_right: UNKNOWN,
79 us_nymex_future_qot_right: UNKNOWN,
80 us_comex_future_qot_right: UNKNOWN,
81 us_cboe_future_qot_right: UNKNOWN,
82 sg_future_qot_right: UNKNOWN,
83 jp_future_qot_right: UNKNOWN,
84 sg_stock_qot_right: UNKNOWN,
85 my_stock_qot_right: UNKNOWN,
86 jp_stock_qot_right: UNKNOWN,
87 cc_qot_right: UNKNOWN,
88 has_digital_future_auth: false,
89 cc_pt_orderbook_qot_right: UNKNOWN,
90 event_contract_qot_right: UNKNOWN,
91 event_contract_prohibited_category_ids: Vec::new(),
92 us_lv2_arca_qot_right: false,
93 us_lv2_nyse_qot_right: false,
94 us_lv2_nasdaq_totalview_qot_right: false,
95 sub_quota: QOT_API_QUOTA_DEFAULT,
96 history_kl_quota: QOT_API_QUOTA_DEFAULT,
97 hk_option_orderbook_depth: None,
98 hk_future_orderbook_depth: None,
99 }
100 }
101}
102
103#[derive(Debug, Clone)]
104pub struct QotRightRefreshReport {
105 pub changed: bool,
106 pub reconnect_quote_types: Vec<i32>,
107 pub has_set_qot_right_before: bool,
108 pub has_us_utp_changed: bool,
109 pub quota_data_changed: bool,
110 pub quota_projection_available: bool,
111 pub backend_generation: u64,
112 pub route_publication_epoch: u64,
113 pub request_is_highest: bool,
114 pub force_resubscribe: bool,
115 pub resubscribe_scope: futu_domain_qot_right::QotRightResubscribeScope,
116 pub deferred_reconnect_token: Option<QotRightReconnectToken>,
117 pub deferred_reconnect_blocked: bool,
118 pub fresh_at_ms: i64,
119 pub decoded_fields: Vec<&'static str>,
120 pub freshness_after: QotRightFreshness,
121 pub login_epoch: u64,
122}
123
124#[derive(Debug, Clone, PartialEq, Eq)]
125pub struct QotRightBackendApplyOutcome {
126 pub public_rights_changed: bool,
127 pub reconnect_quote_types: Vec<i32>,
128 pub has_set_qot_right_before: bool,
129 pub has_us_utp_changed: bool,
130 pub quota_data_changed: bool,
131 pub quota_projection_available: bool,
132}
133
134impl QotRightBackendApplyOutcome {
135 #[must_use]
136 pub fn cpp_reconnect_rights_changed(&self) -> bool {
137 !self.reconnect_quote_types.is_empty()
138 }
139}
140
141#[derive(Debug, Clone, Copy, PartialEq, Eq)]
142pub struct QotRightFullApplyFacts {
143 pub expected_generation: u64,
144 pub source_publication_epoch: Option<u64>,
148 pub is_highest: bool,
149 pub force_resub: bool,
150 pub pushed_notify_version: Option<u64>,
151}
152
153#[must_use]
154pub fn has_set_qot_right_like_cpp(data: &QotRightData) -> bool {
155 [
158 data.hk_own_qot_right,
159 data.hk_option_qot_right,
160 data.hk_qot_right,
161 data.us_qot_right,
162 data.us_own_qot_right,
163 data.sh_qot_right,
164 data.sz_qot_right,
165 data.hk_future_qot_right,
166 data.us_option_qot_right,
167 data.us_cme_future_qot_right,
168 data.us_cbot_future_qot_right,
169 data.us_nymex_future_qot_right,
170 data.us_comex_future_qot_right,
171 data.us_cboe_future_qot_right,
172 data.us_index_qot_right,
173 data.us_otc_qot_right,
174 data.sg_future_qot_right,
175 data.sg_stock_qot_right,
176 data.jp_future_qot_right,
177 data.my_stock_qot_right,
178 data.jp_stock_qot_right,
179 data.cc_qot_right,
180 data.event_contract_qot_right,
181 ]
182 .into_iter()
183 .any(|right| right != QOT_RIGHT_UNKNOWN)
184}
185
186#[derive(Debug, Clone)]
187pub struct QotRightStateMeta {
188 pub freshness: QotRightFreshness,
189 pub user_id: Option<u64>,
190 pub login_epoch: u64,
191 pub backend_generation: u64,
192 pub source_publication_epoch: Option<u64>,
193 pub last_refresh_at_ms: i64,
194 pub last_pushed_quote_change_notify: Option<PushedQuoteChangeNotify>,
195 pub last_pushed_quote_change_notify_version: u64,
196 pub reconnect_lifecycle: QotRightReconnectLifecycle,
197 pub next_reconnect_token: u64,
198 pub event_contract_category_preload_pending: bool,
202}
203
204impl Default for QotRightStateMeta {
205 fn default() -> Self {
206 Self {
207 freshness: QotRightFreshness::Unknown,
208 user_id: None,
209 login_epoch: 0,
210 backend_generation: 0,
211 source_publication_epoch: None,
212 last_refresh_at_ms: 0,
213 last_pushed_quote_change_notify: None,
214 last_pushed_quote_change_notify_version: 0,
215 reconnect_lifecycle: QotRightReconnectLifecycle::Idle,
216 next_reconnect_token: 1,
217 event_contract_category_preload_pending: false,
218 }
219 }
220}
221
222pub(super) fn now_ms() -> i64 {
223 use std::time::{SystemTime, UNIX_EPOCH};
224 SystemTime::now()
225 .duration_since(UNIX_EPOCH)
226 .map(|d| d.as_millis() as i64)
227 .unwrap_or(0)
228}
229
230pub(super) fn next_reconnect_token(meta: &mut QotRightStateMeta) -> QotRightReconnectToken {
231 let token = QotRightReconnectToken(meta.next_reconnect_token);
232 meta.next_reconnect_token = meta.next_reconnect_token.saturating_add(1);
233 token
234}