env_logger/fmt/
humantime.rs

1use std::fmt;
2use std::time::SystemTime;
3
4use humantime::{
5    format_rfc3339_micros, format_rfc3339_millis, format_rfc3339_nanos, format_rfc3339_seconds,
6};
7
8use crate::fmt::{Formatter, TimestampPrecision};
9
10impl Formatter {
11    /// Get a [`Timestamp`] for the current date and time in UTC.
12    ///
13    /// # Examples
14    ///
15    /// Include the current timestamp with the log record:
16    ///
17    /// ```
18    /// use std::io::Write;
19    ///
20    /// let mut builder = env_logger::Builder::new();
21    ///
22    /// builder.format(|buf, record| {
23    ///     let ts = buf.timestamp();
24    ///
25    ///     writeln!(buf, "{}: {}: {}", ts, record.level(), record.args())
26    /// });
27    /// ```
28    pub fn timestamp(&self) -> Timestamp {
29        Timestamp {
30            time: SystemTime::now(),
31            precision: TimestampPrecision::Seconds,
32        }
33    }
34
35    /// Get a [`Timestamp`] for the current date and time in UTC with full
36    /// second precision.
37    pub fn timestamp_seconds(&self) -> Timestamp {
38        Timestamp {
39            time: SystemTime::now(),
40            precision: TimestampPrecision::Seconds,
41        }
42    }
43
44    /// Get a [`Timestamp`] for the current date and time in UTC with
45    /// millisecond precision.
46    pub fn timestamp_millis(&self) -> Timestamp {
47        Timestamp {
48            time: SystemTime::now(),
49            precision: TimestampPrecision::Millis,
50        }
51    }
52
53    /// Get a [`Timestamp`] for the current date and time in UTC with
54    /// microsecond precision.
55    pub fn timestamp_micros(&self) -> Timestamp {
56        Timestamp {
57            time: SystemTime::now(),
58            precision: TimestampPrecision::Micros,
59        }
60    }
61
62    /// Get a [`Timestamp`] for the current date and time in UTC with
63    /// nanosecond precision.
64    pub fn timestamp_nanos(&self) -> Timestamp {
65        Timestamp {
66            time: SystemTime::now(),
67            precision: TimestampPrecision::Nanos,
68        }
69    }
70}
71
72/// An [RFC3339] formatted timestamp.
73///
74/// The timestamp implements [`Display`] and can be written to a [`Formatter`].
75///
76/// [RFC3339]: https://www.ietf.org/rfc/rfc3339.txt
77/// [`Display`]: std::fmt::Display
78pub struct Timestamp {
79    time: SystemTime,
80    precision: TimestampPrecision,
81}
82
83impl fmt::Debug for Timestamp {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        /// A `Debug` wrapper for `Timestamp` that uses the `Display` implementation.
86        struct TimestampValue<'a>(&'a Timestamp);
87
88        impl fmt::Debug for TimestampValue<'_> {
89            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90                fmt::Display::fmt(&self.0, f)
91            }
92        }
93
94        f.debug_tuple("Timestamp")
95            .field(&TimestampValue(self))
96            .finish()
97    }
98}
99
100impl fmt::Display for Timestamp {
101    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102        let formatter = match self.precision {
103            TimestampPrecision::Seconds => format_rfc3339_seconds,
104            TimestampPrecision::Millis => format_rfc3339_millis,
105            TimestampPrecision::Micros => format_rfc3339_micros,
106            TimestampPrecision::Nanos => format_rfc3339_nanos,
107        };
108
109        formatter(self.time).fmt(f)
110    }
111}