use crate::SharedString;
use smallvec::SmallVec;
use std::fmt;
#[derive(Debug, Clone)]
pub struct TraceState {
states: SmallVec<[(SharedString, String); 2]>,
}
impl TraceState {
#[inline]
pub fn new() -> Self {
Self {
states: SmallVec::new(),
}
}
pub fn from_tracestate(tracestate: &str) -> Self {
let states = tracestate
.replace(' ', "")
.split(',')
.filter_map(|state| {
state
.split_once('=')
.map(|(key, value)| (key.to_owned().into(), value.to_owned()))
})
.collect();
Self { states }
}
#[inline]
pub fn push(&mut self, key: impl Into<SharedString>, value: impl ToString) {
let states = &mut self.states;
let key = key.into();
let value = value.to_string();
if let Some(index) = states.iter().position(|(k, _)| k.as_ref() == key.as_ref()) {
states[index] = (key, value);
} else {
states.push((key, value));
}
}
}
impl Default for TraceState {
fn default() -> Self {
Self::new()
}
}
impl fmt::Display for TraceState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let output = self
.states
.iter()
.map(|(key, value)| format!("{key}={value}"))
.collect::<Vec<_>>()
.join(",");
write!(f, "{output}")
}
}