1use futu_core::error::{FutuError, Result};
2use futu_core::proto_id;
3use futu_net::client::FutuClient;
4
5use crate::types::{Security, SubType};
6
7pub async fn subscribe(
12 client: &FutuClient,
13 securities: &[Security],
14 sub_types: &[SubType],
15 is_reg_push: bool,
16 is_first_push: bool,
17) -> Result<()> {
18 let req = futu_proto::qot_sub::Request {
19 c2s: futu_proto::qot_sub::C2s {
20 security_list: securities.iter().map(|s| s.to_proto()).collect(),
21 sub_type_list: sub_types.iter().map(|t| *t as i32).collect(),
22 is_sub_or_un_sub: true,
23 is_reg_or_un_reg_push: Some(is_reg_push),
24 reg_push_rehab_type_list: vec![],
25 is_first_push: Some(is_first_push),
26 is_unsub_all: None,
27 is_sub_order_book_detail: None,
28 extended_time: None,
29 session: None,
30 header: None,
31 },
32 };
33
34 let body = prost::Message::encode_to_vec(&req);
35 let resp_frame = client.request(proto_id::QOT_SUB, body).await?;
36
37 let resp: futu_proto::qot_sub::Response =
38 prost::Message::decode(resp_frame.body.as_ref()).map_err(FutuError::Proto)?;
39
40 check_ret_type(resp.ret_type, resp.ret_msg)
41}
42
43pub async fn unsubscribe(
45 client: &FutuClient,
46 securities: &[Security],
47 sub_types: &[SubType],
48) -> Result<()> {
49 let req = futu_proto::qot_sub::Request {
50 c2s: futu_proto::qot_sub::C2s {
51 security_list: securities.iter().map(|s| s.to_proto()).collect(),
52 sub_type_list: sub_types.iter().map(|t| *t as i32).collect(),
53 is_sub_or_un_sub: false,
54 is_reg_or_un_reg_push: Some(true),
55 reg_push_rehab_type_list: vec![],
56 is_first_push: None,
57 is_unsub_all: None,
58 is_sub_order_book_detail: None,
59 extended_time: None,
60 session: None,
61 header: None,
62 },
63 };
64
65 let body = prost::Message::encode_to_vec(&req);
66 let resp_frame = client.request(proto_id::QOT_SUB, body).await?;
67
68 let resp: futu_proto::qot_sub::Response =
69 prost::Message::decode(resp_frame.body.as_ref()).map_err(FutuError::Proto)?;
70
71 check_ret_type(resp.ret_type, resp.ret_msg)
72}
73
74fn check_ret_type(ret_type: i32, ret_msg: Option<String>) -> Result<()> {
75 if ret_type != 0 {
76 return Err(FutuError::ServerError {
77 ret_type,
78 msg: ret_msg.unwrap_or_default(),
79 });
80 }
81 Ok(())
82}