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