1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#[cfg(feature = "chrono")]
use chrono;
#[cfg(feature = "ansi")]
use ansi_term::Style;
use std::fmt;
use std::time::Instant;
pub trait FormatTime {
fn format_time(&self, w: &mut dyn fmt::Write) -> fmt::Result;
}
impl<'a, F> FormatTime for &'a F
where
F: FormatTime,
{
fn format_time(&self, w: &mut dyn fmt::Write) -> fmt::Result {
(*self).format_time(w)
}
}
impl FormatTime for () {
fn format_time(&self, _: &mut dyn fmt::Write) -> fmt::Result {
Ok(())
}
}
impl FormatTime for fn(&mut dyn fmt::Write) -> fmt::Result {
fn format_time(&self, w: &mut dyn fmt::Write) -> fmt::Result {
(*self)(w)
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
pub struct SystemTime;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct Uptime {
epoch: Instant,
}
impl Default for Uptime {
fn default() -> Self {
Uptime {
epoch: Instant::now(),
}
}
}
impl From<Instant> for Uptime {
fn from(epoch: Instant) -> Self {
Uptime { epoch }
}
}
#[cfg(feature = "chrono")]
impl FormatTime for SystemTime {
fn format_time(&self, w: &mut dyn fmt::Write) -> fmt::Result {
write!(w, "{} ", chrono::Local::now().format("%b %d %H:%M:%S%.3f"))
}
}
#[cfg(not(feature = "chrono"))]
impl FormatTime for SystemTime {
fn format_time(&self, w: &mut fmt::Write) -> fmt::Result {
write!(w, "{:?} ", std::time::SystemTime::now())
}
}
impl FormatTime for Uptime {
fn format_time(&self, w: &mut dyn fmt::Write) -> fmt::Result {
let e = self.epoch.elapsed();
write!(w, "{:4}.{:09}s ", e.as_secs(), e.subsec_nanos())
}
}
#[inline(always)]
#[cfg(feature = "ansi")]
pub(crate) fn write<T>(timer: T, writer: &mut dyn fmt::Write) -> fmt::Result
where
T: FormatTime,
{
let style = Style::new().dimmed();
write!(writer, "{}", style.prefix())?;
timer.format_time(writer)?;
write!(writer, "{}", style.suffix())?;
Ok(())
}
#[inline(always)]
#[cfg(not(feature = "ansi"))]
pub(crate) fn write<T>(timer: T, writer: &mut fmt::Write) -> fmt::Result
where
T: FormatTime,
{
timer.format_time(writer)
}