Skip to main content

libdd_trace_utils/msgpack_decoder/decode/
meta_struct.rs

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