use std::time::{Duration, Instant};
#[derive(Debug, Clone)]
pub struct AppendStep {
pub name: String,
pub elapsed_ms: u128,
pub fields: Vec<(String, String)>,
}
#[derive(Debug, Clone)]
pub struct AppendReport {
pub context: Vec<(String, String)>,
pub steps: Vec<AppendStep>,
pub total_ms: u128,
}
#[derive(Debug)]
pub struct AppendReportBuilder {
start: Instant,
context: Vec<(String, String)>,
steps: Vec<AppendStep>,
}
impl Default for AppendReportBuilder {
fn default() -> Self {
Self::new()
}
}
impl AppendReportBuilder {
pub fn new() -> Self {
Self {
start: Instant::now(),
context: Vec::new(),
steps: Vec::new(),
}
}
pub fn set_context(&mut self, key: &str, value: impl Into<String>) {
let value = value.into();
if let Some((_, v)) = self.context.iter_mut().find(|(k, _)| k == key) {
*v = value;
} else {
self.context.push((key.to_string(), value));
}
}
pub fn push_step<I>(&mut self, name: &str, elapsed: Duration, fields: I)
where
I: IntoIterator<Item = (String, String)>,
{
self.steps.push(AppendStep {
name: name.to_string(),
elapsed_ms: elapsed.as_millis(),
fields: fields.into_iter().collect(),
});
}
pub fn finish(self) -> AppendReport {
AppendReport {
context: self.context,
steps: self.steps,
total_ms: self.start.elapsed().as_millis(),
}
}
}