Skip to main content

futu_backend/
quote_push.rs

1//! Presence-safe CMD6212 quote-push decoder.
2
3use futu_core::error::{FutuError, Result};
4use prost::Message;
5
6use crate::proto_internal::ft_cmd_stock_quote_sub;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct DecodedQuotePush {
10    pub securities: Vec<DecodedQuotePushSecurity>,
11}
12
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct DecodedQuotePushSecurity {
15    pub stock_id: Option<u64>,
16    pub bits: Vec<DecodedQuotePushBit>,
17    pub broker_id: Option<i32>,
18}
19
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct DecodedQuotePushBit {
22    pub bit: Option<u32>,
23    pub data: Option<Vec<u8>>,
24    pub prob: Option<i64>,
25}
26
27pub fn decode_quote_push(body: &[u8]) -> Result<DecodedQuotePush> {
28    let wire = ft_cmd_stock_quote_sub::QuotePush::decode(body)
29        .map_err(|error| FutuError::Codec(format!("CMD6212 QuotePush decode: {error}")))?;
30
31    Ok(DecodedQuotePush {
32        securities: wire
33            .security_qta_list
34            .into_iter()
35            .map(|security| DecodedQuotePushSecurity {
36                stock_id: security.security_id,
37                bits: security
38                    .bit_qta_list
39                    .into_iter()
40                    .map(|bit| DecodedQuotePushBit {
41                        bit: bit.bit,
42                        data: bit.data,
43                        prob: bit.prob,
44                    })
45                    .collect(),
46                broker_id: security.broker_id,
47            })
48            .collect(),
49    })
50}