zino_http/timing/
timing_metric.rs1use std::{fmt, time::Duration};
2use zino_core::SharedString;
3
4#[derive(Debug, Clone)]
6pub struct TimingMetric {
7 name: SharedString,
9 description: Option<SharedString>,
11 duration: Duration,
13}
14
15impl TimingMetric {
16 #[inline]
18 pub fn new(
19 name: SharedString,
20 description: Option<SharedString>,
21 duration: Option<Duration>,
22 ) -> Self {
23 Self {
24 name,
25 description,
26 duration: duration.unwrap_or_default(),
27 }
28 }
29
30 #[inline]
32 pub fn name(&self) -> &str {
33 self.name.as_ref()
34 }
35
36 #[inline]
38 pub fn description(&self) -> Option<&str> {
39 self.description.as_deref()
40 }
41
42 #[inline]
44 pub fn duration(&self) -> Option<Duration> {
45 let duration = self.duration;
46 (duration > Duration::ZERO).then_some(duration)
47 }
48}
49
50impl fmt::Display for TimingMetric {
51 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
52 let name = self.name();
53 if let Some(duration) = self.duration() {
54 let mut buffer = ryu::Buffer::new();
55 let millis = (duration.as_micros() as f64) / 1000.0;
56 let duration_millis = buffer.format_finite(millis);
57 if let Some(description) = self.description() {
58 write!(f, "{name};desc={description};dur={duration_millis}")
59 } else {
60 write!(f, "{name};dur={duration_millis}")
61 }
62 } else if let Some(description) = self.description() {
63 write!(f, "{name};desc={description}")
64 } else {
65 write!(f, "{name}")
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::TimingMetric;
73 use std::time::Duration;
74
75 #[test]
76 fn it_formats_timing_metric() {
77 let cache_miss_metric = TimingMetric::new("miss".into(), None, None);
78 assert_eq!(format!("{cache_miss_metric}"), "miss");
79
80 let db_query_metric = TimingMetric::new(
81 "db".into(),
82 Some("query".into()),
83 Some(Duration::from_secs_f64(0.0024635)),
84 );
85 assert_eq!(format!("{db_query_metric}"), "db;desc=query;dur=2.463");
86
87 let total_timing_metric =
88 TimingMetric::new("total".into(), None, Some(Duration::from_secs_f64(0.01082)));
89 assert_eq!(format!("{total_timing_metric}"), "total;dur=10.82");
90 }
91}