1use super::{u16_from_le_bytes, Result, Tdx};
2
3pub type Heartbeat = SecurityCount;
5
6#[derive(Debug)]
9pub struct SecurityCount {
10 send: Box<[u8]>,
11 market: u16,
13 count: u16,
15}
16
17impl SecurityCount {
18 pub fn new(market: u16) -> Self {
20 let mut send = [0; Self::LEN];
21 send.copy_from_slice(Self::SEND);
22 if market != 0 {
23 send[12..14].copy_from_slice(&market.to_le_bytes());
24 }
25 Self {
26 send: send.into(),
27 market,
28 count: 0,
29 }
30 }
31
32 pub fn market(&mut self, market: u16) {
33 self.market = market;
34 self.send[12..14].copy_from_slice(&market.to_le_bytes());
35 }
36}
37
38impl Tdx for SecurityCount {
39 type Item = u16;
40
41 const SEND: &'static [u8] = &[
43 0x0c, 0x0c, 0x18, 0x6c, 0x00, 0x01, 0x08, 0x00, 0x08, 0x00, 0x4e, 0x04, 0x00, 0x00, 0x75,
44 0xc7, 0x33, 0x01,
45 ];
46 const TAG: &'static str = "heartbeat";
47
48 fn send(&mut self) -> &[u8] {
49 &self.send
50 }
51
52 fn parse(&mut self, response: Vec<u8>) {
53 self.count = u16_from_le_bytes(&response, 0);
54 }
55
56 fn result(&self) -> &Self::Item {
57 &self.count
58 }
59}
60
61#[derive(Debug, Clone)]
68pub struct SecurityList {
69 pub send: Box<[u8]>,
70 pub market: u16,
71 pub start: u16,
72 pub count: usize,
74 pub response: Vec<u8>,
75 pub data: Box<[SecurityListData]>,
76}
77
78impl Default for SecurityList {
79 fn default() -> Self {
80 Self {
81 send: {
82 let mut arr = [0; Self::LEN];
83 arr.copy_from_slice(Self::SEND);
84 arr.into()
85 },
86 market: 0,
87 start: 1,
88 count: 0,
89 response: Vec::new(),
90 data: [].into(),
91 }
92 }
93}
94
95impl SecurityList {
96 pub fn new(market: u16, start: u16) -> Self {
101 Self {
102 send: {
103 let mut arr = [0; Self::LEN];
104 arr.copy_from_slice(Self::SEND);
105 arr[12..14].copy_from_slice(&market.to_le_bytes());
106 arr[14..16].copy_from_slice(&start.to_le_bytes());
107 arr.into()
108 },
109 market,
110 start,
111 count: 0,
112 response: Vec::new(),
113 data: [].into(),
114 }
115 }
116}
117
118impl Tdx for SecurityList {
119 type Item = [SecurityListData];
120
121 const SEND: &'static [u8] = &[
123 0x0c, 0x01, 0x18, 0x64, 0x01, 0x01, 0x06, 0x00, 0x06, 0x00, 0x50, 0x04, 0x00, 0x00, 0x00,
124 0x00,
125 ];
126 const TAG: &'static str = "股票、指数列表";
127
128 fn send(&mut self) -> &[u8] {
129 &self.send
130 }
131
132 fn parse(&mut self, v: Vec<u8>) {
134 self.count = u16_from_le_bytes(&v, 0) as usize;
135 self.data = v[2..]
136 .chunks_exact(29)
137 .map(SecurityListData::parse)
138 .collect();
139 debug_assert_eq!(self.count, self.data.len());
140 self.response = v;
141 }
142
143 fn result(&self) -> &Self::Item {
144 &self.data
145 }
146}
147
148#[test]
149fn connection() -> Result<()> {
150 SecurityList::default().recv_parsed(&mut crate::tcp::Tcp::new()?)?;
151 Ok(())
152}
153
154#[derive(Debug, Clone, serde::Serialize)]
159pub struct SecurityListData {
160 pub code: String,
161 pub name: String,
163}
164
165impl SecurityListData {
166 pub fn parse(bytes: &[u8]) -> Self {
179 let code = unsafe { std::str::from_utf8_unchecked(&bytes[0..6]) }.into();
180 let (name, encoding_used, had_errors) = encoding_rs::GBK.decode(&bytes[8..16]);
181 debug_assert_eq!(encoding_used, encoding_rs::GBK);
182 debug_assert!(!had_errors);
183 Self {
185 code,
186 name: name.into(),
187 }
188 }
189}
190
191pub const PACK1: &[u8] = &[
192 0x0c, 0x02, 0x18, 0x93, 0x00, 0x01, 0x03, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x01,
193];
194pub const PACK2: &[u8] = &[
195 0x0c, 0x02, 0x18, 0x94, 0x00, 0x01, 0x03, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x02,
196];
197pub const PACK3: &[u8] = &[
198 0x0c, 0x03, 0x18, 0x99, 0x00, 0x01, 0x20, 0x00, 0x20, 0x00, 0xdb, 0x0f, 0xd5, 0xd0, 0xc9, 0xcc,
199 0xd6, 0xa4, 0xa8, 0xaf, 0x00, 0x00, 0x00, 0x8f, 0xc2, 0x25, 0x40, 0x13, 0x00, 0x00, 0xd5, 0x00,
200 0xc9, 0xcc, 0xbd, 0xf0, 0xd7, 0xea, 0x00, 0x00, 0x00, 0x02,
201];
202pub const RECV_SIZE: usize = 16;
203
204pub fn send_packs(tcp: &mut super::Tcp, decompress: bool) -> Result<()> {
205 use super::{send_recv, send_recv_decompress};
206 if decompress {
207 send_recv_decompress(tcp, PACK1, "PACK1")?;
208 send_recv_decompress(tcp, PACK2, "PACK2")?;
209 send_recv_decompress(tcp, PACK3, "PACK3")?;
210 } else {
211 send_recv(tcp, PACK1, "PACK1")?;
212 send_recv(tcp, PACK2, "PACK2")?;
213 send_recv(tcp, PACK3, "PACK3")?;
214 }
215 Ok(())
216}