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, 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, 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, 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, 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, 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, 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}