better_tracing/fmt/time/
chrono_crate.rs1use crate::fmt::format::Writer;
2use crate::fmt::time::FormatTime;
3
4use std::sync::Arc;
5
6#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
18#[derive(Debug, Clone, Eq, PartialEq, Default)]
19pub struct ChronoLocal {
20 format: Arc<ChronoFmtType>,
21}
22
23impl ChronoLocal {
24 pub fn rfc_3339() -> Self {
30 Self {
31 format: Arc::new(ChronoFmtType::Rfc3339),
32 }
33 }
34
35 pub fn rfc3339_seconds() -> Self {
37 Self {
38 format: Arc::new(ChronoFmtType::Rfc3339Opts(
39 chrono::SecondsFormat::Secs,
40 true,
41 )),
42 }
43 }
44
45 pub fn rfc3339_millis() -> Self {
47 Self {
48 format: Arc::new(ChronoFmtType::Rfc3339Opts(
49 chrono::SecondsFormat::Millis,
50 true,
51 )),
52 }
53 }
54
55 pub fn rfc3339_nanos() -> Self {
57 Self {
58 format: Arc::new(ChronoFmtType::Rfc3339Opts(
59 chrono::SecondsFormat::Nanos,
60 true,
61 )),
62 }
63 }
64
65 pub fn time_only_secs() -> Self {
67 Self::new("%H:%M:%S".to_owned())
68 }
69
70 pub fn time_only_millis() -> Self {
72 Self::new("%H:%M:%S%.3f".to_owned())
73 }
74
75 pub fn time_only_micros() -> Self {
77 Self::new("%H:%M:%S%.6f".to_owned())
78 }
79
80 pub fn new(format_string: String) -> Self {
84 Self {
85 format: Arc::new(ChronoFmtType::Custom(format_string)),
86 }
87 }
88}
89
90impl FormatTime for ChronoLocal {
91 fn format_time(&self, w: &mut Writer<'_>) -> alloc::fmt::Result {
92 let t = chrono::Local::now();
93 match self.format.as_ref() {
94 ChronoFmtType::Rfc3339 => {
95 use chrono::format::{Fixed, Item};
96 write!(
97 w,
98 "{}",
99 t.format_with_items(core::iter::once(Item::Fixed(Fixed::RFC3339)))
100 )
101 }
102 ChronoFmtType::Rfc3339Opts(secs_fmt, z) => {
103 write!(w, "{}", t.to_rfc3339_opts(*secs_fmt, *z))
104 }
105 ChronoFmtType::Custom(fmt) => {
106 write!(w, "{}", t.format(fmt))
107 }
108 }
109 }
110}
111
112#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
117#[derive(Debug, Clone, Eq, PartialEq, Default)]
118pub struct ChronoUtc {
119 format: Arc<ChronoFmtType>,
120}
121
122impl ChronoUtc {
123 pub fn rfc_3339() -> Self {
129 Self {
130 format: Arc::new(ChronoFmtType::Rfc3339),
131 }
132 }
133
134 pub fn rfc3339_seconds() -> Self {
136 Self {
137 format: Arc::new(ChronoFmtType::Rfc3339Opts(
138 chrono::SecondsFormat::Secs,
139 true,
140 )),
141 }
142 }
143
144 pub fn rfc3339_millis() -> Self {
146 Self {
147 format: Arc::new(ChronoFmtType::Rfc3339Opts(
148 chrono::SecondsFormat::Millis,
149 true,
150 )),
151 }
152 }
153
154 pub fn rfc3339_nanos() -> Self {
156 Self {
157 format: Arc::new(ChronoFmtType::Rfc3339Opts(
158 chrono::SecondsFormat::Nanos,
159 true,
160 )),
161 }
162 }
163
164 pub fn time_only_secs() -> Self {
166 Self::new("%H:%M:%S".to_owned())
167 }
168
169 pub fn time_only_millis() -> Self {
171 Self::new("%H:%M:%S%.3f".to_owned())
172 }
173
174 pub fn time_only_micros() -> Self {
176 Self::new("%H:%M:%S%.6f".to_owned())
177 }
178
179 pub fn new(format_string: String) -> Self {
183 Self {
184 format: Arc::new(ChronoFmtType::Custom(format_string)),
185 }
186 }
187}
188
189impl FormatTime for ChronoUtc {
190 fn format_time(&self, w: &mut Writer<'_>) -> alloc::fmt::Result {
191 let t = chrono::Utc::now();
192 match self.format.as_ref() {
193 ChronoFmtType::Rfc3339 => w.write_str(&t.to_rfc3339()),
194 ChronoFmtType::Custom(fmt) => w.write_str(&format!("{}", t.format(fmt))),
195 ChronoFmtType::Rfc3339Opts(secs_fmt, z) => {
196 w.write_str(&format!("{}", t.to_rfc3339_opts(*secs_fmt, *z)))
197 }
198 }
199 }
200}
201
202#[derive(Debug, Clone, Eq, PartialEq, Default)]
215enum ChronoFmtType {
216 #[default]
218 Rfc3339,
219 Rfc3339Opts(chrono::SecondsFormat, bool),
222 Custom(String),
224}
225
226#[cfg(test)]
229mod tests {
230 use crate::fmt::format::Writer;
231 use crate::fmt::time::FormatTime;
232
233 use std::sync::Arc;
234
235 use super::ChronoFmtType;
236 use super::ChronoLocal;
237 use super::ChronoUtc;
238
239 #[test]
240 fn test_chrono_format_time_utc_default() {
241 let mut buf = String::new();
242 let mut dst: Writer<'_> = Writer::new(&mut buf);
243 assert!(FormatTime::format_time(&ChronoUtc::default(), &mut dst).is_ok());
244 assert!(chrono::DateTime::parse_from_str(&buf, "%FT%H:%M:%S%.6f%z").is_ok());
246 }
247
248 #[test]
249 fn test_chrono_format_time_utc_custom() {
250 let fmt = ChronoUtc {
251 format: Arc::new(ChronoFmtType::Custom("%a %b %e %T %Y".to_owned())),
252 };
253 let mut buf = String::new();
254 let mut dst: Writer<'_> = Writer::new(&mut buf);
255 assert!(FormatTime::format_time(&fmt, &mut dst).is_ok());
256 assert!(chrono::NaiveDateTime::parse_from_str(&buf, "%a %b %e %T %Y").is_ok());
258 }
259
260 #[test]
261 fn test_chrono_format_time_local_default() {
262 let mut buf = String::new();
263 let mut dst: Writer<'_> = Writer::new(&mut buf);
264 assert!(FormatTime::format_time(&ChronoLocal::default(), &mut dst).is_ok());
265 assert!(chrono::DateTime::parse_from_str(&buf, "%FT%H:%M:%S%.6f%z").is_ok());
267 }
268
269 #[test]
270 fn test_chrono_format_time_local_custom() {
271 let fmt = ChronoLocal {
272 format: Arc::new(ChronoFmtType::Custom("%a %b %e %T %Y".to_owned())),
273 };
274 let mut buf = String::new();
275 let mut dst: Writer<'_> = Writer::new(&mut buf);
276 assert!(FormatTime::format_time(&fmt, &mut dst).is_ok());
277 assert!(chrono::NaiveDateTime::parse_from_str(&buf, "%a %b %e %T %Y").is_ok());
279 }
280}