1use bytes::Bytes;
2
3use crate::header::{FutuHeader, ProtoFmtType};
4
5#[derive(Debug, Clone)]
10pub struct FutuFrame {
11 pub header: FutuHeader,
12 pub body: Bytes,
13}
14
15impl FutuFrame {
16 #[must_use]
18 pub fn body_sha1(body: &[u8]) -> [u8; 20] {
19 use sha1::{Digest, Sha1};
20
21 let mut hasher = Sha1::new();
22 hasher.update(body);
23 let sha1_result = hasher.finalize();
24 let mut body_sha1 = [0u8; 20];
25 body_sha1.copy_from_slice(&sha1_result);
26 body_sha1
27 }
28
29 pub fn new(proto_id: u32, serial_no: u32, body: Bytes) -> Self {
31 let body_sha1 = Self::body_sha1(&body);
32 Self::with_sha1(proto_id, serial_no, body, body_sha1)
33 }
34
35 pub fn with_sha1(proto_id: u32, serial_no: u32, body: Bytes, body_sha1: [u8; 20]) -> Self {
41 Self {
42 header: FutuHeader {
43 proto_id,
44 proto_fmt_type: ProtoFmtType::Protobuf,
45 proto_ver: 0,
46 serial_no,
47 body_len: body.len() as u32,
48 body_sha1,
49 },
50 body,
51 }
52 }
53
54 #[must_use]
58 pub fn verify_sha1(&self) -> bool {
59 Self::body_sha1(&self.body) == self.header.body_sha1
60 }
61}
62
63#[cfg(test)]
64mod tests;