livesplit_core/timing/formatter/
days.rs1use super::{
2 format_padded, TimeFormatter, MINUS, SECONDS_PER_DAY, 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}
10
11#[derive(Default)]
25pub struct Days;
26
27impl Days {
28 pub const fn new() -> Self {
30 Days
31 }
32}
33
34impl TimeFormatter<'_> for Days {
35 type Inner = Inner;
36
37 fn format<T>(&self, time: T) -> Self::Inner
38 where
39 T: Into<Option<TimeSpan>>,
40 {
41 Inner { time: time.into() }
42 }
43}
44
45impl Display for Inner {
46 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
47 if let Some(time) = self.time {
48 let (total_seconds, nanoseconds) = time.to_seconds_and_subsec_nanoseconds();
49 let total_seconds = if (total_seconds | nanoseconds as i64) < 0 {
50 f.write_str(MINUS)?;
51 (-total_seconds) as u64
52 } else {
53 total_seconds as u64
54 };
55 let seconds = (total_seconds % SECONDS_PER_MINUTE) as u8;
60 let minutes = ((total_seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE) as u8;
61 let hours = ((total_seconds % SECONDS_PER_DAY) / SECONDS_PER_HOUR) as u8;
62 let days = total_seconds / SECONDS_PER_DAY;
63
64 let mut buffer = itoa::Buffer::new();
65
66 if days > 0 {
67 f.write_str(buffer.format(days))?;
68 f.write_str("d ")?;
69 }
70
71 if days > 0 || hours > 0 {
72 f.write_str(buffer.format(hours))?;
73 f.write_str(":")?;
74 f.write_str(format_padded(minutes))?;
75 } else {
76 f.write_str(buffer.format(minutes))?;
77 }
78 f.write_str(":")?;
79 f.write_str(format_padded(seconds))
80 } else {
81 f.write_str("0:00")
82 }
83 }
84}