libdd_trace_utils/msgpack_decoder/decode/
span_link.rs1use crate::msgpack_decoder::decode::error::DecodeError;
5use crate::msgpack_decoder::decode::number::read_number_slice;
6use crate::msgpack_decoder::decode::string::{
7 handle_null_marker, read_str_map_to_strings, read_string_ref,
8};
9use crate::span::SpanLinkSlice;
10use std::str::FromStr;
11
12pub(crate) fn read_span_links<'a>(
30 buf: &mut &'a [u8],
31) -> Result<Vec<SpanLinkSlice<'a>>, DecodeError> {
32 if handle_null_marker(buf) {
33 return Ok(Vec::default());
34 }
35
36 let len = rmp::decode::read_array_len(buf).map_err(|_| {
37 DecodeError::InvalidType("Unable to get array len for span links".to_owned())
38 })?;
39
40 let mut vec: Vec<SpanLinkSlice> = Vec::with_capacity(len as usize);
41 for _ in 0..len {
42 vec.push(decode_span_link(buf)?);
43 }
44 Ok(vec)
45}
46#[derive(Debug, PartialEq)]
47enum SpanLinkKey {
48 TraceId,
49 TraceIdHigh,
50 SpanId,
51 Attributes,
52 Tracestate,
53 Flags,
54}
55
56impl FromStr for SpanLinkKey {
57 type Err = DecodeError;
58
59 fn from_str(s: &str) -> Result<Self, Self::Err> {
60 match s {
61 "trace_id" => Ok(SpanLinkKey::TraceId),
62 "trace_id_high" => Ok(SpanLinkKey::TraceIdHigh),
63 "span_id" => Ok(SpanLinkKey::SpanId),
64 "attributes" => Ok(SpanLinkKey::Attributes),
65 "tracestate" => Ok(SpanLinkKey::Tracestate),
66 "flags" => Ok(SpanLinkKey::Flags),
67 _ => Err(DecodeError::InvalidFormat(
68 format!("Invalid span link key: {s}").to_owned(),
69 )),
70 }
71 }
72}
73
74fn decode_span_link<'a>(buf: &mut &'a [u8]) -> Result<SpanLinkSlice<'a>, DecodeError> {
75 let mut span = SpanLinkSlice::default();
76 let span_size = rmp::decode::read_map_len(buf)
77 .map_err(|_| DecodeError::InvalidType("Unable to get map len for span size".to_owned()))?;
78
79 for _ in 0..span_size {
80 match read_string_ref(buf)?.parse::<SpanLinkKey>()? {
81 SpanLinkKey::TraceId => span.trace_id = read_number_slice(buf)?,
82 SpanLinkKey::TraceIdHigh => span.trace_id_high = read_number_slice(buf)?,
83 SpanLinkKey::SpanId => span.span_id = read_number_slice(buf)?,
84 SpanLinkKey::Attributes => span.attributes = read_str_map_to_strings(buf)?,
85 SpanLinkKey::Tracestate => span.tracestate = read_string_ref(buf)?,
86 SpanLinkKey::Flags => span.flags = read_number_slice(buf)?,
87 }
88 }
89
90 Ok(span)
91}
92
93#[cfg(test)]
94mod tests {
95 use super::SpanLinkKey;
96 use crate::msgpack_decoder::decode::error::DecodeError;
97 use std::str::FromStr;
98
99 #[test]
100 fn test_span_link_key_from_str() {
101 assert_eq!(
103 SpanLinkKey::from_str("trace_id").unwrap(),
104 SpanLinkKey::TraceId
105 );
106 assert_eq!(
107 SpanLinkKey::from_str("trace_id_high").unwrap(),
108 SpanLinkKey::TraceIdHigh
109 );
110 assert_eq!(
111 SpanLinkKey::from_str("span_id").unwrap(),
112 SpanLinkKey::SpanId
113 );
114 assert_eq!(
115 SpanLinkKey::from_str("attributes").unwrap(),
116 SpanLinkKey::Attributes
117 );
118 assert_eq!(
119 SpanLinkKey::from_str("tracestate").unwrap(),
120 SpanLinkKey::Tracestate
121 );
122 assert_eq!(SpanLinkKey::from_str("flags").unwrap(), SpanLinkKey::Flags);
123
124 assert!(matches!(
126 SpanLinkKey::from_str("invalid_key"),
127 Err(DecodeError::InvalidFormat(_))
128 ));
129 }
130}