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