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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use crate::protocol::len_len;
use crate::protocol::packet::write_remaining_length;
use bytes::{BufMut, Bytes, BytesMut};

/// Subscription packet
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Subscribe {
    V4 {
        packet_id: u16,
        payload: Bytes,
    },
    V5 {
        packet_id: u16,
        properties: Bytes,
        filters: Bytes,
    },
}

impl Subscribe {
    pub fn set_packet_id(&mut self, new_packet_id: u16) {
        match self {
            Subscribe::V4 { packet_id, .. } => *packet_id = new_packet_id,
            Subscribe::V5 { packet_id, .. } => *packet_id = new_packet_id,
        }
    }
    pub fn packet_id(&self) -> u16 {
        match self {
            Subscribe::V4 { packet_id, .. } => *packet_id,
            Subscribe::V5 { packet_id, .. } => *packet_id,
        }
    }
    pub fn write(&self, buffer: &mut BytesMut) -> usize {
        match self {
            Self::V4 {
                packet_id,
                payload: filters,
            } => {
                // write packet type
                buffer.put_u8(0x82);
                let remaining_len = filters.len() + 2;
                let remaining_len_bytes = write_remaining_length(buffer, remaining_len);
                // write packet id
                buffer.put_u16(*packet_id);
                buffer.extend_from_slice(filters.as_ref());
                1 + remaining_len_bytes + remaining_len
            }
            Self::V5 {
                packet_id,
                properties,
                filters,
            } => {
                buffer.put_u8(0x82);
                let properties_len = len_len(properties.len());
                let remaining_len = 2 + properties_len + properties.len() + filters.len();
                let remaining_len_bytes = write_remaining_length(buffer, remaining_len);

                buffer.put_u16(*packet_id);
                let _properties_len_bytes = write_remaining_length(buffer, properties.len());
                if properties.len() > 0 {
                    buffer.extend_from_slice(properties.as_ref())
                }
                buffer.extend_from_slice(filters.as_ref());
                1 + remaining_len + remaining_len_bytes
            }
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Filter {
    pub path: String,
    pub options: SubscribeOptions,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SubscribeOptions(u8);

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RetainForwardRule {
    OnEverySubscribe,
    OnNewSubscribe,
    Never,
}

impl RetainForwardRule {
    pub fn merge_to_u8(&self, val: &mut u8) {
        match self {
            RetainForwardRule::OnEverySubscribe => {}
            RetainForwardRule::OnNewSubscribe => *val |= 1 << 4,
            RetainForwardRule::Never => *val |= 2 << 4,
        }
    }
}

impl Default for RetainForwardRule {
    fn default() -> Self {
        Self::OnEverySubscribe
    }
}
//
// #[derive(Debug, Clone, PartialEq, Eq)]
// pub struct SubscribeProperties {

// }