worterbuch_codec/encode/
client.rs

1use super::{
2    get_key_length, get_num_grave_goods, get_num_last_will, get_num_protocol_versions,
3    get_path_length, get_request_pattern_length, get_value_length,
4};
5use crate::{
6    error::EncodeResult, prepend_buffer_length, ClientMessage, Export, Get, HandshakeRequest,
7    Import, KeyValuePair, PGet, PSubscribe, ProtocolVersion, Set, Subscribe, Unsubscribe, EXP, GET,
8    HSHKR, IMP, PGET, PSUB, SET, SUB, USUB,
9};
10
11pub fn encode_message(msg: &ClientMessage) -> EncodeResult<Vec<u8>> {
12    match msg {
13        ClientMessage::HandshakeRequest(msg) => encode_handshake_request_message(msg),
14        ClientMessage::Get(msg) => encode_get_message(msg),
15        ClientMessage::PGet(msg) => encode_pget_message(msg),
16        ClientMessage::Set(msg) => encode_set_message(msg),
17        ClientMessage::Subscribe(msg) => encode_subscribe_message(msg),
18        ClientMessage::PSubscribe(msg) => encode_psubscribe_message(msg),
19        ClientMessage::Export(msg) => encode_export_message(msg),
20        ClientMessage::Import(msg) => encode_import_message(msg),
21        ClientMessage::Unsubscribe(msg) => encode_unsubscribe_message(msg),
22    }
23}
24
25pub fn encode_get_message(msg: &Get) -> EncodeResult<Vec<u8>> {
26    let key_length = get_key_length(&msg.key)?;
27
28    let mut buf = vec![GET];
29
30    buf.extend(msg.transaction_id.to_be_bytes());
31    buf.extend(key_length.to_be_bytes());
32    buf.extend(msg.key.as_bytes());
33
34    prepend_buffer_length(buf)
35}
36
37pub fn encode_pget_message(msg: &PGet) -> EncodeResult<Vec<u8>> {
38    let request_pattern_length = get_request_pattern_length(&msg.request_pattern)?;
39
40    let mut buf = vec![PGET];
41
42    buf.extend(msg.transaction_id.to_be_bytes());
43    buf.extend(request_pattern_length.to_be_bytes());
44    buf.extend(msg.request_pattern.as_bytes());
45
46    prepend_buffer_length(buf)
47}
48
49pub fn encode_set_message(msg: &Set) -> EncodeResult<Vec<u8>> {
50    let key_length = get_key_length(&msg.key)?;
51    let value_length = get_value_length(&msg.value)?;
52
53    let mut buf = vec![SET];
54
55    buf.extend(msg.transaction_id.to_be_bytes());
56    buf.extend(key_length.to_be_bytes());
57    buf.extend(value_length.to_be_bytes());
58    buf.extend(msg.key.as_bytes());
59    buf.extend(msg.value.as_bytes());
60
61    prepend_buffer_length(buf)
62}
63
64pub fn encode_subscribe_message(msg: &Subscribe) -> EncodeResult<Vec<u8>> {
65    let key_length = get_key_length(&msg.key)?;
66
67    let mut buf = vec![SUB];
68
69    buf.extend(msg.transaction_id.to_be_bytes());
70    buf.extend(key_length.to_be_bytes());
71    buf.extend(msg.key.as_bytes());
72    buf.push(if msg.unique { 1 } else { 0 });
73
74    prepend_buffer_length(buf)
75}
76
77pub fn encode_psubscribe_message(msg: &PSubscribe) -> EncodeResult<Vec<u8>> {
78    let request_pattern_length = get_request_pattern_length(&msg.request_pattern)?;
79
80    let mut buf = vec![PSUB];
81
82    buf.extend(msg.transaction_id.to_be_bytes());
83    buf.extend(request_pattern_length.to_be_bytes());
84    buf.extend(msg.request_pattern.as_bytes());
85    buf.push(if msg.unique { 1 } else { 0 });
86
87    prepend_buffer_length(buf)
88}
89
90pub fn encode_export_message(msg: &Export) -> EncodeResult<Vec<u8>> {
91    let path_length = get_path_length(&msg.path)?;
92
93    let mut buf = vec![EXP];
94
95    buf.extend(msg.transaction_id.to_be_bytes());
96    buf.extend(path_length.to_be_bytes());
97    buf.extend(msg.path.as_bytes());
98
99    prepend_buffer_length(buf)
100}
101
102pub fn encode_import_message(msg: &Import) -> EncodeResult<Vec<u8>> {
103    let path_length = get_path_length(&msg.path)?;
104
105    let mut buf = vec![IMP];
106
107    buf.extend(msg.transaction_id.to_be_bytes());
108    buf.extend(path_length.to_be_bytes());
109    buf.extend(msg.path.as_bytes());
110
111    prepend_buffer_length(buf)
112}
113
114pub fn encode_unsubscribe_message(msg: &Unsubscribe) -> EncodeResult<Vec<u8>> {
115    let mut buf = vec![USUB];
116
117    buf.extend(msg.transaction_id.to_be_bytes());
118
119    prepend_buffer_length(buf)
120}
121
122pub fn encode_handshake_request_message(msg: &HandshakeRequest) -> EncodeResult<Vec<u8>> {
123    let num_protocol_versions = get_num_protocol_versions(&msg.supported_protocol_versions)?;
124    let num_last_will = get_num_last_will(&msg.last_will)?;
125    let num_grave_goods = get_num_grave_goods(&msg.grave_goods)?;
126
127    let mut buf = vec![HSHKR];
128
129    buf.extend(num_protocol_versions.to_be_bytes());
130    buf.extend(num_last_will.to_be_bytes());
131    buf.extend(num_grave_goods.to_be_bytes());
132
133    for ProtocolVersion { major, minor } in &msg.supported_protocol_versions {
134        buf.extend(major.to_be_bytes());
135        buf.extend(minor.to_be_bytes());
136    }
137
138    for KeyValuePair { key, value } in &msg.last_will {
139        let key_length = get_key_length(&key)?;
140        let value_length = get_value_length(&value)?;
141        buf.extend(key_length.to_be_bytes());
142        buf.extend(value_length.to_be_bytes());
143    }
144
145    for grave_good in &msg.grave_goods {
146        let key_length = get_key_length(&grave_good)?;
147        buf.extend(key_length.to_be_bytes());
148    }
149
150    for KeyValuePair { key, value } in &msg.last_will {
151        buf.extend(key.as_bytes());
152        buf.extend(value.as_bytes());
153    }
154
155    for grave_good in &msg.grave_goods {
156        buf.extend(grave_good.as_bytes());
157    }
158
159    prepend_buffer_length(buf)
160}
161
162#[cfg(test)]
163mod test {
164    use super::*;
165    use crate::{
166        Export, Get, Import, PGet, PSubscribe, Set, Subscribe, Unsubscribe, EXP, GET, IMP, PGET,
167        PSUB, SET, SUB, USUB,
168    };
169
170    #[test]
171    fn get_message_is_encoded_correctly() {
172        let msg = Get {
173            transaction_id: 4,
174            key: "trolo".to_owned(),
175        };
176
177        let data = [
178            0b00000000, 0b00000000, 0b00000000, 0b00010000, // message length
179            GET, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
180            0b00000000, 0b00000100, 0b00000000, 0b00000101, b't', b'r', b'o', b'l', b'o',
181        ];
182
183        assert_eq!(data.to_vec(), encode_get_message(&msg).unwrap());
184    }
185
186    #[test]
187    fn pget_message_is_encoded_correctly() {
188        let msg = PGet {
189            transaction_id: 4,
190            request_pattern: "trolo".to_owned(),
191        };
192
193        let data = [
194            0b00000000, 0b00000000, 0b00000000, 0b00010000, // message length
195            PGET, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
196            0b00000000, 0b00000100, 0b00000000, 0b00000101, b't', b'r', b'o', b'l', b'o',
197        ];
198
199        assert_eq!(data.to_vec(), encode_pget_message(&msg).unwrap());
200    }
201
202    #[test]
203    fn set_message_is_encoded_correctly() {
204        let msg = Set {
205            transaction_id: 0,
206            key: "yo/mama".to_owned(),
207            value: "fat".to_owned(),
208        };
209
210        let data = [
211            0b00000000, 0b00000000, 0b00000000, 0b00011001, // message length
212            SET, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
213            0b00000000, 0b00000000, 0b00000000, 0b00000111, 0b00000000, 0b00000000, 0b00000000,
214            0b00000011, b'y', b'o', b'/', b'm', b'a', b'm', b'a', b'f', b'a', b't',
215        ];
216
217        assert_eq!(data.to_vec(), encode_set_message(&msg).unwrap());
218    }
219
220    #[test]
221    fn subscribe_message_is_encoded_correctly() {
222        let msg = Subscribe {
223            transaction_id: 5536684732567,
224            key: "let/me/?/you/its/features".to_owned(),
225            unique: true,
226        };
227
228        let data = [
229            0b00000000, 0b00000000, 0b00000000, 0b00100101, // message length
230            SUB, 0b00000000, 0b00000000, 0b00000101, 0b00001001, 0b00011100, 0b00100000,
231            0b01110000, 0b10010111, 0b00000000, 0b00011001, b'l', b'e', b't', b'/', b'm', b'e',
232            b'/', b'?', b'/', b'y', b'o', b'u', b'/', b'i', b't', b's', b'/', b'f', b'e', b'a',
233            b't', b'u', b'r', b'e', b's', 0b00000001,
234        ];
235
236        assert_eq!(data.to_vec(), encode_subscribe_message(&msg).unwrap());
237    }
238
239    #[test]
240    fn psubscribe_message_is_encoded_correctly() {
241        let msg = PSubscribe {
242            transaction_id: 5536684732567,
243            request_pattern: "let/me/?/you/its/features".to_owned(),
244            unique: false,
245        };
246
247        let data = [
248            0b00000000, 0b00000000, 0b00000000, 0b00100101, // message length
249            PSUB, 0b00000000, 0b00000000, 0b00000101, 0b00001001, 0b00011100, 0b00100000,
250            0b01110000, 0b10010111, 0b00000000, 0b00011001, b'l', b'e', b't', b'/', b'm', b'e',
251            b'/', b'?', b'/', b'y', b'o', b'u', b'/', b'i', b't', b's', b'/', b'f', b'e', b'a',
252            b't', b'u', b'r', b'e', b's', 0b00000000,
253        ];
254
255        assert_eq!(data.to_vec(), encode_psubscribe_message(&msg).unwrap());
256    }
257
258    #[test]
259    fn export_message_is_encoded_correctly() {
260        let msg = Export {
261            transaction_id: 42,
262            path: "/path/to/file".to_owned(),
263        };
264
265        let data = [
266            0b00000000, 0b00000000, 0b00000000, 0b00011000, // message length
267            EXP, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
268            0b00000000, 0b00101010, 0b00000000, 0b00001101, b'/', b'p', b'a', b't', b'h', b'/',
269            b't', b'o', b'/', b'f', b'i', b'l', b'e',
270        ];
271
272        assert_eq!(data.to_vec(), encode_export_message(&msg).unwrap());
273    }
274
275    #[test]
276    fn import_message_is_encoded_correctly() {
277        let msg = Import {
278            transaction_id: 42,
279            path: "/path/to/file".to_owned(),
280        };
281
282        let data = [
283            0b00000000, 0b00000000, 0b00000000, 0b00011000, // message length
284            IMP, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
285            0b00000000, 0b00101010, 0b00000000, 0b00001101, b'/', b'p', b'a', b't', b'h', b'/',
286            b't', b'o', b'/', b'f', b'i', b'l', b'e',
287        ];
288
289        assert_eq!(data.to_vec(), encode_import_message(&msg).unwrap());
290    }
291
292    #[test]
293    fn unsubscribe_message_is_encoded_correctly() {
294        let msg = Unsubscribe { transaction_id: 42 };
295
296        let data = [
297            0b00000000, 0b00000000, 0b00000000, 0b00001001, // message length
298            USUB, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
299            0b00000000, 0b00101010,
300        ];
301
302        assert_eq!(data.to_vec(), encode_unsubscribe_message(&msg).unwrap());
303    }
304
305    #[test]
306    fn handshake_request_message_is_encoded_correctly() {
307        let msg = HandshakeRequest {
308            supported_protocol_versions: vec![
309                ProtocolVersion { major: 0, minor: 1 },
310                ProtocolVersion { major: 0, minor: 5 },
311                ProtocolVersion { major: 1, minor: 0 },
312            ],
313            last_will: vec![("last/will", "test").into()],
314            grave_goods: vec!["grave/goods/1".into(), "grave/goods/2".into()],
315        };
316
317        let data = [
318            0b00000000, 0b00000000, 0b00000000, 0b01000001, // message length
319            HSHKR,      // message type
320            0b00000011, // 3 protocol versions
321            0b00000001, // 1 last will
322            0b00000010, // 2 grave goods
323            0b00000000, 0b00000000, 0b00000000, 0b00000001, // protocol version 0.1
324            0b00000000, 0b00000000, 0b00000000, 0b00000101, // protocol version 0.5
325            0b00000000, 0b00000001, 0b00000000, 0b00000000, // protocol version 1.0
326            0b00000000, 0b00001001, // last will key length (9)
327            0b00000000, 0b00000000, 0b00000000, 0b00000100, // last will value length (4)
328            0b00000000, 0b00001101, // grave good 1 key length (13)
329            0b00000000, 0b00001101, // grave good 2 key length (13)
330            b'l', b'a', b's', b't', b'/', b'w', b'i', b'l', b'l', // last will key
331            b't', b'e', b's', b't', // last will value
332            b'g', b'r', b'a', b'v', b'e', b'/', b'g', b'o', b'o', b'd', b's', b'/',
333            b'1', // grave goods 1 key
334            b'g', b'r', b'a', b'v', b'e', b'/', b'g', b'o', b'o', b'd', b's', b'/',
335            b'2', // grave goods 2 key
336        ];
337
338        assert_eq!(
339            data.to_vec(),
340            encode_handshake_request_message(&msg).unwrap()
341        );
342    }
343}