libdd_trace_utils/msgpack_decoder/decode/
span_event.rs1use crate::msgpack_decoder::decode::error::DecodeError;
5use crate::msgpack_decoder::decode::number::read_number_slice;
6use crate::msgpack_decoder::decode::string::{handle_null_marker, read_string_ref};
7use crate::span::{AttributeAnyValueSlice, AttributeArrayValueSlice, SpanEventSlice};
8use std::collections::HashMap;
9use std::str::FromStr;
10
11pub(crate) fn read_span_events<'a>(
28 buf: &mut &'a [u8],
29) -> Result<Vec<SpanEventSlice<'a>>, DecodeError> {
30 if handle_null_marker(buf) {
31 return Ok(Vec::default());
32 }
33
34 let len = rmp::decode::read_array_len(buf).map_err(|_| {
35 DecodeError::InvalidType("Unable to get array len for span events".to_owned())
36 })?;
37
38 let mut vec: Vec<SpanEventSlice> = Vec::with_capacity(len as usize);
39 for _ in 0..len {
40 vec.push(decode_span_event(buf)?);
41 }
42 Ok(vec)
43}
44#[derive(Debug, PartialEq)]
45enum SpanEventKey {
46 TimeUnixNano,
47 Name,
48 Attributes,
49}
50
51impl FromStr for SpanEventKey {
52 type Err = DecodeError;
53
54 fn from_str(s: &str) -> Result<Self, Self::Err> {
55 match s {
56 "time_unix_nano" => Ok(SpanEventKey::TimeUnixNano),
57 "name" => Ok(SpanEventKey::Name),
58 "attributes" => Ok(SpanEventKey::Attributes),
59 _ => Err(DecodeError::InvalidFormat(
60 format!("Invalid span event key: {s}").to_owned(),
61 )),
62 }
63 }
64}
65
66fn decode_span_event<'a>(buf: &mut &'a [u8]) -> Result<SpanEventSlice<'a>, DecodeError> {
67 let mut event = SpanEventSlice::default();
68 let event_size = rmp::decode::read_map_len(buf)
69 .map_err(|_| DecodeError::InvalidType("Unable to get map len for event size".to_owned()))?;
70
71 for _ in 0..event_size {
72 match read_string_ref(buf)?.parse::<SpanEventKey>()? {
73 SpanEventKey::TimeUnixNano => event.time_unix_nano = read_number_slice(buf)?,
74 SpanEventKey::Name => event.name = read_string_ref(buf)?,
75 SpanEventKey::Attributes => event.attributes = read_attributes_map(buf)?,
76 }
77 }
78
79 Ok(event)
80}
81
82fn read_attributes_map<'a>(
83 buf: &mut &'a [u8],
84) -> Result<HashMap<&'a str, AttributeAnyValueSlice<'a>>, DecodeError> {
85 let len = rmp::decode::read_map_len(buf)
86 .map_err(|_| DecodeError::InvalidType("Unable to get map len for attributes".to_owned()))?;
87
88 #[allow(clippy::expect_used)]
89 let mut map = HashMap::with_capacity(len.try_into().expect("Unable to cast map len to usize"));
90 for _ in 0..len {
91 let key = read_string_ref(buf)?;
92 let value = decode_attribute_any(buf)?;
93 map.insert(key, value);
94 }
95
96 Ok(map)
97}
98
99#[derive(Debug, PartialEq)]
100enum AttributeAnyKey {
101 Type,
102 SingleValue(AttributeArrayKey),
103 ArrayValue,
104}
105
106impl FromStr for AttributeAnyKey {
107 type Err = DecodeError;
108
109 fn from_str(s: &str) -> Result<Self, Self::Err> {
110 match s {
111 "type" => Ok(AttributeAnyKey::Type),
112 "array_value" => Ok(AttributeAnyKey::ArrayValue),
113 s => {
114 let r = AttributeArrayKey::from_str(s);
115 match r {
116 Ok(key) => Ok(AttributeAnyKey::SingleValue(key)),
117 Err(e) => Err(e),
118 }
119 }
120 }
121 }
122}
123
124fn decode_attribute_any<'a>(buf: &mut &'a [u8]) -> Result<AttributeAnyValueSlice<'a>, DecodeError> {
125 let mut attribute: Option<AttributeAnyValueSlice> = None;
126 let attribute_size = rmp::decode::read_map_len(buf).map_err(|_| {
127 DecodeError::InvalidType("Unable to get map len for attribute size".to_owned())
128 })?;
129
130 if attribute_size != 2 {
131 return Err(DecodeError::InvalidFormat(
132 "Invalid number of field for an attribute".to_owned(),
133 ));
134 }
135 let mut attribute_type: Option<u8> = None;
136
137 for _ in 0..attribute_size {
138 match read_string_ref(buf)?.parse::<AttributeAnyKey>()? {
139 AttributeAnyKey::Type => attribute_type = Some(read_number_slice(buf)?),
140 AttributeAnyKey::SingleValue(key) => {
141 attribute = Some(AttributeAnyValueSlice::SingleValue(get_attribute_from_key(
142 buf, key,
143 )?))
144 }
145 AttributeAnyKey::ArrayValue => {
146 attribute = Some(AttributeAnyValueSlice::Array(read_attributes_array(buf)?))
147 }
148 }
149 }
150
151 if let Some(value) = attribute {
152 if let Some(attribute_type) = attribute_type {
153 let value_type: u8 = (&value).into();
154 if attribute_type == value_type {
155 Ok(value)
156 } else {
157 Err(DecodeError::InvalidFormat(
158 "No type for attribute".to_owned(),
159 ))
160 }
161 } else {
162 Err(DecodeError::InvalidType(
163 "Type mismatch for attribute".to_owned(),
164 ))
165 }
166 } else {
167 Err(DecodeError::InvalidFormat("Invalid attribute".to_owned()))
168 }
169}
170
171fn read_attributes_array<'a>(
172 buf: &mut &'a [u8],
173) -> Result<Vec<AttributeArrayValueSlice<'a>>, DecodeError> {
174 if handle_null_marker(buf) {
175 return Ok(Vec::default());
176 }
177
178 let map_len = rmp::decode::read_map_len(buf).map_err(|_| {
179 DecodeError::InvalidType(
180 "Unable to get map len for event attributes array_value object".to_owned(),
181 )
182 })?;
183
184 if map_len != 1 {
185 return Err(DecodeError::InvalidFormat(
186 "event attributes array_value object should only have 'values' field".to_owned(),
187 ));
188 }
189
190 let key = read_string_ref(buf)?;
191 if key != "values" {
192 return Err(DecodeError::InvalidFormat(
193 "Expected 'values' field in event attributes array_value object".to_owned(),
194 ));
195 }
196
197 let len = rmp::decode::read_array_len(buf).map_err(|_| {
198 DecodeError::InvalidType(
199 "Unable to get array len for event attributes values field".to_owned(),
200 )
201 })?;
202
203 let mut vec: Vec<AttributeArrayValueSlice> = Vec::with_capacity(len as usize);
204 if len > 0 {
205 let first = decode_attribute_array(buf, None)?;
206 let array_type = (&first).into();
207 vec.push(first);
208 for _ in 1..len {
209 vec.push(decode_attribute_array(buf, Some(array_type))?);
210 }
211 }
212 Ok(vec)
213}
214
215#[derive(Debug, PartialEq)]
216enum AttributeArrayKey {
217 Type,
218 StringValue,
219 BoolValue,
220 IntValue,
221 DoubleValue,
222}
223
224impl FromStr for AttributeArrayKey {
225 type Err = DecodeError;
226
227 fn from_str(s: &str) -> Result<Self, Self::Err> {
228 match s {
229 "type" => Ok(AttributeArrayKey::Type),
230 "string_value" => Ok(AttributeArrayKey::StringValue),
231 "bool_value" => Ok(AttributeArrayKey::BoolValue),
232 "int_value" => Ok(AttributeArrayKey::IntValue),
233 "double_value" => Ok(AttributeArrayKey::DoubleValue),
234 _ => Err(DecodeError::InvalidFormat(
235 format!("Invalid attribute key: {s}").to_owned(),
236 )),
237 }
238 }
239}
240
241fn get_attribute_from_key<'a>(
242 buf: &mut &'a [u8],
243 key: AttributeArrayKey,
244) -> Result<AttributeArrayValueSlice<'a>, DecodeError> {
245 match key {
246 AttributeArrayKey::StringValue => {
247 Ok(AttributeArrayValueSlice::String(read_string_ref(buf)?))
248 }
249 AttributeArrayKey::BoolValue => {
250 let boolean = rmp::decode::read_bool(buf);
251 if let Ok(value) = boolean {
252 match value {
253 true => Ok(AttributeArrayValueSlice::Boolean(true)),
254 false => Ok(AttributeArrayValueSlice::Boolean(false)),
255 }
256 } else {
257 Err(DecodeError::InvalidType("Invalid boolean field".to_owned()))
258 }
259 }
260 AttributeArrayKey::IntValue => {
261 Ok(AttributeArrayValueSlice::Integer(read_number_slice(buf)?))
262 }
263 AttributeArrayKey::DoubleValue => {
264 Ok(AttributeArrayValueSlice::Double(read_number_slice(buf)?))
265 }
266 _ => Err(DecodeError::InvalidFormat("Invalid attribute".to_owned())),
267 }
268}
269
270fn decode_attribute_array<'a>(
271 buf: &mut &'a [u8],
272 array_type: Option<u8>,
273) -> Result<AttributeArrayValueSlice<'a>, DecodeError> {
274 let mut attribute: Option<AttributeArrayValueSlice> = None;
275 let attribute_size = rmp::decode::read_map_len(buf).map_err(|_| {
276 DecodeError::InvalidType("Unable to get map len for attribute size".to_owned())
277 })?;
278
279 if attribute_size != 2 {
280 return Err(DecodeError::InvalidFormat(
281 "Invalid number of field for an attribute".to_owned(),
282 ));
283 }
284 let mut attribute_type: Option<u8> = None;
285
286 for _ in 0..attribute_size {
287 match read_string_ref(buf)?.parse::<AttributeArrayKey>()? {
288 AttributeArrayKey::Type => attribute_type = Some(read_number_slice(buf)?),
289 key => attribute = Some(get_attribute_from_key(buf, key)?),
290 }
291 }
292
293 if let Some(value) = attribute {
294 if let Some(attribute_type) = attribute_type {
295 let value_type: u8 = (&value).into();
296 if attribute_type == value_type {
297 if let Some(array_type) = array_type {
298 if array_type != attribute_type {
299 return Err(DecodeError::InvalidType(
300 "Array must have same type element".to_owned(),
301 ));
302 }
303 }
304 Ok(value)
305 } else {
306 Err(DecodeError::InvalidFormat(
307 "No type for attribute".to_owned(),
308 ))
309 }
310 } else {
311 Err(DecodeError::InvalidType(
312 "Type mismatch for attribute".to_owned(),
313 ))
314 }
315 } else {
316 Err(DecodeError::InvalidFormat("Invalid attribute".to_owned()))
317 }
318}
319
320#[cfg(test)]
321mod tests {
322 use super::AttributeAnyKey;
323 use super::AttributeArrayKey;
324 use super::SpanEventKey;
325 use crate::msgpack_decoder::decode::error::DecodeError;
326 use std::str::FromStr;
327
328 #[test]
329 fn test_span_event_key_from_str() {
330 assert_eq!(
332 SpanEventKey::from_str("time_unix_nano").unwrap(),
333 SpanEventKey::TimeUnixNano
334 );
335 assert_eq!(SpanEventKey::from_str("name").unwrap(), SpanEventKey::Name);
336 assert_eq!(
337 SpanEventKey::from_str("attributes").unwrap(),
338 SpanEventKey::Attributes
339 );
340
341 assert!(matches!(
343 SpanEventKey::from_str("invalid_key"),
344 Err(DecodeError::InvalidFormat(_))
345 ));
346 }
347
348 #[test]
349 fn test_attribute_any_key_from_str() {
350 assert_eq!(
352 AttributeAnyKey::from_str("type").unwrap(),
353 AttributeAnyKey::Type
354 );
355 assert_eq!(
356 AttributeAnyKey::from_str("string_value").unwrap(),
357 AttributeAnyKey::SingleValue(AttributeArrayKey::StringValue)
358 );
359 assert_eq!(
360 AttributeAnyKey::from_str("bool_value").unwrap(),
361 AttributeAnyKey::SingleValue(AttributeArrayKey::BoolValue)
362 );
363 assert_eq!(
364 AttributeAnyKey::from_str("int_value").unwrap(),
365 AttributeAnyKey::SingleValue(AttributeArrayKey::IntValue)
366 );
367 assert_eq!(
368 AttributeAnyKey::from_str("double_value").unwrap(),
369 AttributeAnyKey::SingleValue(AttributeArrayKey::DoubleValue)
370 );
371 assert_eq!(
372 AttributeAnyKey::from_str("array_value").unwrap(),
373 AttributeAnyKey::ArrayValue
374 );
375
376 assert!(matches!(
378 AttributeAnyKey::from_str("invalid_key"),
379 Err(DecodeError::InvalidFormat(_))
380 ));
381 }
382
383 #[test]
384 fn test_attribute_array_key_from_str() {
385 assert_eq!(
387 AttributeArrayKey::from_str("type").unwrap(),
388 AttributeArrayKey::Type
389 );
390 assert_eq!(
391 AttributeArrayKey::from_str("string_value").unwrap(),
392 AttributeArrayKey::StringValue
393 );
394 assert_eq!(
395 AttributeArrayKey::from_str("bool_value").unwrap(),
396 AttributeArrayKey::BoolValue
397 );
398 assert_eq!(
399 AttributeArrayKey::from_str("int_value").unwrap(),
400 AttributeArrayKey::IntValue
401 );
402 assert_eq!(
403 AttributeArrayKey::from_str("double_value").unwrap(),
404 AttributeArrayKey::DoubleValue
405 );
406
407 assert!(matches!(
409 AttributeArrayKey::from_str("invalid_key"),
410 Err(DecodeError::InvalidFormat(_))
411 ));
412 }
413}