Skip to main content

futu_core/
qot_subscription_options.rs

1pub const SESSION_NONE: i32 = 0;
2pub const SESSION_RTH: i32 = 1;
3pub const SESSION_ETH: i32 = 2;
4pub const SESSION_ALL: i32 = 3;
5pub const SESSION_OVERNIGHT: i32 = 4;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct SubscribeOptionsPlan {
9    pub requested_session: i32,
10    pub backend_session: i32,
11    pub extended_time: bool,
12    pub orderbook_detail: bool,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum SubscribePlanError {
17    OvernightSessionUnsupported,
18}
19
20/// Error text for `Session_OVERNIGHT` rejection in `Qot_Sub`.
21///
22/// C++ `APIServer_Qot_Sub.cpp:194-200` rejects `Session_OVERNIGHT` before
23/// forwarding to backend.
24#[must_use]
25pub fn subscribe_overnight_session_unsupported_message() -> &'static str {
26    "Subscribe: session=4 (Session_OVERNIGHT) is rejected because the backend \
27     does not accept a standalone OVERNIGHT subscription. Use session=2 (ETH) \
28     or 3 (ALL) for 海外夜盘."
29}
30
31impl SubscribeOptionsPlan {
32    /// Normalize Qot_Sub option fields.
33    ///
34    /// C++ `APIServer_Qot_Sub.cpp:194-200` rejects `Session_OVERNIGHT`.
35    /// C++ `ToSession(bExtendedTime, Session_NONE)` maps omitted session to
36    /// ETH when `extended_time=true`, otherwise RTH.
37    pub fn from_raw(
38        requested_session: Option<i32>,
39        extended_time: Option<bool>,
40        orderbook_detail: Option<bool>,
41    ) -> Result<Self, SubscribePlanError> {
42        let requested_session = requested_session.unwrap_or(SESSION_NONE);
43        if requested_session == SESSION_OVERNIGHT {
44            return Err(SubscribePlanError::OvernightSessionUnsupported);
45        }
46
47        let extended_time = extended_time.unwrap_or(false);
48        let backend_session = if requested_session == SESSION_NONE {
49            if extended_time {
50                SESSION_ETH
51            } else {
52                SESSION_RTH
53            }
54        } else {
55            requested_session
56        };
57
58        Ok(Self {
59            requested_session,
60            backend_session,
61            extended_time,
62            orderbook_detail: orderbook_detail.unwrap_or(false),
63        })
64    }
65}