libdd_trace_utils/msgpack_decoder/decode/
meta_struct.rs1use crate::msgpack_decoder::decode::error::DecodeError;
5use crate::msgpack_decoder::decode::map::{read_map, read_map_len};
6use crate::msgpack_decoder::decode::string::{handle_null_marker, read_string_ref};
7use libdd_tinybytes::Bytes;
8use rmp::decode;
9use std::collections::HashMap;
10
11fn read_byte_array_len(buf: &mut &[u8]) -> Result<u32, DecodeError> {
12 decode::read_bin_len(buf).map_err(|_| {
13 DecodeError::InvalidFormat("Unable to read binary len for meta_struct".to_owned())
14 })
15}
16
17#[inline]
18pub fn read_meta_struct<'a>(buf: &mut &'a [u8]) -> Result<HashMap<&'a str, Bytes>, DecodeError> {
19 if handle_null_marker(buf) {
20 return Ok(HashMap::default());
21 }
22
23 fn read_meta_struct_pair<'a>(buf: &mut &'a [u8]) -> Result<(&'a str, Bytes), DecodeError> {
24 let key = read_string_ref(buf)?;
25 let byte_array_len = read_byte_array_len(buf)? as usize;
26
27 let slice = buf.get(0..byte_array_len);
28 if let Some(slice) = slice {
29 let data = Bytes::copy_from_slice(slice);
30 *buf = &buf[byte_array_len..];
31 Ok((key, data))
32 } else {
33 Err(DecodeError::InvalidFormat(
34 "Invalid data length".to_string(),
35 ))
36 }
37 }
38
39 let len = read_map_len(buf)?;
40 read_map(len, buf, read_meta_struct_pair)
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn read_meta_test() {
49 let meta = HashMap::from([("key".to_string(), Bytes::from(vec![1, 2, 3, 4]))]);
50
51 let serialized = rmp_serde::to_vec_named(&meta).unwrap();
52 let mut slice = serialized.as_ref();
53 let res = read_meta_struct(&mut slice).unwrap();
54
55 assert_eq!(res.get("key").unwrap().to_vec(), vec![1, 2, 3, 4]);
56 }
57
58 #[test]
59 fn read_meta_wrong_family_test() {
60 let meta = HashMap::from([("key".to_string(), vec![1, 2, 3, 4])]);
61
62 let serialized = rmp_serde::to_vec_named(&meta).unwrap();
63 let mut slice = serialized.as_ref();
64 let res = read_meta_struct(&mut slice);
65
66 assert!(res.is_err());
67 matches!(res.unwrap_err(), DecodeError::InvalidFormat(_));
68 }
69}