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    ///
29    /// [`Timestamp`]: struct.Timestamp.html
30    pub fn timestamp(&self) -> Timestamp {
31        Timestamp {
32            time: SystemTime::now(),
33            precision: TimestampPrecision::Seconds,
34        }
35    }
36
37    /// Get a [`Timestamp`] for the current date and time in UTC with full
38    /// second precision.
39    pub fn timestamp_seconds(&self) -> Timestamp {
40        Timestamp {
41            time: SystemTime::now(),
42            precision: TimestampPrecision::Seconds,
43        }
44    }
45
46    /// Get a [`Timestamp`] for the current date and time in UTC with
47    /// millisecond precision.
48    pub fn timestamp_millis(&self) -> Timestamp {
49        Timestamp {
50            time: SystemTime::now(),
51            precision: TimestampPrecision::Millis,
52        }
53    }
54
55    /// Get a [`Timestamp`] for the current date and time in UTC with
56    /// microsecond precision.
57    pub fn timestamp_micros(&self) -> Timestamp {
58        Timestamp {
59            time: SystemTime::now(),
60            precision: TimestampPrecision::Micros,
61        }
62    }
63
64    /// Get a [`Timestamp`] for the current date and time in UTC with
65    /// nanosecond precision.
66    pub fn timestamp_nanos(&self) -> Timestamp {
67        Timestamp {
68            time: SystemTime::now(),
69            precision: TimestampPrecision::Nanos,
70        }
71    }
72}
73
74/// An [RFC3339] formatted timestamp.
75///
76/// The timestamp implements [`Display`] and can be written to a [`Formatter`].
77///
78/// [RFC3339]: https://www.ietf.org/rfc/rfc3339.txt
79/// [`Display`]: https://doc.rust-lang.org/stable/std/fmt/trait.Display.html
80/// [`Formatter`]: struct.Formatter.html
81pub struct Timestamp {
82    time: SystemTime,
83    precision: TimestampPrecision,
84}
85
86impl fmt::Debug for Timestamp {
87    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88        /// A `Debug` wrapper for `Timestamp` that uses the `Display` implementation.
89        struct TimestampValue<'a>(&'a Timestamp);
90
91        impl<'a> fmt::Debug for TimestampValue<'a> {
92            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93                fmt::Display::fmt(&self.0, f)
94            }
95        }
96
97        f.debug_tuple("Timestamp")
98            .field(&TimestampValue(self))
99            .finish()
100    }
101}
102
103impl fmt::Display for Timestamp {
104    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105        let formatter = match self.precision {
106            TimestampPrecision::Seconds => format_rfc3339_seconds,
107            TimestampPrecision::Millis => format_rfc3339_millis,
108            TimestampPrecision::Micros => format_rfc3339_micros,
109            TimestampPrecision::Nanos => format_rfc3339_nanos,
110        };
111
112        formatter(self.time).fmt(f)
113    }
114}