1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use super::{
    fixed_header::{FixedHeader, FixedHeaderBuilder},
    Decoder, Encoder,
};
use crate::error::ProtoError;
use crate::v4::{decoder, GeneralVariableHeader, VariableDecoder};
use bytes::{Buf, BufMut, Bytes, BytesMut};

///
///
/// | Bit   | 7   | 6   | 5   | 4   | 3   | 2   | 1   | 0   |
/// | ----- | --- | --- | --- | --- | --- | --- | --- | --- |
/// | byte1 | 0   | 1   | 0   | 1   | 0   | 0   | 0   | 0   |
/// | byte2 | 0   | 0   | 0   | 0   | 0   | 0   | 1   | 0   |
/// | byte3 | 报   | 文   | 标  | 识   | 符  | M   | S   | B   |
/// | byte4 | 报   | 文   | 标  | 识   | 符  | L   | S   | B   |

#[derive(Debug)]
pub struct PubRec {
    fixed_header: FixedHeader,
    variable_header: GeneralVariableHeader,
}

impl PubRec {
    pub fn new(message_id: usize) -> Self {
        Self {
            fixed_header: FixedHeaderBuilder::new().pub_rel().build().unwrap(),
            variable_header: GeneralVariableHeader::new(message_id),
        }
    }

    pub fn message_id(&self) -> usize {
        self.variable_header.message_id
    }
}

//////////////////////////////////////////////////////
/// 为PubComp实现Encoder trait
//////////////////////////////////////////////////////
impl Encoder for PubRec {
    fn encode(&self, buffer: &mut BytesMut) -> Result<usize, ProtoError> {
        let fixed_header = FixedHeaderBuilder::new().pub_rec().build();
        match fixed_header {
            Ok(fixed_header) => {
                if let Ok(_resp) = fixed_header.encode(buffer) {
                    buffer.put_u16(self.variable_header.message_id() as u16);
                    return Ok(4);
                }
                Err(ProtoError::EncodeVariableHeaderError)
            }
            Err(err) => Err(err),
        }
    }
}

//////////////////////////////////////////////////////
/// 为PubComp实现Decoder trait
//////////////////////////////////////////////////////
impl Decoder for PubRec {
    type Item = PubRec;
    type Error = ProtoError;
    fn decode(mut bytes: Bytes) -> Result<Self::Item, ProtoError> {
        let resp = decoder::read_fixed_header(&mut bytes);
        match resp {
            Ok(fixed_header) => {
                let qos = fixed_header.qos();
                let variable_header_index = fixed_header.len();
                bytes.advance(variable_header_index);
                // 读取variable_header
                let resp = GeneralVariableHeader::decode(&mut bytes, qos);
                match resp {
                    Ok(variable_header) => Ok(PubRec {
                        fixed_header,
                        variable_header,
                    }),
                    Err(e) => return Err(e),
                }
            }
            Err(e) => Err(e),
        }
    }
}