livesplit_core/timing/formatter/
delta.rs1use super::{
2 format_padded, Accuracy, TimeFormatter, DASH, MINUS, PLUS, 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 drop_decimals: bool,
10 accuracy: Accuracy,
11}
12
13pub struct Delta(bool, Accuracy);
30
31impl Delta {
32 pub const fn new() -> Self {
35 Delta(true, Accuracy::Tenths)
36 }
37
38 pub const fn custom(drop_decimals: bool, accuracy: Accuracy) -> Self {
42 Delta(drop_decimals, accuracy)
43 }
44
45 pub const fn with_decimal_dropping() -> Self {
48 Delta(true, Accuracy::Tenths)
49 }
50}
51
52impl Default for Delta {
53 fn default() -> Self {
54 Self::new()
55 }
56}
57
58impl TimeFormatter<'_> for Delta {
59 type Inner = Inner;
60
61 fn format<T>(&self, time: T) -> Self::Inner
62 where
63 T: Into<Option<TimeSpan>>,
64 {
65 Inner {
66 time: time.into(),
67 drop_decimals: self.0,
68 accuracy: self.1,
69 }
70 }
71}
72
73impl Display for Inner {
74 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
75 if let Some(time) = self.time {
76 let (total_seconds, nanoseconds) = time.to_seconds_and_subsec_nanoseconds();
77 let (total_seconds, nanoseconds) = if (total_seconds | nanoseconds as i64) < 0 {
78 f.write_str(MINUS)?;
79 ((-total_seconds) as u64, (-nanoseconds) as u32)
80 } else {
81 f.write_str(PLUS)?;
82 (total_seconds as u64, nanoseconds as u32)
83 };
84 let seconds = (total_seconds % SECONDS_PER_MINUTE) as u8;
89 let minutes = ((total_seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE) as u8;
90 let hours = total_seconds / SECONDS_PER_HOUR;
91
92 let mut buffer = itoa::Buffer::new();
93
94 if hours > 0 {
95 f.write_str(buffer.format(hours))?;
96 f.write_str(":")?;
97 f.write_str(format_padded(minutes))?;
98 f.write_str(":")?;
99 f.write_str(format_padded(seconds))?;
100 } else if minutes > 0 {
101 f.write_str(buffer.format(minutes))?;
102 f.write_str(":")?;
103 f.write_str(format_padded(seconds))?;
104 } else {
105 f.write_str(buffer.format(seconds))?;
106 return self.accuracy.format_nanoseconds(nanoseconds).fmt(f);
107 }
108 if !self.drop_decimals {
109 self.accuracy.format_nanoseconds(nanoseconds).fmt(f)
110 } else {
111 Ok(())
112 }
113 } else {
114 f.write_str(DASH)
115 }
116 }
117}