1use crate::{
2 buffer::{ArrayBuffer, Buffer},
3 bytes::parse_i64_exact,
4 PackRef, PackValue,
5};
6use bytes::{BufMut, Bytes};
7
8pub trait Packable {
10 fn pack_size(&self) -> usize;
12
13 fn pack_write(&self, buffer: impl BufMut);
15
16 fn pack_eq<'a>(&'a self, other: &PackRef<'a>) -> bool;
18}
19
20impl Packable for f64 {
21 fn pack_size(&self) -> usize {
22 10
23 }
24
25 fn pack_write(&self, mut buffer: impl BufMut) {
26 buffer.put_u8(0xf5);
27 buffer.put_f64_le(*self);
28 buffer.put_u8(9);
29 }
30
31 fn pack_eq<'a>(&'a self, other: &PackRef<'a>) -> bool {
32 let mut buffer = ArrayBuffer::default();
33
34 use PackRef::*;
35 match other {
36 Float(other) => self == other,
37 Integer(other) => {
38 if self.fract() == 0f64 {
39 #[allow(clippy::cast_possible_truncation)]
40 let i = *self as i64;
41 i == *other
42 } else {
43 false
44 }
45 }
46 Slice(other) => buffer.write_f64(*self) == &other[..],
47 }
48 }
49}
50
51impl Packable for i64 {
52 fn pack_size(&self) -> usize {
53 match self {
54 0..=0x7f => 2,
56 -0x1000..=0xfff => 3,
58 -0x8000..=0x7fff => 4,
60 -0x0080_0000..=0x007f_ffff => 5,
62 -0x8000_0000..=0x7fff_ffff => 6,
64 _ => 10,
66 }
67 }
68
69 fn pack_write(&self, mut buffer: impl BufMut) {
70 match self {
71 0..=0x7f => {
73 buffer.put_int_le(*self, 1);
74 buffer.put_u8(1);
75 }
76 -0x1000..=0xfff => {
78 let bytes = self.to_be_bytes();
79 buffer.put_u8(0xc0 | (0xdf & bytes[6]));
80 buffer.put_u8(bytes[7]);
81 buffer.put_u8(2);
82 }
83 -0x8000..=0x7fff => {
85 buffer.put_u8(0xf1);
86 buffer.put_int_le(*self, 2);
87 buffer.put_u8(3);
88 }
89 -0x0080_0000..=0x007f_ffff => {
91 buffer.put_u8(0xf2);
92 buffer.put_int_le(*self, 3);
93 buffer.put_u8(4);
94 }
95 -0x8000_0000..=0x7fff_ffff => {
97 buffer.put_u8(0xf3);
98 buffer.put_int_le(*self, 4);
99 buffer.put_u8(5);
100 }
101 _ => {
103 buffer.put_u8(0xf4);
104 buffer.put_i64_le(*self);
105 buffer.put_u8(9);
106 }
107 }
108 }
109
110 fn pack_eq<'a>(&'a self, other: &PackRef<'a>) -> bool {
111 use PackRef::*;
112 match other {
113 Float(f) => {
114 if f.fract() == 0f64 {
115 #[allow(clippy::cast_possible_truncation)]
116 let i = *f as i64;
117 i == *self
118 } else {
119 false
120 }
121 }
122 Integer(i) => self == i,
123 Slice(s) => match parse_i64_exact(&s[..]) {
124 Some(i) => *self == i,
125 None => false,
126 },
127 }
128 }
129}
130
131impl Packable for &[u8] {
132 fn pack_size(&self) -> usize {
133 if let Some(i) = parse_i64_exact(self) {
134 return i.pack_size();
135 }
136
137 match self.len() {
138 0..=0x3f => self.len() + 2,
139 0x40..=0xfff => self.len() + 2 + back_len_size(self.len() + 2),
140 0x1000..=0xffff_ffff => self.len() + 5 + back_len_size(self.len() + 5),
141 _ => todo!("xl string"),
142 }
143 }
144
145 fn pack_write(&self, mut buffer: impl BufMut) {
146 if let Some(i) = parse_i64_exact(self) {
147 return i.pack_write(buffer);
148 }
149
150 match self.len() {
151 0..=0x3f => {
152 buffer.put_u8(0x80 | u8::try_from(self.len()).unwrap());
153 buffer.put_slice(self);
154 write_back_len(self.len() + 1, buffer);
155 }
156 0x40..=0xfff => {
157 let len = u16::try_from(self.len()).unwrap();
158 buffer.put_u16(0xe000 | (0x0fff & len));
159 buffer.put_slice(self);
160 write_back_len(self.len() + 2, buffer);
161 }
162 0x1000..=0xffff_ffff => {
163 buffer.put_u8(0xf0);
164 buffer.put_u32_le(u32::try_from(self.len()).unwrap());
165 buffer.put_slice(self);
166 write_back_len(self.len() + 5, buffer);
167 }
168 _ => todo!("xl string"),
169 }
170 }
171
172 fn pack_eq<'a>(&'a self, other: &PackRef<'a>) -> bool {
173 let mut buffer = ArrayBuffer::default();
174
175 use PackRef::*;
176 match other {
177 Float(f) => &self[..] == buffer.write_f64(*f),
178 Integer(i) => match parse_i64_exact(&self[..]) {
179 Some(parsed) => *i == parsed,
180 None => false,
181 },
182 Slice(s) => self[..] == s[..],
183 }
184 }
185}
186
187impl Packable for Bytes {
188 fn pack_size(&self) -> usize {
189 (&self[..]).pack_size()
190 }
191
192 fn pack_write(&self, buffer: impl BufMut) {
193 (&self[..]).pack_write(buffer);
194 }
195
196 fn pack_eq<'a>(&'a self, other: &PackRef<'a>) -> bool {
197 (&self[..]).pack_eq(other)
198 }
199}
200
201impl Packable for &str {
202 fn pack_size(&self) -> usize {
203 self.as_bytes().pack_size()
204 }
205
206 fn pack_write(&self, buffer: impl BufMut) {
207 self.as_bytes().pack_write(buffer);
208 }
209
210 fn pack_eq<'a>(&'a self, other: &PackRef<'a>) -> bool {
211 self.as_bytes().pack_eq(other)
212 }
213}
214
215impl Packable for PackRef<'_> {
216 fn pack_size(&self) -> usize {
217 use PackRef::*;
218 match self {
219 Float(f) => f.pack_size(),
220 Integer(i) => i.pack_size(),
221 Slice(s) => (&s[..]).pack_size(),
222 }
223 }
224
225 fn pack_write(&self, buffer: impl BufMut) {
226 use PackRef::*;
227 match self {
228 Float(f) => f.pack_write(buffer),
229 Integer(i) => i.pack_write(buffer),
230 Slice(s) => (&s[..]).pack_write(buffer),
231 }
232 }
233
234 fn pack_eq<'a>(&'a self, other: &PackRef<'a>) -> bool {
235 use PackRef::*;
236 match self {
237 Float(f) => f.pack_eq(other),
238 Integer(i) => i.pack_eq(other),
239 Slice(s) => (&s[..]).pack_eq(other),
240 }
241 }
242}
243
244impl Packable for PackValue {
245 fn pack_size(&self) -> usize {
246 use PackValue::*;
247 match self {
248 Float(f) => f.pack_size(),
249 Integer(i) => i.pack_size(),
250 Raw(s) => (&s[..]).pack_size(),
251 }
252 }
253
254 fn pack_write(&self, buffer: impl BufMut) {
255 use PackValue::*;
256 match self {
257 Float(f) => f.pack_write(buffer),
258 Integer(i) => i.pack_write(buffer),
259 Raw(s) => (&s[..]).pack_write(buffer),
260 }
261 }
262
263 fn pack_eq<'a>(&'a self, other: &PackRef<'a>) -> bool {
264 use PackValue::*;
265 match self {
266 Float(f) => f.pack_eq(other),
267 Integer(i) => i.pack_eq(other),
268 Raw(s) => (&s[..]).pack_eq(other),
269 }
270 }
271}
272
273fn back_len_size(mut len: usize) -> usize {
274 let mut size = 0;
275 while len > 0 {
276 size += 1;
277 len >>= 7;
278 }
279 size
280}
281
282fn write_back_len(mut len: usize, mut buffer: impl BufMut) {
283 buffer.put_u8(u8::try_from(0x7f & len).unwrap());
284 len >>= 7;
285 while len > 0 {
286 buffer.put_u8(0x80 | u8::try_from(0x7f & len).unwrap());
287 len >>= 7;
288 }
289}
290
291#[cfg(test)]
292mod tests {
293 use super::*;
294 use crate::Pack;
295
296 macro_rules! assert_back_len {
297 ($len:expr, $expected:expr) => {{
298 let mut buffer: Vec<u8> = Vec::new();
299 write_back_len($len, &mut buffer);
300 assert_eq!(&buffer[..], &$expected[..]);
301 }};
302 }
303
304 #[test]
305 fn test_back_len_size() {
306 assert_eq!(back_len_size(0x01), 1);
307 assert_eq!(back_len_size(0x7f), 1);
308
309 assert_eq!(back_len_size(0x80), 2);
310 assert_eq!(back_len_size(0x81), 2);
311 assert_eq!(back_len_size(0x3fff), 2);
312
313 assert_eq!(back_len_size(0x4000), 3);
314 assert_eq!(back_len_size(0x4001), 3);
315 assert_eq!(back_len_size(0x1fffff), 3);
316
317 assert_eq!(back_len_size(0x200000), 4);
318 assert_eq!(back_len_size(0x200001), 4);
319 assert_eq!(back_len_size(0xfffffff), 4);
320
321 assert_eq!(back_len_size(0x10000000), 5);
322 assert_eq!(back_len_size(0x10000001), 5);
323 }
324
325 #[test]
326 fn test_write_back_len() {
327 assert_back_len!(0x01, b"\x01");
329 assert_back_len!(0x02, b"\x02");
330 assert_back_len!(0x7f, b"\x7f");
331
332 assert_back_len!(0x80, b"\x00\x81");
334 assert_back_len!(0x81, b"\x01\x81");
335 assert_back_len!(0x3fff, b"\x7f\xff");
336
337 assert_back_len!(0x4000, b"\x00\x80\x81");
339 assert_back_len!(0x4001, b"\x01\x80\x81");
340 assert_back_len!(0x1fffff, b"\x7f\xff\xff");
341
342 assert_back_len!(0x200000, b"\x00\x80\x80\x81");
344 assert_back_len!(0x200001, b"\x01\x80\x80\x81");
345 assert_back_len!(0xfffffff, b"\x7f\xff\xff\xff");
346
347 assert_back_len!(0x10000000, b"\x00\x80\x80\x80\x81");
349 assert_back_len!(0x10000001, b"\x01\x80\x80\x80\x81");
350 }
351
352 #[test]
353 fn test_pack_eq() {
354 let mut pack = Pack::default();
355 pack.append(&1234);
356 pack.append(&12.34f64);
357 pack.append(&"12.34");
358 pack.append(&12f64);
359 pack.append(&"12");
360 let mut iter = pack.iter();
361
362 let i = iter.next().unwrap();
363 assert!("1234".pack_eq(&i));
364 assert!(1234f64.pack_eq(&i));
365 assert!(!1234.2f64.pack_eq(&i));
366
367 let f = iter.next().unwrap();
368 assert!("12.34".pack_eq(&f));
369
370 let s = iter.next().unwrap();
371 assert!(12.34f64.pack_eq(&s));
372
373 let f = iter.next().unwrap();
374 assert!(12i64.pack_eq(&f));
375 assert!(!13i64.pack_eq(&f));
376
377 let s = iter.next().unwrap();
378 assert!(12i64.pack_eq(&s));
379 assert!(!13i64.pack_eq(&s));
380 }
381}