use std::time::Instant;
pub struct Timer {
last: Instant,
timings: Vec<Timing>,
}
struct Timing {
name: String,
duration: u128,
}
impl Timer {
pub fn new() -> Self {
Timer {
last: Instant::now(),
timings: Vec::new(),
}
}
pub fn add(&mut self, name: &str) {
let now = Instant::now();
let duration = now.duration_since(self.last).as_millis();
self.last = now;
self.timings.push(Timing {
name: name.into(),
duration,
});
}
pub fn header_key() -> &'static str {
"Server-Timing"
}
pub fn header_value(&self) -> String {
let mut out = String::new();
use std::fmt::Write;
for timing in self.timings.iter() {
let name = timing.name.replace(|c: char| !c.is_alphanumeric(), "_");
_ = write!(out, "{};dur={}, ", name, timing.duration);
}
out.pop();
out.pop();
out
}
}
impl Default for Timer {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test() {
let mut timer = Timer::new();
timer.add("parse headers");
timer.add("get_db_data");
assert_eq!(
timer.header_value(),
"parse_headers;dur=0, get_db_data;dur=0"
);
}
}