tracing_glog/
time_crate.rs1#[cfg(feature = "ansi")]
2use crate::nu_ansi_term::Style;
3use std::{fmt, io};
4use time::{format_description::FormatItem, formatting::Formattable, OffsetDateTime};
5use tracing_subscriber::fmt::{format::Writer, time::FormatTime};
6
7pub(crate) struct WriteAdaptor<'a> {
15 fmt_write: &'a mut dyn fmt::Write,
16}
17
18#[cfg(feature = "time")]
19fn format_datetime(
20 into: &mut Writer<'_>,
21 now: OffsetDateTime,
22 fmt: &impl Formattable,
23) -> fmt::Result {
24 let mut into = WriteAdaptor::new(into);
25 now.format_into(&mut into, fmt)
26 .map_err(|_| fmt::Error)
27 .map(|_| ())
28}
29
30impl<'a> WriteAdaptor<'a> {
31 pub(crate) fn new(fmt_write: &'a mut dyn fmt::Write) -> Self {
32 Self { fmt_write }
33 }
34}
35
36impl<'a> std::io::Write for WriteAdaptor<'a> {
37 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
38 let s = std::str::from_utf8(buf)
39 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
40
41 self.fmt_write
42 .write_str(s)
43 .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
44
45 Ok(s.as_bytes().len())
46 }
47
48 fn flush(&mut self) -> io::Result<()> {
49 Ok(())
50 }
51}
52
53impl<'a> fmt::Debug for WriteAdaptor<'a> {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 f.pad("WriteAdaptor { .. }")
56 }
57}
58
59#[derive(Clone, Debug)]
68pub struct UtcTime<F = Vec<FormatItem<'static>>> {
69 format: F,
70}
71
72impl<F> FormatTime for UtcTime<F>
73where
74 F: Formattable,
75{
76 fn format_time(&self, writer: &mut Writer<'_>) -> fmt::Result {
77 let now = OffsetDateTime::now_utc();
78
79 #[cfg(feature = "ansi")]
80 if writer.has_ansi_escapes() {
81 let style = Style::new().dimmed();
82 write!(writer, "{}", style.prefix())?;
83 format_datetime(writer, now, &self.format)?;
84 write!(writer, "{}", style.suffix())?;
85 return Ok(());
86 }
87
88 format_datetime(writer, now, &self.format)
89 }
90}
91
92impl Default for UtcTime {
93 fn default() -> Self {
94 let format: Vec<FormatItem> = time::format_description::parse(
95 "[month][day] [hour]:[minute]:[second].[subsecond digits:6]",
96 )
97 .expect("Unable to make time formatter");
98 Self { format }
99 }
100}
101
102#[derive(Clone, Debug)]
122#[cfg(feature = "local-time")]
123pub struct LocalTime<F = Vec<FormatItem<'static>>> {
124 format: F,
125}
126
127#[cfg(feature = "local-time")]
128impl Default for LocalTime {
129 fn default() -> Self {
130 let format: Vec<FormatItem> = time::format_description::parse(
131 "[month][day] [hour]:[minute]:[second].[subsecond digits:6]",
132 )
133 .expect("Unable to make time formatter");
134 Self { format }
135 }
136}
137
138#[cfg(feature = "local-time")]
139impl<F> FormatTime for LocalTime<F>
140where
141 F: Formattable,
142{
143 fn format_time(&self, writer: &mut Writer<'_>) -> fmt::Result {
144 let now = OffsetDateTime::now_local().map_err(|_| fmt::Error)?;
145
146 #[cfg(feature = "ansi")]
147 if writer.has_ansi_escapes() {
148 let style = Style::new().dimmed();
149 write!(writer, "{}", style.prefix())?;
150 format_datetime(writer, now, &self.format)?;
151 write!(writer, "{}", style.suffix())?;
153 return Ok(());
154 }
155
156 format_datetime(writer, now, &self.format)
157 }
158}