use alloc::vec::Vec;
use ref_str::{RefStr, StaticRefStr};
use crate::report::{AttachmentValue, ReportTrace, TraceContext, TraceEvent, TraceEventAttribute};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json", serde(bound(deserialize = "'de: 'a")))]
pub(super) struct TraceSectionValue<'a> {
pub context: TraceContextValue<'a>,
pub events: Vec<TraceEventValue<'a>>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json", serde(bound(deserialize = "'de: 'a")))]
pub(super) struct TraceContextValue<'a> {
pub trace_id: Option<RefStr<'a>>,
pub span_id: Option<RefStr<'a>>,
pub parent_span_id: Option<RefStr<'a>>,
pub sampled: Option<bool>,
pub trace_state: Option<RefStr<'a>>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json", serde(bound(deserialize = "'de: 'a")))]
pub(super) struct TraceEventValue<'a> {
pub name: RefStr<'a>,
pub level: Option<StaticRefStr>,
pub timestamp_unix_nano: Option<u64>,
pub attributes: Vec<TraceAttributeValue<'a>>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json", serde(bound(deserialize = "'de: 'a")))]
pub(super) struct TraceAttributeValue<'a> {
pub key: RefStr<'a>,
pub value: AttachmentValue,
}
pub(super) fn build_trace_section_value(trace: &ReportTrace) -> TraceSectionValue<'_> {
TraceSectionValue {
context: build_trace_ctx_value_opt(trace.context()),
events: trace
.events()
.map(|e| e.iter().map(build_trace_evt_value).collect())
.unwrap_or_default(),
}
}
fn build_trace_ctx_value_opt(context: Option<&TraceContext>) -> TraceContextValue<'_> {
match context {
Some(ctx) => build_trace_ctx_value(ctx),
None => TraceContextValue {
trace_id: None,
span_id: None,
parent_span_id: None,
sampled: None,
trace_state: None,
},
}
}
fn build_trace_ctx_value(context: &TraceContext) -> TraceContextValue<'_> {
TraceContextValue {
trace_id: context.trace_id.as_ref().map(|v| v.as_ref().into()),
span_id: context.span_id.as_ref().map(|v| v.as_ref().into()),
parent_span_id: context.parent_span_id.as_ref().map(|v| v.as_ref().into()),
sampled: context.sampled,
trace_state: context.trace_state.as_ref().map(|v| v.as_str().into()),
}
}
fn build_trace_evt_value(event: &TraceEvent) -> TraceEventValue<'_> {
TraceEventValue {
name: event.name.clone().into(),
level: event.level.map(trace_event_level_ref),
timestamp_unix_nano: event.timestamp_unix_nano,
attributes: event
.attributes
.iter()
.map(build_trace_attr_value)
.collect(),
}
}
fn build_trace_attr_value(attr: &TraceEventAttribute) -> TraceAttributeValue<'_> {
TraceAttributeValue {
key: attr.key.clone().into(),
value: attr.value.clone(),
}
}
fn trace_event_level_ref(level: crate::report::TraceEventLevel) -> StaticRefStr {
match level {
crate::report::TraceEventLevel::Trace => "trace".into(),
crate::report::TraceEventLevel::Debug => "debug".into(),
crate::report::TraceEventLevel::Info => "info".into(),
crate::report::TraceEventLevel::Warn => "warn".into(),
crate::report::TraceEventLevel::Error => "error".into(),
}
}