livesplit_core/timing/formatter/
complete.rs1use super::{
2 format_padded, TimeFormatter, ASCII_MINUS, SECONDS_PER_DAY, SECONDS_PER_HOUR,
3 SECONDS_PER_MINUTE,
4};
5use crate::TimeSpan;
6use core::fmt::{Display, Formatter, Result};
7
8pub struct Inner(Option<TimeSpan>);
9
10#[derive(Default)]
27pub struct Complete;
28
29impl Complete {
30 pub const fn new() -> Self {
32 Complete
33 }
34}
35
36impl TimeFormatter<'_> for Complete {
37 type Inner = Inner;
38
39 fn format<T>(&self, time: T) -> Self::Inner
40 where
41 T: Into<Option<TimeSpan>>,
42 {
43 Inner(time.into())
44 }
45}
46
47impl Display for Inner {
48 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
49 if let Some(time) = self.0 {
50 let (total_seconds, nanoseconds) = time.to_seconds_and_subsec_nanoseconds();
51 let (total_seconds, nanoseconds) = if (total_seconds | nanoseconds as i64) < 0 {
52 f.write_str(ASCII_MINUS)?;
55 ((-total_seconds) as u64, (-nanoseconds) as u32)
56 } else {
57 (total_seconds as u64, nanoseconds as u32)
58 };
59 let seconds = (total_seconds % SECONDS_PER_MINUTE) as u8;
64 let minutes = ((total_seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE) as u8;
65 let hours = ((total_seconds % SECONDS_PER_DAY) / SECONDS_PER_HOUR) as u8;
66 let days = total_seconds / SECONDS_PER_DAY;
67
68 let mut buffer = itoa::Buffer::new();
69
70 if days > 0 {
71 f.write_str(buffer.format(days))?;
72 f.write_str(".")?;
73 }
74
75 f.write_str(format_padded(hours))?;
76 f.write_str(":")?;
77 f.write_str(format_padded(minutes))?;
78 f.write_str(":")?;
79 f.write_str(format_padded(seconds))?;
80 f.write_str(".")?;
81 let nanoseconds = buffer.format(nanoseconds);
82 f.write_str(&"000000000"[nanoseconds.len()..])?;
83 f.write_str(nanoseconds)
84 } else {
85 f.write_str("00:00:00.000000000")
86 }
87 }
88}