pub mod dict;
use crate::span::{v05::dict::SharedDict, TraceData};
use anyhow::Result;
use serde::Serialize;
use std::collections::HashMap;
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct Span {
pub service: u32,
pub name: u32,
pub resource: u32,
pub trace_id: u64,
pub span_id: u64,
pub parent_id: u64,
pub start: i64,
pub duration: i64,
pub error: i32,
pub meta: HashMap<u32, u32>,
pub metrics: HashMap<u32, f64>,
pub r#type: u32,
}
pub fn from_v04_span<T: TraceData>(
span: crate::span::v04::Span<T>,
dict: &mut SharedDict<T::Text>,
) -> Result<Span> {
let meta_len = span.meta.len();
let metrics_len = span.metrics.len();
Ok(Span {
service: dict.get_or_insert(span.service)?,
name: dict.get_or_insert(span.name)?,
resource: dict.get_or_insert(span.resource)?,
trace_id: span.trace_id as u64,
span_id: span.span_id,
parent_id: span.parent_id,
start: span.start,
duration: span.duration,
error: span.error,
meta: span.meta.into_iter().try_fold(
HashMap::with_capacity(meta_len),
|mut meta, (k, v)| -> anyhow::Result<HashMap<u32, u32>> {
meta.insert(dict.get_or_insert(k)?, dict.get_or_insert(v)?);
Ok(meta)
},
)?,
metrics: span.metrics.into_iter().try_fold(
HashMap::with_capacity(metrics_len),
|mut metrics, (k, v)| -> anyhow::Result<HashMap<u32, f64>> {
metrics.insert(dict.get_or_insert(k)?, v);
Ok(metrics)
},
)?,
r#type: dict.get_or_insert(span.r#type)?,
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::span::v04::SpanBytes;
use libdd_tinybytes::BytesString;
#[test]
fn from_span_bytes_test() {
let span = SpanBytes {
service: BytesString::from("service"),
name: BytesString::from("name"),
resource: BytesString::from("resource"),
r#type: BytesString::from("type"),
trace_id: 1,
span_id: 1,
parent_id: 0,
start: 1,
duration: 111,
error: 0,
meta: HashMap::from([(
BytesString::from("meta_field"),
BytesString::from("meta_value"),
)]),
metrics: HashMap::from([(BytesString::from("metrics_field"), 1.1)]),
meta_struct: HashMap::new(),
span_links: vec![],
span_events: vec![],
};
let mut dict = SharedDict::default();
let v05_span = from_v04_span(span, &mut dict).unwrap();
let get_index_from_str = |str: &str| -> u32 {
dict.iter()
.position(|s| s.as_str() == str)
.unwrap()
.try_into()
.unwrap()
};
assert_eq!(v05_span.service, get_index_from_str("service"));
assert_eq!(v05_span.name, get_index_from_str("name"));
assert_eq!(v05_span.resource, get_index_from_str("resource"));
assert_eq!(v05_span.r#type, get_index_from_str("type"));
assert_eq!(v05_span.trace_id, 1);
assert_eq!(v05_span.span_id, 1);
assert_eq!(v05_span.parent_id, 0);
assert_eq!(v05_span.start, 1);
assert_eq!(v05_span.duration, 111);
assert_eq!(v05_span.error, 0);
assert_eq!(v05_span.meta.len(), 1);
assert_eq!(v05_span.metrics.len(), 1);
assert_eq!(
*v05_span
.meta
.get(&get_index_from_str("meta_field"))
.unwrap(),
get_index_from_str("meta_value")
);
assert_eq!(
*v05_span
.metrics
.get(&get_index_from_str("metrics_field"))
.unwrap(),
1.1
);
}
}