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