1use bstr::ByteSlice;
2
3use crate::{SecondsSinceUnixEpoch, Time};
4
5impl std::fmt::Display for Time {
7 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8 let mut buf = Vec::with_capacity(Time::MAX.size());
9 self.write_to(&mut buf).expect("write to memory cannot fail");
10 #[allow(unsafe_code)]
12 let raw = unsafe { buf.to_str_unchecked() };
13 f.write_str(raw)
14 }
15}
16
17impl Time {
19 pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
21 const SECONDS_PER_HOUR: u32 = 60 * 60;
22 let offset = self.offset.unsigned_abs();
23 let hours = offset / SECONDS_PER_HOUR;
24 let minutes = (offset - (hours * SECONDS_PER_HOUR)) / 60;
25
26 if hours > 99 {
27 return Err(std::io::Error::other("Cannot represent offsets larger than +-9900"));
28 }
29
30 let mut itoa = itoa::Buffer::new();
31 out.write_all(itoa.format(self.seconds).as_bytes())?;
32 out.write_all(b" ")?;
33 out.write_all(if self.offset < 0 { b"-" } else { b"+" })?;
34
35 const ZERO: &[u8; 1] = b"0";
36
37 if hours < 10 {
38 out.write_all(ZERO)?;
39 }
40 out.write_all(itoa.format(hours).as_bytes())?;
41
42 if minutes < 10 {
43 out.write_all(ZERO)?;
44 }
45 out.write_all(itoa.format(minutes).as_bytes()).map(|_| ())
46 }
47
48 pub const fn size(&self) -> usize {
50 (if self.seconds >= 1_000_000_000_000_000_000 {
51 19
52 } else if self.seconds >= 100_000_000_000_000_000 {
53 18
54 } else if self.seconds >= 10_000_000_000_000_000 {
55 17
56 } else if self.seconds >= 1_000_000_000_000_000 {
57 16
58 } else if self.seconds >= 100_000_000_000_000 {
59 15
60 } else if self.seconds >= 10_000_000_000_000 {
61 14
62 } else if self.seconds >= 1_000_000_000_000 {
63 13
64 } else if self.seconds >= 100_000_000_000 {
65 12
66 } else if self.seconds >= 10_000_000_000 {
67 11
68 } else if self.seconds >= 1_000_000_000 {
69 10
70 } else if self.seconds >= 100_000_000 {
71 9
72 } else if self.seconds >= 10_000_000 {
73 8
74 } else if self.seconds >= 1_000_000 {
75 7
76 } else if self.seconds >= 100_000 {
77 6
78 } else if self.seconds >= 10_000 {
79 5
80 } else if self.seconds >= 1_000 {
81 4
82 } else if self.seconds >= 100 {
83 3
84 } else if self.seconds >= 10 {
85 2
86 } else if self.seconds >= 0 {
87 1
88 } else if self.seconds >= -10 {
90 2
91 } else if self.seconds >= -100 {
92 3
93 } else if self.seconds >= -1_000 {
94 4
95 } else if self.seconds >= -10_000 {
96 5
97 } else if self.seconds >= -100_000 {
98 6
99 } else if self.seconds >= -1_000_000 {
100 7
101 } else if self.seconds >= -10_000_000 {
102 8
103 } else if self.seconds >= -100_000_000 {
104 9
105 } else if self.seconds >= -1_000_000_000 {
106 10
107 } else if self.seconds >= -10_000_000_000 {
108 11
109 } else if self.seconds >= -100_000_000_000 {
110 12
111 } else if self.seconds >= -1_000_000_000_000 {
112 13
113 } else if self.seconds >= -10_000_000_000_000 {
114 14
115 } else if self.seconds >= -100_000_000_000_000 {
116 15
117 } else if self.seconds >= -1_000_000_000_000_000 {
118 16
119 } else if self.seconds >= -10_000_000_000_000_000 {
120 17
121 } else if self.seconds >= -100_000_000_000_000_000 {
122 18
123 } else if self.seconds >= -1_000_000_000_000_000_000 {
124 19
125 } else {
126 20
127 }) + 2 + 2 + 2 }
129
130 pub const MAX: Time = Time {
133 seconds: SecondsSinceUnixEpoch::MAX,
134 offset: 99 * 60 * 60 + 59 * 60 + 59,
135 };
136}