libdd_trace_utils/span/v05/
mod.rs1pub mod dict;
5
6use crate::span::{v05::dict::SharedDict, SpanText};
7use anyhow::Result;
8use serde::Serialize;
9use std::collections::HashMap;
10
11#[derive(Clone, Debug, Default, PartialEq, Serialize)]
16pub struct Span {
17 pub service: u32,
18 pub name: u32,
19 pub resource: u32,
20 pub trace_id: u64,
21 pub span_id: u64,
22 pub parent_id: u64,
23 pub start: i64,
24 pub duration: i64,
25 pub error: i32,
26 pub meta: HashMap<u32, u32>,
27 pub metrics: HashMap<u32, f64>,
28 pub r#type: u32,
29}
30
31pub fn from_span<T: SpanText>(
32 span: crate::span::Span<T>,
33 dict: &mut SharedDict<T>,
34) -> Result<Span> {
35 let meta_len = span.meta.len();
36 let metrics_len = span.metrics.len();
37 Ok(Span {
38 service: dict.get_or_insert(span.service)?,
39 name: dict.get_or_insert(span.name)?,
40 resource: dict.get_or_insert(span.resource)?,
41 trace_id: span.trace_id as u64,
42 span_id: span.span_id,
43 parent_id: span.parent_id,
44 start: span.start,
45 duration: span.duration,
46 error: span.error,
47 meta: span.meta.into_iter().try_fold(
48 HashMap::with_capacity(meta_len),
49 |mut meta, (k, v)| -> anyhow::Result<HashMap<u32, u32>> {
50 meta.insert(dict.get_or_insert(k)?, dict.get_or_insert(v)?);
51 Ok(meta)
52 },
53 )?,
54 metrics: span.metrics.into_iter().try_fold(
55 HashMap::with_capacity(metrics_len),
56 |mut metrics, (k, v)| -> anyhow::Result<HashMap<u32, f64>> {
57 metrics.insert(dict.get_or_insert(k)?, v);
58 Ok(metrics)
59 },
60 )?,
61 r#type: dict.get_or_insert(span.r#type)?,
62 })
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use crate::span::SpanBytes;
69 use libdd_tinybytes::BytesString;
70
71 #[test]
72 fn from_span_bytes_test() {
73 let span = SpanBytes {
74 service: BytesString::from("service"),
75 name: BytesString::from("name"),
76 resource: BytesString::from("resource"),
77 r#type: BytesString::from("type"),
78 trace_id: 1,
79 span_id: 1,
80 parent_id: 0,
81 start: 1,
82 duration: 111,
83 error: 0,
84 meta: HashMap::from([(
85 BytesString::from("meta_field"),
86 BytesString::from("meta_value"),
87 )]),
88 metrics: HashMap::from([(BytesString::from("metrics_field"), 1.1)]),
89 meta_struct: HashMap::new(),
90 span_links: vec![],
91 span_events: vec![],
92 };
93
94 let mut dict = SharedDict::default();
95 let v05_span = from_span(span, &mut dict).unwrap();
96
97 let get_index_from_str = |str: &str| -> u32 {
98 dict.iter()
99 .position(|s| s.as_str() == str)
100 .unwrap()
101 .try_into()
102 .unwrap()
103 };
104
105 assert_eq!(v05_span.service, get_index_from_str("service"));
106 assert_eq!(v05_span.name, get_index_from_str("name"));
107 assert_eq!(v05_span.resource, get_index_from_str("resource"));
108 assert_eq!(v05_span.r#type, get_index_from_str("type"));
109 assert_eq!(v05_span.trace_id, 1);
110 assert_eq!(v05_span.span_id, 1);
111 assert_eq!(v05_span.parent_id, 0);
112 assert_eq!(v05_span.start, 1);
113 assert_eq!(v05_span.duration, 111);
114 assert_eq!(v05_span.error, 0);
115 assert_eq!(v05_span.meta.len(), 1);
116 assert_eq!(v05_span.metrics.len(), 1);
117
118 assert_eq!(
119 *v05_span
120 .meta
121 .get(&get_index_from_str("meta_field"))
122 .unwrap(),
123 get_index_from_str("meta_value")
124 );
125 assert_eq!(
126 *v05_span
127 .metrics
128 .get(&get_index_from_str("metrics_field"))
129 .unwrap(),
130 1.1
131 );
132 }
133}