livesplit_core/timing/formatter/
regular.rs1use super::{
2 format_padded, Accuracy, TimeFormatter, DASH, MINUS, SECONDS_PER_HOUR, SECONDS_PER_MINUTE,
3};
4use crate::TimeSpan;
5use core::fmt::{Display, Formatter, Result};
6
7pub struct Inner {
8 time: Option<TimeSpan>,
9 accuracy: Accuracy,
10}
11
12pub struct Regular {
28 accuracy: Accuracy,
29}
30
31impl Regular {
32 pub const fn new() -> Self {
35 Regular {
36 accuracy: Accuracy::Seconds,
37 }
38 }
39
40 pub const fn with_accuracy(accuracy: Accuracy) -> Self {
43 Regular { accuracy }
44 }
45}
46
47impl Default for Regular {
48 fn default() -> Self {
49 Self::new()
50 }
51}
52
53impl TimeFormatter<'_> for Regular {
54 type Inner = Inner;
55
56 fn format<T>(&self, time: T) -> Self::Inner
57 where
58 T: Into<Option<TimeSpan>>,
59 {
60 Inner {
61 time: time.into(),
62 accuracy: self.accuracy,
63 }
64 }
65}
66
67impl Display for Inner {
68 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
69 if let Some(time) = self.time {
70 let (total_seconds, nanoseconds) = time.to_seconds_and_subsec_nanoseconds();
71 let (total_seconds, nanoseconds) = if (total_seconds | nanoseconds as i64) < 0 {
72 f.write_str(MINUS)?;
73 ((-total_seconds) as u64, (-nanoseconds) as u32)
74 } else {
75 (total_seconds as u64, nanoseconds as u32)
76 };
77 let seconds = (total_seconds % SECONDS_PER_MINUTE) as u8;
82 let minutes = ((total_seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE) as u8;
83 let hours = total_seconds / SECONDS_PER_HOUR;
84
85 let mut buffer = itoa::Buffer::new();
86
87 if hours > 0 {
88 f.write_str(buffer.format(hours))?;
89 f.write_str(":")?;
90 f.write_str(format_padded(minutes))?;
91 } else {
92 f.write_str(buffer.format(minutes))?;
93 }
94 f.write_str(":")?;
95 f.write_str(format_padded(seconds))?;
96 self.accuracy.format_nanoseconds(nanoseconds).fmt(f)
97 } else {
98 f.write_str(DASH)
99 }
100 }
101}