distant_net/common/
packet.rs

1mod header;
2mod request;
3mod response;
4mod value;
5
6use std::io::Cursor;
7
8pub use header::*;
9pub use request::*;
10pub use response::*;
11pub use value::*;
12
13/// Represents a generic id type
14pub type Id = String;
15
16/// Reads the header bytes from msgpack input, including the marker and len bytes.
17///
18/// * If succeeds, returns (header, remaining).
19/// * If fails, returns existing bytes.
20fn read_header_bytes(input: &[u8]) -> Result<(&[u8], &[u8]), &[u8]> {
21    let mut cursor = Cursor::new(input);
22    let input_len = input.len();
23
24    // Determine size of header map in terms of total objects
25    let len = match rmp::decode::read_map_len(&mut cursor) {
26        Ok(x) => x,
27        Err(_) => return Err(input),
28    };
29
30    // For each object, we have a corresponding key in front of it has a string,
31    // so we need to iterate, advancing by a string key and then the object
32    for _i in 0..len {
33        // Read just the length of the key to avoid copying the key itself
34        let key_len = match rmp::decode::read_str_len(&mut cursor) {
35            Ok(x) => x as u64,
36            Err(_) => return Err(input),
37        };
38
39        // Advance forward past the key
40        cursor.set_position(cursor.position() + key_len);
41
42        // If we would have advanced past our input, fail
43        if cursor.position() as usize > input_len {
44            return Err(input);
45        }
46
47        // Point locally to just past the str key so we can determine next byte len to skip
48        let input = &input[cursor.position() as usize..];
49
50        // Read the type of object and advance accordingly
51        match find_msgpack_byte_len(input) {
52            Some(len) => cursor.set_position(cursor.position() + len),
53            None => return Err(input),
54        }
55
56        // If we would have advanced past our input, fail
57        if cursor.position() as usize > input_len {
58            return Err(input);
59        }
60    }
61
62    let pos = cursor.position() as usize;
63
64    // Check if we've read beyond the input (being equal to len is okay
65    // because we could consume all of the remaining input this way)
66    if pos > input_len {
67        return Err(input);
68    }
69
70    Ok((&input[..pos], &input[pos..]))
71}
72
73/// Determines the length of the next object based on its marker. From the marker, some objects
74/// need to be traversed (e.g. map) in order to fully understand the total byte length.
75///
76/// This will include the marker bytes in the total byte len such that collecting all of the
77/// bytes up to len will yield a valid msgpack object in byte form.
78///
79/// If the first byte does not signify a valid marker, this method returns None.
80fn find_msgpack_byte_len(input: &[u8]) -> Option<u64> {
81    if input.is_empty() {
82        return None;
83    }
84
85    macro_rules! read_len {
86        (u8: $input:expr $(, start = $start:expr)?) => {{
87            let input = $input;
88
89            $(
90                if input.len() < $start {
91                    return None;
92                }
93                let input = &input[$start..];
94            )?
95
96            if input.is_empty() {
97                return None;
98            } else {
99                input[0] as u64
100            }
101        }};
102        (u16: $input:expr $(, start = $start:expr)?) => {{
103            let input = $input;
104
105            $(
106                if input.len() < $start {
107                    return None;
108                }
109                let input = &input[$start..];
110            )?
111
112            if input.len() < 2 {
113                return None;
114            } else {
115                u16::from_be_bytes([input[0], input[1]]) as u64
116            }
117        }};
118        (u32: $input:expr $(, start = $start:expr)?) => {{
119            let input = $input;
120
121            $(
122                if input.len() < $start {
123                    return None;
124                }
125                let input = &input[$start..];
126            )?
127
128            if input.len() < 4 {
129                return None;
130            } else {
131                u32::from_be_bytes([input[0], input[1], input[2], input[3]]) as u64
132            }
133        }};
134        ($cnt:expr => $input:expr $(, start = $start:expr)?) => {{
135            let input = $input;
136
137            $(
138                if input.len() < $start {
139                    return None;
140                }
141                let input = &input[$start..];
142            )?
143
144            let cnt = $cnt;
145            let mut len = 0;
146            for _i in 0..cnt {
147                if input.len() < len {
148                    return None;
149                }
150
151                let input = &input[len..];
152                match find_msgpack_byte_len(input) {
153                    Some(x) => len += x as usize,
154                    None => return None,
155                }
156            }
157            len as u64
158        }};
159    }
160
161    Some(match rmp::Marker::from_u8(input[0]) {
162        // Booleans and nil (aka null) are a combination of marker and value (single byte)
163        rmp::Marker::Null => 1,
164        rmp::Marker::True => 1,
165        rmp::Marker::False => 1,
166
167        // Integers are stored in 1, 2, 3, 5, or 9 bytes
168        rmp::Marker::FixPos(_) => 1,
169        rmp::Marker::FixNeg(_) => 1,
170        rmp::Marker::U8 => 2,
171        rmp::Marker::U16 => 3,
172        rmp::Marker::U32 => 5,
173        rmp::Marker::U64 => 9,
174        rmp::Marker::I8 => 2,
175        rmp::Marker::I16 => 3,
176        rmp::Marker::I32 => 5,
177        rmp::Marker::I64 => 9,
178
179        // Floats are stored in 5 or 9 bytes
180        rmp::Marker::F32 => 5,
181        rmp::Marker::F64 => 9,
182
183        // Str are stored in 1, 2, 3, or 5 bytes + the data buffer
184        rmp::Marker::FixStr(len) => 1 + len as u64,
185        rmp::Marker::Str8 => 2 + read_len!(u8: input, start = 1),
186        rmp::Marker::Str16 => 3 + read_len!(u16: input, start = 1),
187        rmp::Marker::Str32 => 5 + read_len!(u32: input, start = 1),
188
189        // Bin are stored in 2, 3, or 5 bytes + the data buffer
190        rmp::Marker::Bin8 => 2 + read_len!(u8: input, start = 1),
191        rmp::Marker::Bin16 => 3 + read_len!(u16: input, start = 1),
192        rmp::Marker::Bin32 => 5 + read_len!(u32: input, start = 1),
193
194        // Arrays are stored in 1, 3, or 5 bytes + N objects (where each object has its own len)
195        rmp::Marker::FixArray(cnt) => 1 + read_len!(cnt => input, start = 1),
196        rmp::Marker::Array16 => {
197            let cnt = read_len!(u16: input, start = 1);
198            3 + read_len!(cnt => input, start = 3)
199        }
200        rmp::Marker::Array32 => {
201            let cnt = read_len!(u32: input, start = 1);
202            5 + read_len!(cnt => input, start = 5)
203        }
204
205        // Maps are stored in 1, 3, or 5 bytes + 2*N objects (where each object has its own len)
206        rmp::Marker::FixMap(cnt) => 1 + read_len!(2 * cnt => input, start = 1),
207        rmp::Marker::Map16 => {
208            let cnt = read_len!(u16: input, start = 1);
209            3 + read_len!(2 * cnt => input, start = 3)
210        }
211        rmp::Marker::Map32 => {
212            let cnt = read_len!(u32: input, start = 1);
213            5 + read_len!(2 * cnt => input, start = 5)
214        }
215
216        // Ext are stored in an integer (8-bit, 16-bit, 32-bit), type (8-bit), and byte array
217        rmp::Marker::FixExt1 => 3,
218        rmp::Marker::FixExt2 => 4,
219        rmp::Marker::FixExt4 => 6,
220        rmp::Marker::FixExt8 => 10,
221        rmp::Marker::FixExt16 => 18,
222        rmp::Marker::Ext8 => 3 + read_len!(u8: input, start = 1),
223        rmp::Marker::Ext16 => 4 + read_len!(u16: input, start = 1),
224        rmp::Marker::Ext32 => 6 + read_len!(u32: input, start = 1),
225
226        // NOTE: This is marked in the msgpack spec as never being used, so we return none
227        //       as this is signfies something has gone wrong!
228        rmp::Marker::Reserved => return None,
229    })
230}
231
232/// Reads the str bytes from msgpack input, including the marker and len bytes.
233///
234/// * If succeeds, returns (str, remaining).
235/// * If fails, returns existing bytes.
236fn read_str_bytes(input: &[u8]) -> Result<(&str, &[u8]), &[u8]> {
237    match rmp::decode::read_str_from_slice(input) {
238        Ok(x) => Ok(x),
239        Err(_) => Err(input),
240    }
241}
242
243/// Reads a str key from msgpack input and checks if it matches `key`. If so, the input is
244/// advanced, otherwise the original input is returned.
245///
246/// * If key read successfully and matches, returns (unit, remaining).
247/// * Otherwise, returns existing bytes.
248fn read_key_eq<'a>(input: &'a [u8], key: &str) -> Result<((), &'a [u8]), &'a [u8]> {
249    match read_str_bytes(input) {
250        Ok((s, input)) if s == key => Ok(((), input)),
251        _ => Err(input),
252    }
253}
254
255#[cfg(test)]
256mod tests {
257    use super::*;
258
259    mod read_str_bytes {
260        use test_log::test;
261
262        use super::*;
263
264        #[test]
265        fn should_fail_if_input_is_empty() {
266            let input = read_str_bytes(&[]).unwrap_err();
267            assert!(input.is_empty());
268        }
269
270        #[test]
271        fn should_fail_if_input_does_not_start_with_str() {
272            let input = read_str_bytes(&[0xff, 0xa5, b'h', b'e', b'l', b'l', b'o']).unwrap_err();
273            assert_eq!(input, [0xff, 0xa5, b'h', b'e', b'l', b'l', b'o']);
274        }
275
276        #[test]
277        fn should_succeed_if_input_starts_with_str() {
278            let (s, remaining) =
279                read_str_bytes(&[0xa5, b'h', b'e', b'l', b'l', b'o', 0xff]).unwrap();
280            assert_eq!(s, "hello");
281            assert_eq!(remaining, [0xff]);
282        }
283    }
284
285    mod read_key_eq {
286        use test_log::test;
287
288        use super::*;
289
290        #[test]
291        fn should_fail_if_input_is_empty() {
292            let input = read_key_eq(&[], "key").unwrap_err();
293            assert!(input.is_empty());
294        }
295
296        #[test]
297        fn should_fail_if_input_does_not_start_with_str() {
298            let input = &[
299                0xff,
300                rmp::Marker::FixStr(5).to_u8(),
301                b'h',
302                b'e',
303                b'l',
304                b'l',
305                b'o',
306            ];
307            let remaining = read_key_eq(input, "key").unwrap_err();
308            assert_eq!(remaining, input);
309        }
310
311        #[test]
312        fn should_fail_if_read_key_does_not_match_specified_key() {
313            let input = &[
314                rmp::Marker::FixStr(5).to_u8(),
315                b'h',
316                b'e',
317                b'l',
318                b'l',
319                b'o',
320                0xff,
321            ];
322            let remaining = read_key_eq(input, "key").unwrap_err();
323            assert_eq!(remaining, input);
324        }
325
326        #[test]
327        fn should_succeed_if_read_key_matches_specified_key() {
328            let input = &[
329                rmp::Marker::FixStr(5).to_u8(),
330                b'h',
331                b'e',
332                b'l',
333                b'l',
334                b'o',
335                0xff,
336            ];
337            let (_, remaining) = read_key_eq(input, "hello").unwrap();
338            assert_eq!(remaining, [0xff]);
339        }
340    }
341
342    mod read_header_bytes {
343        use test_log::test;
344
345        use super::*;
346
347        #[test]
348        fn should_fail_if_input_is_empty() {
349            let input = vec![];
350            assert!(read_header_bytes(&input).is_err());
351        }
352
353        #[test]
354        fn should_fail_if_not_a_map() {
355            // Provide an array instead of a map
356            let input = vec![0x93, 0xa3, b'a', b'b', b'c', 0xcc, 0xff, 0xc2];
357            assert!(read_header_bytes(&input).is_err());
358        }
359
360        #[test]
361        fn should_fail_if_cannot_read_str_key_length() {
362            let input = vec![
363                0x81, // valid map with 1 pair, but key is not a str
364                0x03, 0xa3, b'a', b'b', b'c', // 3 -> "abc"
365            ];
366            assert!(read_header_bytes(&input).is_err());
367        }
368        #[test]
369        fn should_fail_if_key_length_exceeds_remaining_bytes() {
370            let input = vec![
371                0x81, // valid map with 1 pair, but key length is too long
372                0xa8, b'a', b'b', b'c', // key: "abc" (but len is much greater)
373                0xa3, b'a', b'b', b'c', // value: "abc"
374            ];
375            assert!(read_header_bytes(&input).is_err());
376        }
377
378        #[test]
379        fn should_fail_if_missing_value_for_key() {
380            let input = vec![
381                0x81, // valid map with 1 pair, but value is missing
382                0xa3, b'a', b'b', b'c', // key: "abc"
383            ];
384            assert!(read_header_bytes(&input).is_err());
385        }
386
387        #[test]
388        fn should_fail_if_unable_to_read_value_length() {
389            let input = vec![
390                0x81, // valid map with 1 pair, but value is missing
391                0xa3, b'a', b'b', b'c', // key: "abc"
392                0xd9, // value: str 8 with missing length
393            ];
394            assert!(read_header_bytes(&input).is_err());
395        }
396
397        #[test]
398        fn should_fail_if_value_length_exceeds_remaining_bytes() {
399            let input = vec![
400                0x81, // valid map with 1 pair, but value is too long
401                0xa3, b'a', b'b', b'c', // key: "abc"
402                0xa2, b'd', // value: fixstr w/ len 1 too long
403            ];
404            assert!(read_header_bytes(&input).is_err());
405        }
406
407        #[test]
408        fn should_succeed_with_empty_map() {
409            // fixmap with 0 pairs
410            let input = vec![0x80];
411            let (header, _) = read_header_bytes(&input).unwrap();
412            assert_eq!(header, input);
413
414            // map 16 with 0 pairs
415            let input = vec![0xde, 0x00, 0x00];
416            let (header, _) = read_header_bytes(&input).unwrap();
417            assert_eq!(header, input);
418
419            // map 32 with 0 pairs
420            let input = vec![0xdf, 0x00, 0x00, 0x00, 0x00];
421            let (header, _) = read_header_bytes(&input).unwrap();
422            assert_eq!(header, input);
423        }
424
425        #[test]
426        fn should_succeed_with_single_key_value_map() {
427            // fixmap with single pair
428            let input = vec![
429                0x81, // valid map with 1 pair
430                0xa3, b'k', b'e', b'y', // key: "key"
431                0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
432            ];
433            let (header, _) = read_header_bytes(&input).unwrap();
434            assert_eq!(header, input);
435
436            // map 16 with single pair
437            let input = vec![
438                0xde, 0x00, 0x01, // valid map with 1 pair
439                0xa3, b'k', b'e', b'y', // key: "key"
440                0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
441            ];
442            let (header, _) = read_header_bytes(&input).unwrap();
443            assert_eq!(header, input);
444
445            // map 32 with single pair
446            let input = vec![
447                0xdf, 0x00, 0x00, 0x00, 0x01, // valid map with 1 pair
448                0xa3, b'k', b'e', b'y', // key: "key"
449                0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
450            ];
451            let (header, _) = read_header_bytes(&input).unwrap();
452            assert_eq!(header, input);
453        }
454
455        #[test]
456        fn should_succeed_with_multiple_key_value_map() {
457            // fixmap with single pair
458            let input = vec![
459                0x82, // valid map with 2 pairs
460                0xa3, b'k', b'e', b'y', // key: "key"
461                0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
462                0xa3, b'y', b'e', b'k', // key: "yek"
463                0x7b, // value: 123 (fixint)
464            ];
465            let (header, _) = read_header_bytes(&input).unwrap();
466            assert_eq!(header, input);
467
468            // map 16 with single pair
469            let input = vec![
470                0xde, 0x00, 0x02, // valid map with 2 pairs
471                0xa3, b'k', b'e', b'y', // key: "key"
472                0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
473                0xa3, b'y', b'e', b'k', // key: "yek"
474                0x7b, // value: 123 (fixint)
475            ];
476            let (header, _) = read_header_bytes(&input).unwrap();
477            assert_eq!(header, input);
478
479            // map 32 with single pair
480            let input = vec![
481                0xdf, 0x00, 0x00, 0x00, 0x02, // valid map with 2 pairs
482                0xa3, b'k', b'e', b'y', // key: "key"
483                0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
484                0xa3, b'y', b'e', b'k', // key: "yek"
485                0x7b, // value: 123 (fixint)
486            ];
487            let (header, _) = read_header_bytes(&input).unwrap();
488            assert_eq!(header, input);
489        }
490
491        #[test]
492        fn should_succeed_with_nested_map() {
493            // fixmap with single pair
494            let input = vec![
495                0x81, // valid map with 1 pair
496                0xa3, b'm', b'a', b'p', // key: "map"
497                0x81, // value: valid map with 1 pair
498                0xa3, b'k', b'e', b'y', // key: "key"
499                0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
500            ];
501            let (header, _) = read_header_bytes(&input).unwrap();
502            assert_eq!(header, input);
503        }
504
505        #[test]
506        fn should_only_consume_map_from_input() {
507            // fixmap with single pair
508            let input = vec![
509                0x81, // valid map with 1 pair
510                0xa3, b'k', b'e', b'y', // key: "key"
511                0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
512                0xa4, b'm', b'o', b'r', b'e', // "more" (fixstr)
513            ];
514            let (header, remaining) = read_header_bytes(&input).unwrap();
515            assert_eq!(
516                header,
517                vec![
518                    0x81, // valid map with 1 pair
519                    0xa3, b'k', b'e', b'y', // key: "key"
520                    0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
521                ]
522            );
523            assert_eq!(
524                remaining,
525                vec![
526                0xa4, b'm', b'o', b'r', b'e', // "more" (fixstr)
527            ]
528            );
529        }
530    }
531
532    mod find_msgpack_byte_len {
533        use test_log::test;
534
535        use super::*;
536
537        #[test]
538        fn should_return_none_if_input_is_empty() {
539            let input = vec![];
540            let len = find_msgpack_byte_len(&input);
541            assert_eq!(len, None, "Wrong len for {input:X?}");
542        }
543
544        #[test]
545        fn should_return_none_if_input_has_reserved_marker() {
546            let input = vec![rmp::Marker::Reserved.to_u8()];
547            let len = find_msgpack_byte_len(&input);
548            assert_eq!(len, None, "Wrong len for {input:X?}");
549        }
550
551        #[test]
552        fn should_return_1_if_input_is_nil() {
553            let input = vec![0xc0];
554            let len = find_msgpack_byte_len(&input);
555            assert_eq!(len, Some(1), "Wrong len for {input:X?}");
556        }
557
558        #[test]
559        fn should_return_1_if_input_is_a_boolean() {
560            let input = vec![0xc2]; // false
561            let len = find_msgpack_byte_len(&input);
562            assert_eq!(len, Some(1), "Wrong len for {input:X?}");
563
564            let input = vec![0xc3]; // true
565            let len = find_msgpack_byte_len(&input);
566            assert_eq!(len, Some(1), "Wrong len for {input:X?}");
567        }
568
569        #[test]
570        fn should_return_appropriate_len_if_input_is_some_integer() {
571            let input = vec![0x00]; // positive fixint (0)
572            let len = find_msgpack_byte_len(&input);
573            assert_eq!(len, Some(1), "Wrong len for {input:X?}");
574
575            let input = vec![0xff]; // negative fixint (-1)
576            let len = find_msgpack_byte_len(&input);
577            assert_eq!(len, Some(1), "Wrong len for {input:X?}");
578
579            let input = vec![0xcc, 0xff]; // unsigned 8-bit (255)
580            let len = find_msgpack_byte_len(&input);
581            assert_eq!(len, Some(2), "Wrong len for {input:X?}");
582
583            let input = vec![0xcd, 0xff, 0xff]; // unsigned 16-bit (65535)
584            let len = find_msgpack_byte_len(&input);
585            assert_eq!(len, Some(3), "Wrong len for {input:X?}");
586
587            let input = vec![0xce, 0xff, 0xff, 0xff, 0xff]; // unsigned 32-bit (4294967295)
588            let len = find_msgpack_byte_len(&input);
589            assert_eq!(len, Some(5), "Wrong len for {input:X?}");
590
591            let input = vec![0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]; // unsigned 64-bit (4294967296)
592            let len = find_msgpack_byte_len(&input);
593            assert_eq!(len, Some(9), "Wrong len for {input:X?}");
594
595            let input = vec![0xd0, 0x81]; // signed 8-bit (-127)
596            let len = find_msgpack_byte_len(&input);
597            assert_eq!(len, Some(2), "Wrong len for {input:X?}");
598
599            let input = vec![0xd1, 0x80, 0x01]; // signed 16-bit (-32767)
600            let len = find_msgpack_byte_len(&input);
601            assert_eq!(len, Some(3), "Wrong len for {input:X?}");
602
603            let input = vec![0xd2, 0x80, 0x00, 0x00, 0x01]; // signed 32-bit (-2147483647)
604            let len = find_msgpack_byte_len(&input);
605            assert_eq!(len, Some(5), "Wrong len for {input:X?}");
606
607            let input = vec![0xd3, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00]; // signed 64-bit (-2147483648)
608            let len = find_msgpack_byte_len(&input);
609            assert_eq!(len, Some(9), "Wrong len for {input:X?}");
610        }
611
612        #[test]
613        fn should_return_appropriate_len_if_input_is_some_float() {
614            let input = vec![0xca, 0x3d, 0xcc, 0xcc, 0xcd]; // f32 (0.1)
615            let len = find_msgpack_byte_len(&input);
616            assert_eq!(len, Some(5), "Wrong len for {input:X?}");
617
618            let input = vec![0xcb, 0x3f, 0xb9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a]; // f64 (0.1)
619            let len = find_msgpack_byte_len(&input);
620            assert_eq!(len, Some(9), "Wrong len for {input:X?}");
621        }
622
623        #[test]
624        fn should_return_appropriate_len_if_input_is_some_str() {
625            // fixstr (31 bytes max)
626            let input = vec![0xa5, b'h', b'e', b'l', b'l', b'o'];
627            let len = find_msgpack_byte_len(&input);
628            assert_eq!(len, Some(5 + 1), "Wrong len for {input:X?}");
629
630            // str 8 will read second byte (u8) for size
631            let input = vec![0xd9, 0xff, b'd', b'a', b't', b'a'];
632            let len = find_msgpack_byte_len(&input);
633            assert_eq!(len, Some(u8::MAX as u64 + 2), "Wrong len for {input:X?}");
634
635            // str 16 will read second & third bytes (u16) for size
636            let input = vec![0xda, 0xff, 0xff, b'd', b'a', b't', b'a'];
637            let len = find_msgpack_byte_len(&input);
638            assert_eq!(len, Some(u16::MAX as u64 + 3), "Wrong len for {input:X?}");
639
640            // str 32 will read second, third, fourth, & fifth bytes (u32) for size
641            let input = vec![0xdb, 0xff, 0xff, 0xff, 0xff, b'd', b'a', b't', b'a'];
642            let len = find_msgpack_byte_len(&input);
643            assert_eq!(len, Some(u32::MAX as u64 + 5), "Wrong len for {input:X?}");
644        }
645
646        #[test]
647        fn should_return_appropriate_len_if_input_is_some_bin() {
648            // bin 8 will read second byte (u8) for size
649            let input = vec![0xc4, 0xff, b'd', b'a', b't', b'a'];
650            let len = find_msgpack_byte_len(&input);
651            assert_eq!(len, Some(u8::MAX as u64 + 2), "Wrong len for {input:X?}");
652
653            // bin 16 will read second & third bytes (u16) for size
654            let input = vec![0xc5, 0xff, 0xff, b'd', b'a', b't', b'a'];
655            let len = find_msgpack_byte_len(&input);
656            assert_eq!(len, Some(u16::MAX as u64 + 3), "Wrong len for {input:X?}");
657
658            // bin 32 will read second, third, fourth, & fifth bytes (u32) for size
659            let input = vec![0xc6, 0xff, 0xff, 0xff, 0xff, b'd', b'a', b't', b'a'];
660            let len = find_msgpack_byte_len(&input);
661            assert_eq!(len, Some(u32::MAX as u64 + 5), "Wrong len for {input:X?}");
662        }
663
664        #[test]
665        fn should_return_appropriate_len_if_input_is_some_array() {
666            // fixarray has a length up to 15 objects
667            //
668            // In this example, we have an array of 3 objects that are a str, integer, and bool
669            let input = vec![0x93, 0xa3, b'a', b'b', b'c', 0xcc, 0xff, 0xc2];
670            let len = find_msgpack_byte_len(&input);
671            assert_eq!(len, Some(1 + 4 + 2 + 1), "Wrong len for {input:X?}");
672
673            // Invalid fixarray count should return none
674            let input = vec![0x93, 0xa3, b'a', b'b', b'c', 0xcc, 0xff];
675            let len = find_msgpack_byte_len(&input);
676            assert_eq!(len, None, "Wrong len for {input:X?}");
677
678            // array 16 will read second & third bytes (u16) for object length
679            //
680            // In this example, we have an array of 3 objects that are a str, integer, and bool
681            let input = vec![0xdc, 0x00, 0x03, 0xa3, b'a', b'b', b'c', 0xcc, 0xff, 0xc2];
682            let len = find_msgpack_byte_len(&input);
683            assert_eq!(len, Some(3 + 4 + 2 + 1), "Wrong len for {input:X?}");
684
685            // Invalid array 16 count should return none
686            let input = vec![0xdc, 0x00, 0x03, 0xa3, b'a', b'b', b'c', 0xcc, 0xff];
687            let len = find_msgpack_byte_len(&input);
688            assert_eq!(len, None, "Wrong len for {input:X?}");
689
690            // array 32 will read second, third, fourth, & fifth bytes (u32) for object length
691            let input = vec![
692                0xdd, 0x00, 0x00, 0x00, 0x03, 0xa3, b'a', b'b', b'c', 0xcc, 0xff, 0xc2,
693            ];
694            let len = find_msgpack_byte_len(&input);
695            assert_eq!(len, Some(5 + 4 + 2 + 1), "Wrong len for {input:X?}");
696
697            // Invalid array 32 count should return none
698            let input = vec![
699                0xdd, 0x00, 0x00, 0x00, 0x03, 0xa3, b'a', b'b', b'c', 0xcc, 0xff,
700            ];
701            let len = find_msgpack_byte_len(&input);
702            assert_eq!(len, None, "Wrong len for {input:X?}");
703        }
704
705        #[test]
706        fn should_return_appropriate_len_if_input_is_some_map() {
707            // fixmap has a length up to 2*15 objects
708            let input = vec![
709                0x83, // 3 objects /w keys
710                0x03, 0xa3, b'a', b'b', b'c', // 3 -> "abc"
711                0xa3, b'a', b'b', b'c', 0xcc, 0xff, // "abc" -> 255
712                0xc3, 0xc2, // true -> false
713            ];
714            let len = find_msgpack_byte_len(&input);
715            assert_eq!(len, Some(1 + 5 + 6 + 2), "Wrong len for {input:X?}");
716
717            // Invalid fixmap count should return none
718            let input = vec![
719                0x83, // 3 objects /w keys
720                0x03, 0xa3, b'a', b'b', b'c', // 3 -> "abc"
721                0xa3, b'a', b'b', b'c', 0xcc, 0xff, // "abc" -> 255
722                0xc3, // true -> ???
723            ];
724            let len = find_msgpack_byte_len(&input);
725            assert_eq!(len, None, "Wrong len for {input:X?}");
726
727            // map 16 will read second & third bytes (u16) for object length
728            let input = vec![
729                0xde, 0x00, 0x03, // 3 objects w/ keys
730                0x03, 0xa3, b'a', b'b', b'c', // 3 -> "abc"
731                0xa3, b'a', b'b', b'c', 0xcc, 0xff, // "abc" -> 255
732                0xc3, 0xc2, // true -> false
733            ];
734            let len = find_msgpack_byte_len(&input);
735            assert_eq!(len, Some(3 + 5 + 6 + 2), "Wrong len for {input:X?}");
736
737            // Invalid map 16 count should return none
738            let input = vec![
739                0xde, 0x00, 0x03, // 3 objects w/ keys
740                0x03, 0xa3, b'a', b'b', b'c', // 3 -> "abc"
741                0xa3, b'a', b'b', b'c', 0xcc, 0xff, // "abc" -> 255
742                0xc3, // true -> ???
743            ];
744            let len = find_msgpack_byte_len(&input);
745            assert_eq!(len, None, "Wrong len for {input:X?}");
746
747            // map 32 will read second, third, fourth, & fifth bytes (u32) for object length
748            let input = vec![
749                0xdf, 0x00, 0x00, 0x00, 0x03, // 3 objects w/ keys
750                0x03, 0xa3, b'a', b'b', b'c', // 3 -> "abc"
751                0xa3, b'a', b'b', b'c', 0xcc, 0xff, // "abc" -> 255
752                0xc3, 0xc2, // true -> false
753            ];
754            let len = find_msgpack_byte_len(&input);
755            assert_eq!(len, Some(5 + 5 + 6 + 2), "Wrong len for {input:X?}");
756
757            // Invalid map 32 count should return none
758            let input = vec![
759                0xdf, 0x00, 0x00, 0x00, 0x03, // 3 objects w/ keys
760                0x03, 0xa3, b'a', b'b', b'c', // 3 -> "abc"
761                0xa3, b'a', b'b', b'c', 0xcc, 0xff, // "abc" -> 255
762                0xc3, // true -> ???
763            ];
764            let len = find_msgpack_byte_len(&input);
765            assert_eq!(len, None, "Wrong len for {input:X?}");
766        }
767
768        #[test]
769        fn should_return_appropriate_len_if_input_is_some_ext() {
770            // fixext 1 claims single data byte (excluding type)
771            let input = vec![0xd4, 0x00, 0x12];
772            let len = find_msgpack_byte_len(&input);
773            assert_eq!(len, Some(1 + 1 + 1), "Wrong len for {input:X?}");
774
775            // fixext 2 claims two data bytes (excluding type)
776            let input = vec![0xd5, 0x00, 0x12, 0x34];
777            let len = find_msgpack_byte_len(&input);
778            assert_eq!(len, Some(1 + 1 + 2), "Wrong len for {input:X?}");
779
780            // fixext 4 claims four data bytes (excluding type)
781            let input = vec![0xd6, 0x00, 0x12, 0x34, 0x56, 0x78];
782            let len = find_msgpack_byte_len(&input);
783            assert_eq!(len, Some(1 + 1 + 4), "Wrong len for {input:X?}");
784
785            // fixext 8 claims eight data bytes (excluding type)
786            let input = vec![0xd7, 0x00, 0x12, 0x34, 0x56, 0x78];
787            let len = find_msgpack_byte_len(&input);
788            assert_eq!(len, Some(1 + 1 + 8), "Wrong len for {input:X?}");
789
790            // fixext 16 claims sixteen data bytes (excluding type)
791            let input = vec![0xd8, 0x00, 0x12, 0x34, 0x56, 0x78];
792            let len = find_msgpack_byte_len(&input);
793            assert_eq!(len, Some(1 + 1 + 16), "Wrong len for {input:X?}");
794
795            // ext 8 will read second byte (u8) for size (excluding type)
796            let input = vec![0xc7, 0xff, 0x00, b'd', b'a', b't', b'a'];
797            let len = find_msgpack_byte_len(&input);
798            assert_eq!(len, Some(u8::MAX as u64 + 3), "Wrong len for {input:X?}");
799
800            // ext 16 will read second & third bytes (u16) for size (excluding type)
801            let input = vec![0xc8, 0xff, 0xff, 0x00, b'd', b'a', b't', b'a'];
802            let len = find_msgpack_byte_len(&input);
803            assert_eq!(len, Some(u16::MAX as u64 + 4), "Wrong len for {input:X?}");
804
805            // ext 32 will read second, third, fourth, & fifth bytes (u32) for size (excluding type)
806            let input = vec![0xc9, 0xff, 0xff, 0xff, 0xff, 0x00, b'd', b'a', b't', b'a'];
807            let len = find_msgpack_byte_len(&input);
808            assert_eq!(len, Some(u32::MAX as u64 + 6), "Wrong len for {input:X?}");
809        }
810    }
811}