nt_time/file_time/
fmt.rs

1// SPDX-FileCopyrightText: 2023 Shun Sakai
2//
3// SPDX-License-Identifier: Apache-2.0 OR MIT
4
5//! Utilities for formatting and printing [`FileTime`].
6
7use core::fmt;
8
9use super::FileTime;
10
11impl fmt::Display for FileTime {
12    /// Shows the underlying [`u64`] value of this `FileTime`.
13    ///
14    /// # Examples
15    ///
16    /// ```
17    /// # use nt_time::FileTime;
18    /// #
19    /// assert_eq!(format!("{}", FileTime::NT_TIME_EPOCH), "0");
20    /// assert_eq!(format!("{}", FileTime::UNIX_EPOCH), "116444736000000000");
21    /// assert_eq!(format!("{}", FileTime::SIGNED_MAX), "9223372036854775807");
22    /// assert_eq!(format!("{}", FileTime::MAX), "18446744073709551615");
23    /// ```
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        u64::from(*self).fmt(f)
26    }
27}
28
29impl fmt::Octal for FileTime {
30    /// Shows the underlying [`u64`] value of this `FileTime`.
31    ///
32    /// # Examples
33    ///
34    /// ```
35    /// # use nt_time::FileTime;
36    /// #
37    /// assert_eq!(format!("{:#o}", FileTime::NT_TIME_EPOCH), "0o0");
38    /// assert_eq!(
39    ///     format!("{:022o}", FileTime::UNIX_EPOCH),
40    ///     "0006355435732517500000"
41    /// );
42    /// assert_eq!(
43    ///     format!("{:#024o}", FileTime::SIGNED_MAX),
44    ///     "0o0777777777777777777777"
45    /// );
46    /// assert_eq!(format!("{:o}", FileTime::MAX), "1777777777777777777777");
47    /// ```
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        u64::from(*self).fmt(f)
50    }
51}
52
53impl fmt::LowerHex for FileTime {
54    /// Shows the underlying [`u64`] value of this `FileTime`.
55    ///
56    /// # Examples
57    ///
58    /// ```
59    /// # use nt_time::FileTime;
60    /// #
61    /// assert_eq!(format!("{:#x}", FileTime::NT_TIME_EPOCH), "0x0");
62    /// assert_eq!(format!("{:016x}", FileTime::UNIX_EPOCH), "019db1ded53e8000");
63    /// assert_eq!(
64    ///     format!("{:#018x}", FileTime::SIGNED_MAX),
65    ///     "0x7fffffffffffffff"
66    /// );
67    /// assert_eq!(format!("{:x}", FileTime::MAX), "ffffffffffffffff");
68    /// ```
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        u64::from(*self).fmt(f)
71    }
72}
73
74impl fmt::UpperHex for FileTime {
75    /// Shows the underlying [`u64`] value of this `FileTime`.
76    ///
77    /// # Examples
78    ///
79    /// ```
80    /// # use nt_time::FileTime;
81    /// #
82    /// assert_eq!(format!("{:#X}", FileTime::NT_TIME_EPOCH), "0x0");
83    /// assert_eq!(format!("{:016X}", FileTime::UNIX_EPOCH), "019DB1DED53E8000");
84    /// assert_eq!(
85    ///     format!("{:#018X}", FileTime::SIGNED_MAX),
86    ///     "0x7FFFFFFFFFFFFFFF"
87    /// );
88    /// assert_eq!(format!("{:X}", FileTime::MAX), "FFFFFFFFFFFFFFFF");
89    /// ```
90    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91        u64::from(*self).fmt(f)
92    }
93}
94
95impl fmt::Binary for FileTime {
96    /// Shows the underlying [`u64`] value of this `FileTime`.
97    ///
98    /// # Examples
99    ///
100    /// ```
101    /// # use nt_time::FileTime;
102    /// #
103    /// assert_eq!(format!("{:#b}", FileTime::NT_TIME_EPOCH), "0b0");
104    /// assert_eq!(
105    ///     format!("{:064b}", FileTime::UNIX_EPOCH),
106    ///     "0000000110011101101100011101111011010101001111101000000000000000"
107    /// );
108    /// assert_eq!(
109    ///     format!("{:#066b}", FileTime::SIGNED_MAX),
110    ///     "0b0111111111111111111111111111111111111111111111111111111111111111"
111    /// );
112    /// assert_eq!(
113    ///     format!("{:b}", FileTime::MAX),
114    ///     "1111111111111111111111111111111111111111111111111111111111111111"
115    /// );
116    /// ```
117    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118        u64::from(*self).fmt(f)
119    }
120}
121
122impl fmt::LowerExp for FileTime {
123    /// Shows the underlying [`u64`] value of this `FileTime`.
124    ///
125    /// # Examples
126    ///
127    /// ```
128    /// # use nt_time::FileTime;
129    /// #
130    /// assert_eq!(
131    ///     format!("{:024e}", FileTime::NT_TIME_EPOCH),
132    ///     "0000000000000000000000e0"
133    /// );
134    /// assert_eq!(format!("{:e}", FileTime::UNIX_EPOCH), "1.16444736e17");
135    /// assert_eq!(
136    ///     format!("{:024e}", FileTime::SIGNED_MAX),
137    ///     "09.223372036854775807e18"
138    /// );
139    /// assert_eq!(format!("{:e}", FileTime::MAX), "1.8446744073709551615e19");
140    /// ```
141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142        u64::from(*self).fmt(f)
143    }
144}
145
146impl fmt::UpperExp for FileTime {
147    /// Shows the underlying [`u64`] value of this `FileTime`.
148    ///
149    /// # Examples
150    ///
151    /// ```
152    /// # use nt_time::FileTime;
153    /// #
154    /// assert_eq!(
155    ///     format!("{:024E}", FileTime::NT_TIME_EPOCH),
156    ///     "0000000000000000000000E0"
157    /// );
158    /// assert_eq!(format!("{:E}", FileTime::UNIX_EPOCH), "1.16444736E17");
159    /// assert_eq!(
160    ///     format!("{:024E}", FileTime::SIGNED_MAX),
161    ///     "09.223372036854775807E18"
162    /// );
163    /// assert_eq!(format!("{:E}", FileTime::MAX), "1.8446744073709551615E19");
164    /// ```
165    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166        u64::from(*self).fmt(f)
167    }
168}
169
170#[cfg(test)]
171mod tests {
172    #[cfg(feature = "std")]
173    use proptest::prop_assert_eq;
174    #[cfg(feature = "std")]
175    use test_strategy::proptest;
176
177    use super::*;
178
179    #[test]
180    fn debug() {
181        assert_eq!(format!("{:?}", FileTime::NT_TIME_EPOCH), "FileTime(0)");
182        assert_eq!(
183            format!("{:?}", FileTime::UNIX_EPOCH),
184            "FileTime(116444736000000000)"
185        );
186        assert_eq!(
187            format!("{:?}", FileTime::SIGNED_MAX),
188            "FileTime(9223372036854775807)"
189        );
190        assert_eq!(
191            format!("{:?}", FileTime::MAX),
192            "FileTime(18446744073709551615)"
193        );
194    }
195
196    #[test]
197    fn display() {
198        assert_eq!(format!("{}", FileTime::NT_TIME_EPOCH), "0");
199        assert_eq!(format!("{}", FileTime::UNIX_EPOCH), "116444736000000000");
200        assert_eq!(format!("{}", FileTime::SIGNED_MAX), "9223372036854775807");
201        assert_eq!(format!("{}", FileTime::MAX), "18446744073709551615");
202    }
203
204    #[cfg(feature = "std")]
205    #[proptest]
206    fn display_roundtrip(ft: FileTime) {
207        prop_assert_eq!(format!("{ft}"), format!("{}", ft.to_raw()));
208    }
209
210    #[test]
211    fn octal() {
212        assert_eq!(format!("{:o}", FileTime::NT_TIME_EPOCH), "0");
213        assert_eq!(format!("{:#o}", FileTime::NT_TIME_EPOCH), "0o0");
214        assert_eq!(
215            format!("{:022o}", FileTime::NT_TIME_EPOCH),
216            "0000000000000000000000"
217        );
218        assert_eq!(
219            format!("{:#024o}", FileTime::NT_TIME_EPOCH),
220            "0o0000000000000000000000"
221        );
222        assert_eq!(format!("{:o}", FileTime::UNIX_EPOCH), "6355435732517500000");
223        assert_eq!(
224            format!("{:#o}", FileTime::UNIX_EPOCH),
225            "0o6355435732517500000"
226        );
227        assert_eq!(
228            format!("{:022o}", FileTime::UNIX_EPOCH),
229            "0006355435732517500000"
230        );
231        assert_eq!(
232            format!("{:#024o}", FileTime::UNIX_EPOCH),
233            "0o0006355435732517500000"
234        );
235        assert_eq!(
236            format!("{:o}", FileTime::SIGNED_MAX),
237            "777777777777777777777"
238        );
239        assert_eq!(
240            format!("{:#o}", FileTime::SIGNED_MAX),
241            "0o777777777777777777777"
242        );
243        assert_eq!(
244            format!("{:022o}", FileTime::SIGNED_MAX),
245            "0777777777777777777777"
246        );
247        assert_eq!(
248            format!("{:#024o}", FileTime::SIGNED_MAX),
249            "0o0777777777777777777777"
250        );
251        assert_eq!(format!("{:o}", FileTime::MAX), "1777777777777777777777");
252        assert_eq!(format!("{:#o}", FileTime::MAX), "0o1777777777777777777777");
253        assert_eq!(format!("{:022o}", FileTime::MAX), "1777777777777777777777");
254        assert_eq!(
255            format!("{:#024o}", FileTime::MAX),
256            "0o1777777777777777777777"
257        );
258    }
259
260    #[cfg(feature = "std")]
261    #[proptest]
262    fn octal_roundtrip(ft: FileTime) {
263        prop_assert_eq!(format!("{ft:o}"), format!("{:o}", ft.to_raw()));
264        prop_assert_eq!(format!("{ft:#o}"), format!("{:#o}", ft.to_raw()));
265        prop_assert_eq!(format!("{ft:022o}"), format!("{:022o}", ft.to_raw()));
266        prop_assert_eq!(format!("{ft:#024o}"), format!("{:#024o}", ft.to_raw()));
267    }
268
269    #[test]
270    fn lower_hex() {
271        assert_eq!(format!("{:x}", FileTime::NT_TIME_EPOCH), "0");
272        assert_eq!(format!("{:#x}", FileTime::NT_TIME_EPOCH), "0x0");
273        assert_eq!(
274            format!("{:016x}", FileTime::NT_TIME_EPOCH),
275            "0000000000000000"
276        );
277        assert_eq!(
278            format!("{:#018x}", FileTime::NT_TIME_EPOCH),
279            "0x0000000000000000"
280        );
281        assert_eq!(format!("{:x}", FileTime::UNIX_EPOCH), "19db1ded53e8000");
282        assert_eq!(format!("{:#x}", FileTime::UNIX_EPOCH), "0x19db1ded53e8000");
283        assert_eq!(format!("{:016x}", FileTime::UNIX_EPOCH), "019db1ded53e8000");
284        assert_eq!(
285            format!("{:#018x}", FileTime::UNIX_EPOCH),
286            "0x019db1ded53e8000"
287        );
288        assert_eq!(format!("{:x}", FileTime::SIGNED_MAX), "7fffffffffffffff");
289        assert_eq!(format!("{:#x}", FileTime::SIGNED_MAX), "0x7fffffffffffffff");
290        assert_eq!(format!("{:016x}", FileTime::SIGNED_MAX), "7fffffffffffffff");
291        assert_eq!(
292            format!("{:#018x}", FileTime::SIGNED_MAX),
293            "0x7fffffffffffffff"
294        );
295        assert_eq!(format!("{:x}", FileTime::MAX), "ffffffffffffffff");
296        assert_eq!(format!("{:#x}", FileTime::MAX), "0xffffffffffffffff");
297        assert_eq!(format!("{:016x}", FileTime::MAX), "ffffffffffffffff");
298        assert_eq!(format!("{:#018x}", FileTime::MAX), "0xffffffffffffffff");
299    }
300
301    #[cfg(feature = "std")]
302    #[proptest]
303    fn lower_hex_roundtrip(ft: FileTime) {
304        prop_assert_eq!(format!("{ft:x}"), format!("{:x}", ft.to_raw()));
305        prop_assert_eq!(format!("{ft:#x}"), format!("{:#x}", ft.to_raw()));
306        prop_assert_eq!(format!("{ft:016x}"), format!("{:016x}", ft.to_raw()));
307        prop_assert_eq!(format!("{ft:#018x}"), format!("{:#018x}", ft.to_raw()));
308    }
309
310    #[test]
311    fn upper_hex() {
312        assert_eq!(format!("{:X}", FileTime::NT_TIME_EPOCH), "0");
313        assert_eq!(format!("{:#X}", FileTime::NT_TIME_EPOCH), "0x0");
314        assert_eq!(
315            format!("{:016X}", FileTime::NT_TIME_EPOCH),
316            "0000000000000000"
317        );
318        assert_eq!(
319            format!("{:#018X}", FileTime::NT_TIME_EPOCH),
320            "0x0000000000000000"
321        );
322        assert_eq!(format!("{:X}", FileTime::UNIX_EPOCH), "19DB1DED53E8000");
323        assert_eq!(format!("{:#X}", FileTime::UNIX_EPOCH), "0x19DB1DED53E8000");
324        assert_eq!(format!("{:016X}", FileTime::UNIX_EPOCH), "019DB1DED53E8000");
325        assert_eq!(
326            format!("{:#018X}", FileTime::UNIX_EPOCH),
327            "0x019DB1DED53E8000"
328        );
329        assert_eq!(format!("{:X}", FileTime::SIGNED_MAX), "7FFFFFFFFFFFFFFF");
330        assert_eq!(format!("{:#X}", FileTime::SIGNED_MAX), "0x7FFFFFFFFFFFFFFF");
331        assert_eq!(format!("{:016X}", FileTime::SIGNED_MAX), "7FFFFFFFFFFFFFFF");
332        assert_eq!(
333            format!("{:#018X}", FileTime::SIGNED_MAX),
334            "0x7FFFFFFFFFFFFFFF"
335        );
336        assert_eq!(format!("{:X}", FileTime::MAX), "FFFFFFFFFFFFFFFF");
337        assert_eq!(format!("{:#X}", FileTime::MAX), "0xFFFFFFFFFFFFFFFF");
338        assert_eq!(format!("{:016X}", FileTime::MAX), "FFFFFFFFFFFFFFFF");
339        assert_eq!(format!("{:#018X}", FileTime::MAX), "0xFFFFFFFFFFFFFFFF");
340    }
341
342    #[cfg(feature = "std")]
343    #[proptest]
344    fn upper_hex_roundtrip(ft: FileTime) {
345        prop_assert_eq!(format!("{ft:X}"), format!("{:X}", ft.to_raw()));
346        prop_assert_eq!(format!("{ft:#X}"), format!("{:#X}", ft.to_raw()));
347        prop_assert_eq!(format!("{ft:016X}"), format!("{:016X}", ft.to_raw()));
348        prop_assert_eq!(format!("{ft:#018X}"), format!("{:#018X}", ft.to_raw()));
349    }
350
351    #[test]
352    fn binary() {
353        assert_eq!(format!("{:b}", FileTime::NT_TIME_EPOCH), "0");
354        assert_eq!(format!("{:#b}", FileTime::NT_TIME_EPOCH), "0b0");
355        assert_eq!(
356            format!("{:064b}", FileTime::NT_TIME_EPOCH),
357            "0000000000000000000000000000000000000000000000000000000000000000"
358        );
359        assert_eq!(
360            format!("{:#066b}", FileTime::NT_TIME_EPOCH),
361            "0b0000000000000000000000000000000000000000000000000000000000000000"
362        );
363        assert_eq!(
364            format!("{:b}", FileTime::UNIX_EPOCH),
365            "110011101101100011101111011010101001111101000000000000000"
366        );
367        assert_eq!(
368            format!("{:#b}", FileTime::UNIX_EPOCH),
369            "0b110011101101100011101111011010101001111101000000000000000"
370        );
371        assert_eq!(
372            format!("{:064b}", FileTime::UNIX_EPOCH),
373            "0000000110011101101100011101111011010101001111101000000000000000"
374        );
375        assert_eq!(
376            format!("{:#066b}", FileTime::UNIX_EPOCH),
377            "0b0000000110011101101100011101111011010101001111101000000000000000"
378        );
379        assert_eq!(
380            format!("{:b}", FileTime::SIGNED_MAX),
381            "111111111111111111111111111111111111111111111111111111111111111"
382        );
383        assert_eq!(
384            format!("{:#b}", FileTime::SIGNED_MAX),
385            "0b111111111111111111111111111111111111111111111111111111111111111"
386        );
387        assert_eq!(
388            format!("{:064b}", FileTime::SIGNED_MAX),
389            "0111111111111111111111111111111111111111111111111111111111111111"
390        );
391        assert_eq!(
392            format!("{:#066b}", FileTime::SIGNED_MAX),
393            "0b0111111111111111111111111111111111111111111111111111111111111111"
394        );
395        assert_eq!(
396            format!("{:b}", FileTime::MAX),
397            "1111111111111111111111111111111111111111111111111111111111111111"
398        );
399        assert_eq!(
400            format!("{:#b}", FileTime::MAX),
401            "0b1111111111111111111111111111111111111111111111111111111111111111"
402        );
403        assert_eq!(
404            format!("{:064b}", FileTime::MAX),
405            "1111111111111111111111111111111111111111111111111111111111111111"
406        );
407        assert_eq!(
408            format!("{:#066b}", FileTime::MAX),
409            "0b1111111111111111111111111111111111111111111111111111111111111111"
410        );
411    }
412
413    #[cfg(feature = "std")]
414    #[proptest]
415    fn binary_roundtrip(ft: FileTime) {
416        prop_assert_eq!(format!("{ft:b}"), format!("{:b}", ft.to_raw()));
417        prop_assert_eq!(format!("{ft:#b}"), format!("{:#b}", ft.to_raw()));
418        prop_assert_eq!(format!("{ft:064b}"), format!("{:064b}", ft.to_raw()));
419        prop_assert_eq!(format!("{ft:#066b}"), format!("{:#066b}", ft.to_raw()));
420    }
421
422    #[test]
423    fn lower_exp() {
424        assert_eq!(format!("{:e}", FileTime::NT_TIME_EPOCH), "0e0");
425        assert_eq!(
426            format!("{:024e}", FileTime::NT_TIME_EPOCH),
427            "0000000000000000000000e0"
428        );
429        assert_eq!(format!("{:e}", FileTime::UNIX_EPOCH), "1.16444736e17");
430        assert_eq!(
431            format!("{:024e}", FileTime::UNIX_EPOCH),
432            "000000000001.16444736e17"
433        );
434        assert_eq!(
435            format!("{:e}", FileTime::SIGNED_MAX),
436            "9.223372036854775807e18"
437        );
438        assert_eq!(
439            format!("{:024e}", FileTime::SIGNED_MAX),
440            "09.223372036854775807e18"
441        );
442        assert_eq!(format!("{:e}", FileTime::MAX), "1.8446744073709551615e19");
443        assert_eq!(
444            format!("{:024e}", FileTime::MAX),
445            "1.8446744073709551615e19"
446        );
447    }
448
449    #[cfg(feature = "std")]
450    #[proptest]
451    fn lower_exp_roundtrip(ft: FileTime) {
452        prop_assert_eq!(format!("{ft:e}"), format!("{:e}", ft.to_raw()));
453        prop_assert_eq!(format!("{ft:024e}"), format!("{:024e}", ft.to_raw()));
454    }
455
456    #[test]
457    fn upper_exp() {
458        assert_eq!(format!("{:E}", FileTime::NT_TIME_EPOCH), "0E0");
459        assert_eq!(
460            format!("{:024E}", FileTime::NT_TIME_EPOCH),
461            "0000000000000000000000E0"
462        );
463        assert_eq!(format!("{:E}", FileTime::UNIX_EPOCH), "1.16444736E17");
464        assert_eq!(
465            format!("{:024E}", FileTime::UNIX_EPOCH),
466            "000000000001.16444736E17"
467        );
468        assert_eq!(
469            format!("{:E}", FileTime::SIGNED_MAX),
470            "9.223372036854775807E18"
471        );
472        assert_eq!(
473            format!("{:024E}", FileTime::SIGNED_MAX),
474            "09.223372036854775807E18"
475        );
476        assert_eq!(format!("{:E}", FileTime::MAX), "1.8446744073709551615E19");
477        assert_eq!(
478            format!("{:024E}", FileTime::MAX),
479            "1.8446744073709551615E19"
480        );
481    }
482
483    #[cfg(feature = "std")]
484    #[proptest]
485    fn upper_exp_roundtrip(ft: FileTime) {
486        prop_assert_eq!(format!("{ft:E}"), format!("{:E}", ft.to_raw()));
487        prop_assert_eq!(format!("{ft:024E}"), format!("{:024E}", ft.to_raw()));
488    }
489}