Skip to main content

libdd_trace_utils/msgpack_decoder/v04/
mod.rs

1// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
2// SPDX-License-Identifier: Apache-2.0
3
4pub(crate) mod span;
5
6use self::span::decode_span;
7use crate::msgpack_decoder::decode::buffer::Buffer;
8use crate::msgpack_decoder::decode::error::DecodeError;
9use crate::span::v04::{Span, SpanBytes, SpanSlice};
10use crate::span::DeserializableTraceData;
11
12/// Decodes a Bytes buffer into a `Vec<Vec<SpanBytes>>` object, also represented as a vector of
13/// `TracerPayloadV04` objects.
14///
15/// # Arguments
16///
17/// * `data` - A tinybytes Bytes buffer containing the encoded data. Bytes are expected to be
18///   encoded msgpack data containing a list of a list of v04 spans.
19///
20/// # Returns
21///
22/// * `Ok(Vec<TracerPayloadV04>, usize)` - A vector of decoded `Vec<SpanSlice>` objects if
23///   successful. and the number of bytes in the slice used by the decoder.
24/// * `Err(DecodeError)` - An error if the decoding process fails.
25///
26/// # Errors
27///
28/// This function will return an error if:
29/// - The array length for trace count or span count cannot be read.
30/// - Any span cannot be decoded.
31///
32/// # Examples
33///
34/// ```
35/// use libdd_tinybytes;
36/// use libdd_trace_protobuf::pb::Span;
37/// use libdd_trace_utils::msgpack_decoder::v04::from_bytes;
38/// use rmp_serde::to_vec_named;
39///
40/// let span = Span {
41///     name: "test-span".to_owned(),
42///     ..Default::default()
43/// };
44/// let encoded_data = to_vec_named(&vec![vec![span]]).unwrap();
45/// let encoded_data_as_tinybytes = libdd_tinybytes::Bytes::from(encoded_data);
46/// let (decoded_traces, _payload_size) =
47///     from_bytes(encoded_data_as_tinybytes).expect("Decoding failed");
48///
49/// assert_eq!(1, decoded_traces.len());
50/// assert_eq!(1, decoded_traces[0].len());
51/// let decoded_span = &decoded_traces[0][0];
52/// assert_eq!("test-span", decoded_span.name.as_str());
53/// ```
54pub fn from_bytes(
55    data: libdd_tinybytes::Bytes,
56) -> Result<(Vec<Vec<SpanBytes>>, usize), DecodeError> {
57    from_buffer(&mut Buffer::new(data))
58}
59
60/// Decodes a slice of bytes into a `Vec<Vec<SpanSlice>>` object.
61/// The resulting spans have the same lifetime as the initial buffer.
62///
63/// # Arguments
64///
65/// * `data` - A slice of bytes containing the encoded data. Bytes are expected to be encoded
66///   msgpack data containing a list of a list of v04 spans.
67///
68/// # Returns
69///
70/// * `Ok(Vec<TracerPayloadV04>, usize)` - A vector of decoded `Vec<SpanSlice>` objects if
71///   successful. and the number of bytes in the slice used by the decoder.
72/// * `Err(DecodeError)` - An error if the decoding process fails.
73///
74/// # Errors
75///
76/// This function will return an error if:
77/// - The array length for trace count or span count cannot be read.
78/// - Any span cannot be decoded.
79///
80/// # Examples
81///
82/// ```
83/// use libdd_tinybytes;
84/// use libdd_trace_protobuf::pb::Span;
85/// use libdd_trace_utils::msgpack_decoder::v04::from_slice;
86/// use rmp_serde::to_vec_named;
87///
88/// let span = Span {
89///     name: "test-span".to_owned(),
90///     ..Default::default()
91/// };
92/// let encoded_data = to_vec_named(&vec![vec![span]]).unwrap();
93/// let encoded_data_as_tinybytes = libdd_tinybytes::Bytes::from(encoded_data);
94/// let (decoded_traces, _payload_size) =
95///     from_slice(&encoded_data_as_tinybytes).expect("Decoding failed");
96///
97/// assert_eq!(1, decoded_traces.len());
98/// assert_eq!(1, decoded_traces[0].len());
99/// let decoded_span = &decoded_traces[0][0];
100/// assert_eq!("test-span", decoded_span.name);
101/// ```
102pub fn from_slice(data: &[u8]) -> Result<(Vec<Vec<SpanSlice<'_>>>, usize), DecodeError> {
103    from_buffer(&mut Buffer::new(data))
104}
105
106#[allow(clippy::type_complexity)]
107pub fn from_buffer<T: DeserializableTraceData>(
108    data: &mut Buffer<T>,
109) -> Result<(Vec<Vec<Span<T>>>, usize), DecodeError> {
110    let trace_count = rmp::decode::read_array_len(data.as_mut_slice()).map_err(|_| {
111        DecodeError::InvalidFormat("Unable to read array len for trace count".to_owned())
112    })?;
113
114    // Intentionally skip the size of the array (as it will be recomputed after coalescing).
115    let start_len = data.len();
116
117    #[allow(clippy::expect_used)]
118    Ok((
119        (0..trace_count).try_fold(
120            Vec::with_capacity(
121                trace_count
122                    .try_into()
123                    .expect("Unable to cast trace_count to usize"),
124            ),
125            |mut traces, _| {
126                let span_count =
127                    rmp::decode::read_array_len(data.as_mut_slice()).map_err(|_| {
128                        DecodeError::InvalidFormat(
129                            "Unable to read array len for span count".to_owned(),
130                        )
131                    })?;
132
133                let trace = (0..span_count).try_fold(
134                    Vec::with_capacity(
135                        span_count
136                            .try_into()
137                            .expect("Unable to cast span_count to usize"),
138                    ),
139                    |mut trace, _| {
140                        let span = decode_span(data)?;
141                        trace.push(span);
142                        Ok(trace)
143                    },
144                )?;
145
146                traces.push(trace);
147
148                Ok(traces)
149            },
150        )?,
151        start_len - data.len(),
152    ))
153}
154
155#[cfg(test)]
156mod tests {
157    use super::*;
158    use crate::test_utils::{create_test_json_span, create_test_no_alloc_span};
159    use bolero::check;
160    use libdd_tinybytes::{Bytes, BytesString};
161    use rmp_serde;
162    use rmp_serde::to_vec_named;
163    use serde_json::json;
164    use std::collections::HashMap;
165
166    #[test]
167    fn test_empty_array() {
168        let encoded_data = vec![0x90];
169        let slice = encoded_data.as_ref();
170        let (_decoded_traces, decoded_size) = from_slice(slice).expect("Decoding failed");
171
172        assert_eq!(0, decoded_size);
173    }
174
175    #[test]
176    fn test_decoder_size() {
177        let span = SpanBytes {
178            name: BytesString::from_slice("span_name".as_ref()).unwrap(),
179            ..Default::default()
180        };
181        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
182        let expected_size = encoded_data.len() - 1; // rmp_serde adds additional 0 byte
183        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
184        let (_decoded_traces, decoded_size) =
185            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
186
187        assert_eq!(expected_size, decoded_size);
188    }
189
190    #[test]
191    fn test_decoder_read_string_success() {
192        let expected_string = "test-service-name";
193        let span = SpanBytes {
194            name: BytesString::from_slice(expected_string.as_ref()).unwrap(),
195            ..Default::default()
196        };
197        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
198        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
199        let (decoded_traces, _) =
200            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
201
202        assert_eq!(1, decoded_traces.len());
203        assert_eq!(1, decoded_traces[0].len());
204        let decoded_span = &decoded_traces[0][0];
205        assert_eq!(expected_string, decoded_span.name.as_str());
206    }
207
208    #[test]
209    fn test_decoder_read_null_string_success() {
210        let mut span = create_test_json_span(1, 2, 0, 0, false);
211        span["name"] = json!(null);
212        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
213        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
214        let (decoded_traces, _) =
215            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
216
217        assert_eq!(1, decoded_traces.len());
218        assert_eq!(1, decoded_traces[0].len());
219        let decoded_span = &decoded_traces[0][0];
220        assert_eq!("", decoded_span.name.as_str());
221    }
222
223    #[test]
224    fn test_decoder_read_number_success() {
225        let span = create_test_json_span(1, 2, 0, 0, false);
226        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
227        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
228        let (decoded_traces, _) =
229            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
230
231        assert_eq!(1, decoded_traces.len());
232        assert_eq!(1, decoded_traces[0].len());
233        let decoded_span = &decoded_traces[0][0];
234        assert_eq!(1, decoded_span.trace_id);
235    }
236
237    #[test]
238    fn test_decoder_read_null_number_success() {
239        let mut span = create_test_json_span(1, 2, 0, 0, false);
240        span["trace_id"] = json!(null);
241        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
242        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
243        let (decoded_traces, _) =
244            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
245
246        assert_eq!(1, decoded_traces.len());
247        assert_eq!(1, decoded_traces[0].len());
248        let decoded_span = &decoded_traces[0][0];
249        assert_eq!(0, decoded_span.trace_id);
250    }
251
252    #[test]
253    fn test_decoder_meta_struct_null_map_success() {
254        let mut span = create_test_json_span(1, 2, 0, 0, false);
255        span["meta_struct"] = json!(null);
256
257        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
258        let (decoded_traces, _) =
259            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
260
261        assert_eq!(1, decoded_traces.len());
262        assert_eq!(1, decoded_traces[0].len());
263        let decoded_span = &decoded_traces[0][0];
264
265        assert!(decoded_span.meta_struct.is_empty());
266    }
267
268    #[test]
269    fn test_decoder_meta_struct_success() {
270        let data = vec![1, 2, 3, 4];
271        let mut span = create_test_no_alloc_span(1, 2, 0, 0, false);
272        span.meta_struct = vec![(BytesString::from("meta_key"), Bytes::from(data.clone()))].into();
273
274        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
275        let (decoded_traces, _) =
276            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
277
278        assert_eq!(1, decoded_traces.len());
279        assert_eq!(1, decoded_traces[0].len());
280        let decoded_span = &decoded_traces[0][0];
281
282        assert_eq!(
283            decoded_span.meta_struct.get("meta_key").unwrap().to_vec(),
284            data
285        );
286    }
287
288    #[test]
289    fn test_decoder_meta_fixed_map_success() {
290        let expected_meta = HashMap::from([
291            ("key1".to_string(), "value1".to_string()),
292            ("key2".to_string(), "value2".to_string()),
293        ]);
294
295        let mut span = create_test_json_span(1, 2, 0, 0, false);
296        span["meta"] = json!(expected_meta.clone());
297
298        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
299        let (decoded_traces, _) =
300            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
301
302        assert_eq!(1, decoded_traces.len());
303        assert_eq!(1, decoded_traces[0].len());
304        let decoded_span = &decoded_traces[0][0];
305
306        for (key, value) in expected_meta.iter() {
307            let bs_key = BytesString::from_slice(key.as_ref()).unwrap();
308            assert_eq!(value, &decoded_span.meta.get(&bs_key).unwrap().as_str());
309        }
310    }
311
312    #[test]
313    fn test_decoder_meta_null_map_success() {
314        let mut span = create_test_json_span(1, 2, 0, 0, false);
315        span["meta"] = json!(null);
316
317        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
318        let (decoded_traces, _) =
319            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
320
321        assert_eq!(1, decoded_traces.len());
322        assert_eq!(1, decoded_traces[0].len());
323        let decoded_span = &decoded_traces[0][0];
324
325        assert!(decoded_span.meta.is_empty());
326    }
327
328    #[test]
329    fn test_decoder_meta_map_16_success() {
330        let expected_meta: HashMap<String, String> = (0..20)
331            .map(|i| {
332                (
333                    format!("key {i}").to_owned(),
334                    format!("value {i}").to_owned(),
335                )
336            })
337            .collect();
338
339        let mut span = create_test_json_span(1, 2, 0, 0, false);
340        span["meta"] = json!(expected_meta.clone());
341
342        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
343        let (decoded_traces, _) =
344            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
345
346        assert_eq!(1, decoded_traces.len());
347        assert_eq!(1, decoded_traces[0].len());
348        let decoded_span = &decoded_traces[0][0];
349
350        for (key, value) in expected_meta.iter() {
351            let bs_key = BytesString::from_slice(key.as_ref()).unwrap();
352            assert_eq!(value, &decoded_span.meta.get(&bs_key).unwrap().as_str());
353        }
354    }
355
356    #[test]
357    fn test_decoder_metrics_fixed_map_success() {
358        let expected_metrics = HashMap::from([("metric1", 1.23), ("metric2", 4.56)]);
359
360        let mut span = create_test_json_span(1, 2, 0, 0, false);
361        span["metrics"] = json!(expected_metrics.clone());
362        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
363        let (decoded_traces, _) =
364            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
365
366        assert_eq!(1, decoded_traces.len());
367        assert_eq!(1, decoded_traces[0].len());
368        let decoded_span = &decoded_traces[0][0];
369
370        for (key, value) in expected_metrics.iter() {
371            let bs_key = BytesString::from_slice(key.as_ref()).unwrap();
372            assert_eq!(value, decoded_span.metrics.get(&bs_key).unwrap());
373        }
374    }
375
376    #[test]
377    fn test_decoder_metrics_map16_success() {
378        let expected_metrics: HashMap<String, f64> =
379            (0..20).map(|i| (format!("metric{i}"), i as f64)).collect();
380
381        let mut span = create_test_json_span(1, 2, 0, 0, false);
382        span["metrics"] = json!(expected_metrics.clone());
383        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
384        let (decoded_traces, _) =
385            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
386
387        assert_eq!(1, decoded_traces.len());
388        assert_eq!(1, decoded_traces[0].len());
389        let decoded_span = &decoded_traces[0][0];
390
391        for (key, value) in expected_metrics.iter() {
392            let bs_key = BytesString::from_slice(key.as_ref()).unwrap();
393            assert_eq!(value, decoded_span.metrics.get(&bs_key).unwrap());
394        }
395    }
396
397    #[test]
398    fn test_decoder_metrics_null_success() {
399        let mut span = create_test_json_span(1, 2, 0, 0, false);
400        span["metrics"] = json!(null);
401        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
402        let (decoded_traces, _) =
403            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
404
405        assert_eq!(1, decoded_traces.len());
406        assert_eq!(1, decoded_traces[0].len());
407        let decoded_span = &decoded_traces[0][0];
408        assert!(decoded_span.metrics.is_empty());
409    }
410
411    #[test]
412    fn test_decoded_span_maps_are_marked_deduped() {
413        // A decoded span's maps must be flagged deduped so the encoder skips the defensive dedup
414        // (and its warning) when re-encoding (e.g. in the sidecar).
415        let mut span = create_test_json_span(1, 2, 0, 0, false);
416        span["meta"] = json!({ "key": "value" });
417        span["metrics"] = json!({ "metric": 1.0 });
418        // No meta_struct on the wire: it stays at its empty `Span::default()` value.
419
420        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
421        let (decoded_traces, _) =
422            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
423
424        let decoded_span = &decoded_traces[0][0];
425        assert!(decoded_span.meta.is_deduped(), "meta should be deduped");
426        assert!(
427            decoded_span.metrics.is_deduped(),
428            "metrics should be deduped"
429        );
430        assert!(
431            decoded_span.meta_struct.is_deduped(),
432            "empty meta_struct should be deduped"
433        );
434    }
435
436    #[test]
437    fn test_decoder_span_link_success() {
438        let expected_span_link = json!({
439            "trace_id": 1,
440            "trace_id_high": 0,
441            "span_id": 1,
442            "attributes": {
443                "attr1": "test_value",
444                "attr2": "test_value2"
445            },
446            "tracestate": "state_test",
447            "flags": 0b101
448        });
449
450        let mut span = create_test_json_span(1, 2, 0, 0, false);
451        span["span_links"] = json!([expected_span_link]);
452
453        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
454        let (decoded_traces, _) =
455            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
456
457        assert_eq!(1, decoded_traces.len());
458        assert_eq!(1, decoded_traces[0].len());
459        let decoded_span = &decoded_traces[0][0];
460
461        assert_eq!(
462            expected_span_link["trace_id"],
463            decoded_span.span_links[0].trace_id
464        );
465        assert_eq!(
466            expected_span_link["trace_id_high"],
467            decoded_span.span_links[0].trace_id_high
468        );
469        assert_eq!(
470            expected_span_link["span_id"],
471            decoded_span.span_links[0].span_id
472        );
473        assert_eq!(
474            expected_span_link["tracestate"],
475            decoded_span.span_links[0].tracestate.as_str()
476        );
477        assert_eq!(
478            expected_span_link["flags"],
479            decoded_span.span_links[0].flags
480        );
481        assert_eq!(
482            expected_span_link["attributes"]["attr1"],
483            decoded_span.span_links[0].attributes
484                [&BytesString::from_slice("attr1".as_ref()).unwrap()]
485                .as_str()
486        );
487        assert_eq!(
488            expected_span_link["attributes"]["attr2"],
489            decoded_span.span_links[0].attributes
490                [&BytesString::from_slice("attr2".as_ref()).unwrap()]
491                .as_str()
492        );
493    }
494
495    #[test]
496    fn test_decoder_null_span_link_success() {
497        let mut span = create_test_json_span(1, 2, 0, 0, false);
498        span["span_links"] = json!(null);
499
500        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
501        let (decoded_traces, _) =
502            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
503
504        assert_eq!(1, decoded_traces.len());
505        assert_eq!(1, decoded_traces[0].len());
506        let decoded_span = &decoded_traces[0][0];
507
508        assert!(decoded_span.span_links.is_empty());
509    }
510
511    #[test]
512    fn test_decoder_meta_with_null_values() {
513        let mut span = create_test_json_span(1, 2, 0, 0, false);
514        span["meta"] = json!({
515            "key1": "value1",
516            "key2": null,  // This null value should be skipped
517            "key3": "value3"
518        });
519
520        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
521        let (decoded_traces, _) =
522            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
523
524        assert_eq!(1, decoded_traces.len());
525        assert_eq!(1, decoded_traces[0].len());
526        let decoded_span = &decoded_traces[0][0];
527
528        let key1 = BytesString::from_slice("key1".as_ref()).unwrap();
529        let key2 = BytesString::from_slice("key2".as_ref()).unwrap();
530        let key3 = BytesString::from_slice("key3".as_ref()).unwrap();
531        assert_eq!("value1", decoded_span.meta.get(&key1).unwrap().as_str());
532        assert!(
533            !decoded_span.meta.contains_key(&key2),
534            "Null value should be skipped, but key was present"
535        );
536        assert_eq!("value3", decoded_span.meta.get(&key3).unwrap().as_str());
537    }
538
539    #[test]
540    fn test_decoder_read_string_wrong_format() {
541        let span = SpanBytes {
542            service: BytesString::from_slice("my_service".as_ref()).unwrap(),
543            ..Default::default()
544        };
545        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
546        // This changes the map size from 11 to 12 to trigger an InvalidMarkerRead error.
547        encoded_data[2] = 0x8c;
548        let slice = encoded_data.as_ref();
549
550        let result = from_slice(slice);
551        assert_eq!(
552            Err(DecodeError::InvalidFormat(
553                "Expected at least bytes 1, but only got 0 (pos 0)".to_owned()
554            )),
555            result
556        );
557    }
558
559    #[test]
560    fn test_decoder_read_string_utf8_error() {
561        let invalid_seq = vec![0, 159, 146, 150];
562        let invalid_str = unsafe { String::from_utf8_unchecked(invalid_seq) };
563        let invalid_str_as_bytes = libdd_tinybytes::Bytes::from(invalid_str);
564        let span = SpanBytes {
565            name: unsafe { BytesString::from_bytes_unchecked(invalid_str_as_bytes) },
566            ..Default::default()
567        };
568        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
569        let slice = encoded_data.as_ref();
570
571        let result = from_slice(slice);
572        assert_eq!(
573            Err(DecodeError::Utf8Error(
574                "invalid utf-8 sequence of 1 bytes from index 1".to_owned()
575            )),
576            result
577        );
578    }
579
580    #[test]
581    fn test_decoder_invalid_marker_for_trace_count_read() {
582        let span = SpanBytes::default();
583        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
584        // This changes the entire payload to a map with 12 keys in order to trigger an error when
585        // reading the array len of traces
586        encoded_data[0] = 0x8c;
587        let slice = encoded_data.as_ref();
588
589        let result = from_slice(slice);
590        assert_eq!(
591            Err(DecodeError::InvalidFormat(
592                "Unable to read array len for trace count".to_string()
593            )),
594            result
595        );
596    }
597
598    #[test]
599    fn test_decoder_invalid_marker_for_span_count_read() {
600        let span = SpanBytes::default();
601        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
602        // This changes the entire payload to a map with 12 keys in order to trigger an error when
603        // reading the array len of spans
604        encoded_data[1] = 0x8c;
605        let slice = encoded_data.as_ref();
606
607        let result = from_slice(slice);
608        assert_eq!(
609            Err(DecodeError::InvalidFormat(
610                "Unable to read array len for span count".to_owned()
611            )),
612            result
613        );
614    }
615
616    #[test]
617    fn test_decoder_read_string_type_mismatch() {
618        let span = SpanBytes::default();
619        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
620        // Modify the encoded data to cause a type mismatch by changing the marker for the `name`
621        // field to an integer marker
622        encoded_data[3] = 0x01;
623        let slice = encoded_data.as_ref();
624
625        let result = from_slice(slice);
626        assert_eq!(
627            Err(DecodeError::InvalidType(
628                "Type mismatch at marker FixPos(1)".to_owned()
629            )),
630            result
631        );
632    }
633
634    #[test]
635    #[cfg_attr(miri, ignore)]
636    fn fuzz_from_bytes() {
637        check!()
638            .with_type::<(
639                String,
640                String,
641                String,
642                String,
643                String,
644                String,
645                String,
646                String,
647                u64,
648                u64,
649                u64,
650                i64,
651            )>()
652            .cloned()
653            .for_each(
654                |(
655                    name,
656                    service,
657                    resource,
658                    span_type,
659                    meta_key,
660                    meta_value,
661                    metric_key,
662                    metric_value,
663                    trace_id,
664                    span_id,
665                    parent_id,
666                    start,
667                )| {
668                    let span = SpanBytes {
669                        name: BytesString::from_slice(name.as_ref()).unwrap(),
670                        service: BytesString::from_slice(service.as_ref()).unwrap(),
671                        resource: BytesString::from_slice(resource.as_ref()).unwrap(),
672                        r#type: BytesString::from_slice(span_type.as_ref()).unwrap(),
673                        meta: vec![(
674                            BytesString::from_slice(meta_key.as_ref()).unwrap(),
675                            BytesString::from_slice(meta_value.as_ref()).unwrap(),
676                        )]
677                        .into(),
678                        metrics: vec![(
679                            BytesString::from_slice(metric_key.as_ref()).unwrap(),
680                            metric_value.parse::<f64>().unwrap_or_default(),
681                        )]
682                        .into(),
683                        trace_id: trace_id as u128,
684                        span_id,
685                        parent_id,
686                        start,
687                        ..Default::default()
688                    };
689                    let encoded_data = to_vec_named(&vec![vec![span]]).unwrap();
690                    let result = from_bytes(libdd_tinybytes::Bytes::from(encoded_data));
691
692                    assert!(result.is_ok());
693                },
694            );
695    }
696}