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