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_len, read_map_vec};
7use crate::msgpack_decoder::decode::string::handle_null_marker;
8use crate::span::vec_map::VecMap;
9use crate::span::DeserializableTraceData;
10use rmp::decode;
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<VecMap<T::Text, T::Bytes>, DecodeError> {
24    if handle_null_marker(buf) {
25        return Ok(VecMap::new());
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_vec(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    use std::collections::HashMap;
53
54    #[test]
55    fn read_meta_test() {
56        let meta = HashMap::from([("key".to_string(), Bytes::from(vec![1, 2, 3, 4]))]);
57
58        let serialized = rmp_serde::to_vec_named(&meta).unwrap();
59        let mut slice = Buffer::<SliceData>::new(serialized.as_ref());
60        let res = read_meta_struct(&mut slice).unwrap();
61
62        let val = res.iter().find(|(k, _)| *k == "key").map(|(_, v)| v);
63        assert_eq!(val.unwrap().to_vec(), vec![1, 2, 3, 4]);
64    }
65
66    #[test]
67    fn read_meta_wrong_family_test() {
68        let meta = HashMap::from([("key".to_string(), vec![1, 2, 3, 4])]);
69
70        let serialized = rmp_serde::to_vec_named(&meta).unwrap();
71        let mut slice = Buffer::<SliceData>::new(serialized.as_ref());
72        let res = read_meta_struct(&mut slice);
73
74        assert!(res.is_err());
75        matches!(res.unwrap_err(), DecodeError::InvalidFormat(_));
76    }
77}