Skip to main content

futu_backend/
command_runtime_qot.rs

1//! QOT command-family entrypoints for the shared backend command runtime.
2
3use super::*;
4use futu_command_spec::{market_event_command, qot_read_command};
5
6pub async fn execute_market_event(
7    backend: &BackendConn,
8    operation: MarketEventOperation,
9    body: Bytes,
10    reserved: [u8; 10],
11) -> FutuResult<CommandResponse> {
12    if operation == MarketEventOperation::Push {
13        return Err(FutuError::Codec(
14            "market-event CMD6301 is push-only and cannot be executed as a request".to_string(),
15        ));
16    }
17    let spec = market_event_command(operation);
18    if spec.runtime.channel != BackendChannelKind::Qot {
19        return Err(FutuError::Codec(format!(
20            "market-event command {} is bound to {:?}",
21            spec.runtime.name, spec.runtime.channel
22        )));
23    }
24    execute_qot_command(
25        backend,
26        CommandSpecId::MarketEvent(operation),
27        body,
28        reserved,
29    )
30    .await
31}
32
33pub async fn execute_qot_read(
34    backend: &BackendConn,
35    operation: QotReadOperation,
36    body: Bytes,
37) -> FutuResult<CommandResponse> {
38    execute_qot_read_with_reserved(backend, operation, body, [0_u8; 10]).await
39}
40
41pub async fn execute_qot_read_with_reserved(
42    backend: &BackendConn,
43    operation: QotReadOperation,
44    body: Bytes,
45    reserved: [u8; 10],
46) -> FutuResult<CommandResponse> {
47    let spec = qot_read_command(operation);
48    let runtime = login_runtime_with_transport(ChannelBoundBackendTransport::new(
49        backend,
50        spec.runtime.channel,
51    ));
52    let execution = runtime
53        .execute(
54            CommandExecutionContext::new(CommandSpecId::QotRead(operation), body)
55                .with_reserved(reserved),
56        )
57        .await
58        .map_err(|error| FutuError::Codec(format!("qot-read command spec error: {error}")))?;
59    let report = &execution.report;
60    tracing::trace!(
61        command = report.command_name,
62        cmd_id = report.cmd_id,
63        channel = ?report.channel,
64        outcome = ?report.outcome,
65        response_body_len = report.response_body_len,
66        "command runtime executed QOT read"
67    );
68    execution.into_response()
69}
70
71pub async fn execute_qot_subscription_set(
72    backend: &BackendConn,
73    body: Bytes,
74    reserved: [u8; 10],
75) -> FutuResult<CommandResponse> {
76    execute_qot_command(backend, CommandSpecId::QotSubscriptionSet, body, reserved).await
77}
78
79pub(crate) async fn execute_qot_subscription_set_with_dispatch(
80    backend: &BackendConn,
81    body: Bytes,
82    reserved: [u8; 10],
83    context: SubscriptionDispatchContext,
84) -> FutuResult<CommandResponse> {
85    let runtime = login_runtime_with_transport(
86        ChannelBoundBackendTransport::new(backend, BackendChannelKind::Qot)
87            .with_subscription_dispatch(context),
88    );
89    let execution = runtime
90        .execute(
91            CommandExecutionContext::new(CommandSpecId::QotSubscriptionSet, body)
92                .with_reserved(reserved),
93        )
94        .await
95        .map_err(|error| FutuError::Codec(format!("qot command spec error: {error}")))?;
96    execution.into_response()
97}