worterbuch_codec/encode/
server.rs

1use super::{
2    get_key_length, get_metadata_length, get_num_key_val_pairs, get_request_pattern_length,
3    get_value_length,
4};
5use crate::{
6    error::EncodeResult, prepend_buffer_length, Ack, Err, Handshake, KeyValuePair, PState, State,
7    ACK, ERR, HSHK, PSTA, STA,
8};
9
10pub fn encode_pstate_message(msg: &PState) -> EncodeResult<Vec<u8>> {
11    let request_pattern_length = get_request_pattern_length(&msg.request_pattern)?;
12    let num_key_val_pairs = get_num_key_val_pairs(&msg.key_value_pairs)?;
13
14    let mut buf = vec![PSTA];
15
16    buf.extend(msg.transaction_id.to_be_bytes());
17    buf.extend(request_pattern_length.to_be_bytes());
18    buf.extend(num_key_val_pairs.to_be_bytes());
19
20    for KeyValuePair { key, value } in &msg.key_value_pairs {
21        let key_length = get_key_length(&key)?;
22        let value_length = get_value_length(&value)?;
23        buf.extend(key_length.to_be_bytes());
24        buf.extend(value_length.to_be_bytes());
25    }
26
27    buf.extend(msg.request_pattern.as_bytes());
28
29    for KeyValuePair { key, value } in &msg.key_value_pairs {
30        buf.extend(key.as_bytes());
31        buf.extend(value.as_bytes());
32    }
33
34    prepend_buffer_length(buf)
35}
36
37pub fn encode_ack_message(msg: &Ack) -> EncodeResult<Vec<u8>> {
38    let mut buf = vec![ACK];
39
40    buf.extend(msg.transaction_id.to_be_bytes());
41
42    prepend_buffer_length(buf)
43}
44
45pub fn encode_state_message(msg: &State) -> EncodeResult<Vec<u8>> {
46    let KeyValuePair { key, value } = &msg.key_value;
47    let key_length = get_key_length(key)?;
48    let value_length = get_value_length(value)?;
49
50    let mut buf = vec![STA];
51
52    buf.extend(msg.transaction_id.to_be_bytes());
53    buf.extend(key_length.to_be_bytes());
54    buf.extend(value_length.to_be_bytes());
55
56    buf.extend(key.as_bytes());
57    buf.extend(value.as_bytes());
58
59    prepend_buffer_length(buf)
60}
61
62pub fn encode_err_message(msg: &Err) -> EncodeResult<Vec<u8>> {
63    let metadata_length = get_metadata_length(&msg.metadata)?;
64
65    let mut buf = vec![ERR];
66
67    buf.extend(msg.transaction_id.to_be_bytes());
68    buf.push(msg.error_code);
69    buf.extend(metadata_length.to_be_bytes());
70    buf.extend(msg.metadata.as_bytes());
71
72    prepend_buffer_length(buf)
73}
74
75pub fn encode_handshake_message(msg: &Handshake) -> EncodeResult<Vec<u8>> {
76    let mut buf = vec![HSHK];
77
78    buf.extend(msg.protocol_version.major.to_be_bytes());
79    buf.extend(msg.protocol_version.minor.to_be_bytes());
80
81    buf.push(msg.separator as u8);
82    buf.push(msg.wildcard as u8);
83    buf.push(msg.multi_wildcard as u8);
84
85    prepend_buffer_length(buf)
86}
87
88#[cfg(test)]
89mod test {
90    use super::*;
91    use crate::{Ack, Err, Handshake, PState, ProtocolVersion, State, ACK, ERR, HSHK, PSTA, STA};
92
93    #[test]
94    fn handshake_message_is_encoded_correctly() {
95        let msg = Handshake {
96            protocol_version: ProtocolVersion { major: 1, minor: 0 },
97            separator: '/',
98            wildcard: '?',
99            multi_wildcard: '#',
100        };
101
102        let data = [
103            0b00000000, 0b00000000, 0b00000000, 0b00001000, // message length
104            HSHK, 0b00000000, 0b00000001, 0b00000000, 0b00000000, b'/', b'?', b'#',
105        ];
106
107        assert_eq!(data.to_vec(), encode_handshake_message(&msg).unwrap());
108    }
109
110    #[test]
111    fn pstate_message_is_encoded_correctly() {
112        let msg = PState {
113            transaction_id: u64::MAX,
114            request_pattern: "who/let/the/?/#".to_owned(),
115            key_value_pairs: vec![
116                (
117                    "who/let/the/chicken/cross/the/road".to_owned(),
118                    "yeah, that was me, I guess".to_owned(),
119                )
120                    .into(),
121                (
122                    "who/let/the/dogs/out".to_owned(),
123                    "Who? Who? Who? Who? Who?".to_owned(),
124                )
125                    .into(),
126            ],
127        };
128
129        let data = [
130            0b00000000, 0b00000000, 0b00000000, 0b10010010, // message length
131            PSTA, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111,
132            0b11111111, 0b11111111, 0b00000000, 0b00001111, 0b00000000, 0b00000000, 0b00000000,
133            0b00000010, 0b00000000, 0b00100010, 0b00000000, 0b00000000, 0b00000000, 0b00011010,
134            0b00000000, 0b00010100, 0b00000000, 0b00000000, 0b00000000, 0b00011000, b'w', b'h',
135            b'o', b'/', b'l', b'e', b't', b'/', b't', b'h', b'e', b'/', b'?', b'/', b'#', b'w',
136            b'h', b'o', b'/', b'l', b'e', b't', b'/', b't', b'h', b'e', b'/', b'c', b'h', b'i',
137            b'c', b'k', b'e', b'n', b'/', b'c', b'r', b'o', b's', b's', b'/', b't', b'h', b'e',
138            b'/', b'r', b'o', b'a', b'd', b'y', b'e', b'a', b'h', b',', b' ', b't', b'h', b'a',
139            b't', b' ', b'w', b'a', b's', b' ', b'm', b'e', b',', b' ', b'I', b' ', b'g', b'u',
140            b'e', b's', b's', b'w', b'h', b'o', b'/', b'l', b'e', b't', b'/', b't', b'h', b'e',
141            b'/', b'd', b'o', b'g', b's', b'/', b'o', b'u', b't', b'W', b'h', b'o', b'?', b' ',
142            b'W', b'h', b'o', b'?', b' ', b'W', b'h', b'o', b'?', b' ', b'W', b'h', b'o', b'?',
143            b' ', b'W', b'h', b'o', b'?',
144        ];
145
146        assert_eq!(data.to_vec(), encode_pstate_message(&msg).unwrap());
147    }
148
149    #[test]
150    fn ack_message_is_encoded_correctly() {
151        let msg = Ack { transaction_id: 42 };
152
153        let data = [
154            0b00000000, 0b00000000, 0b00000000, 0b00001001, // message length
155            ACK, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
156            0b00000000, 0b00101010,
157        ];
158
159        assert_eq!(data.to_vec(), encode_ack_message(&msg).unwrap());
160    }
161
162    #[test]
163    fn state_message_is_encoded_correctly() {
164        let msg = State {
165            transaction_id: 42,
166            key_value: ("1/2/3", "4").into(),
167        };
168
169        let data = [
170            0b00000000, 0b00000000, 0b00000000, 0b00010101, // message length
171            STA, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
172            0b00000000, 0b00101010, 0b00000000, 0b00000101, 0b00000000, 0b00000000, 0b00000000,
173            0b00000001, b'1', b'/', b'2', b'/', b'3', b'4',
174        ];
175
176        assert_eq!(data.to_vec(), encode_state_message(&msg).unwrap());
177    }
178
179    #[test]
180    fn empty_state_message_is_encoded_correctly() {
181        let msg = State {
182            transaction_id: 42,
183            key_value: ("1/2/3", "").into(),
184        };
185
186        let data = [
187            0b00000000, 0b00000000, 0b00000000, 0b00010100, // message length
188            STA, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
189            0b00000000, 0b00101010, 0b00000000, 0b00000101, 0b00000000, 0b00000000, 0b00000000,
190            0b00000000, b'1', b'/', b'2', b'/', b'3',
191        ];
192
193        assert_eq!(data.to_vec(), encode_state_message(&msg).unwrap());
194    }
195
196    #[test]
197    fn err_message_is_encoded_correctly() {
198        let msg = Err {
199            transaction_id: 42,
200            error_code: 5,
201            metadata: "THIS IS METAAA!!!".to_owned(),
202        };
203
204        let data = [
205            0b00000000, 0b00000000, 0b00000000, 0b00011111, // message length
206            ERR, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
207            0b00000000, 0b00101010, 0b00000101, 0b00000000, 0b00000000, 0b00000000, 0b00010001,
208            b'T', b'H', b'I', b'S', b' ', b'I', b'S', b' ', b'M', b'E', b'T', b'A', b'A', b'A',
209            b'!', b'!', b'!',
210        ];
211
212        assert_eq!(data.to_vec(), encode_err_message(&msg).unwrap());
213    }
214}