diff --git a/src/app.rs b/src/app.rs index 7e4487d..490de75 100644 --- a/src/app.rs +++ b/src/app.rs @@ -232,13 +232,19 @@ impl App { style: self.style, with_decis: self.with_decis, pomodoro_mode: self.pomodoro.get_mode().clone(), - inital_value_work: self.pomodoro.get_clock_work().initial_value, - current_value_work: self.pomodoro.get_clock_work().current_value, - inital_value_pause: self.pomodoro.get_clock_pause().initial_value, - current_value_pause: self.pomodoro.get_clock_pause().current_value, - inital_value_countdown: self.countdown.get_clock().initial_value, - current_value_countdown: self.countdown.get_clock().current_value, - current_value_timer: self.timer.get_clock().current_value, + inital_value_work: Duration::from(*self.pomodoro.get_clock_work().get_initial_value()), + current_value_work: Duration::from(*self.pomodoro.get_clock_work().get_current_value()), + inital_value_pause: Duration::from( + *self.pomodoro.get_clock_pause().get_initial_value(), + ), + current_value_pause: Duration::from( + *self.pomodoro.get_clock_pause().get_current_value(), + ), + inital_value_countdown: Duration::from(*self.countdown.get_clock().get_initial_value()), + current_value_countdown: Duration::from( + *self.countdown.get_clock().get_current_value(), + ), + current_value_timer: Duration::from(*self.timer.get_clock().get_current_value()), } } } diff --git a/src/duration.rs b/src/duration.rs new file mode 100644 index 0000000..c5357df --- /dev/null +++ b/src/duration.rs @@ -0,0 +1,143 @@ +use std::fmt; +use std::time::Duration; + +pub const ONE_SECOND: Duration = Duration::from_secs(1); +pub const ONE_MINUTE: Duration = Duration::from_secs(SECS_PER_MINUTE); +pub const ONE_HOUR: Duration = Duration::from_secs(MINS_PER_HOUR * SECS_PER_MINUTE); + +// unstable +// https://doc.rust-lang.org/src/core/time.rs.html#32 +pub const SECS_PER_MINUTE: u64 = 60; +// unstable +// https://doc.rust-lang.org/src/core/time.rs.html#34 +pub const MINS_PER_HOUR: u64 = 60; +// unstable +// https://doc.rust-lang.org/src/core/time.rs.html#36 +const HOURS_PER_DAY: u64 = 24; + +#[derive(Debug, Clone, Copy, PartialOrd)] +pub struct DurationEx { + inner: Duration, +} + +impl PartialEq for DurationEx { + fn eq(&self, other: &Self) -> bool { + self.inner == other.inner + } +} + +impl From for DurationEx { + fn from(inner: Duration) -> Self { + Self { inner } + } +} + +impl From for Duration { + fn from(ex: DurationEx) -> Self { + ex.inner + } +} + +impl DurationEx { + pub fn seconds(&self) -> u64 { + self.inner.as_secs() + } + + pub fn seconds_mod(&self) -> u64 { + self.seconds() % SECS_PER_MINUTE + } + + pub fn hours(&self) -> u64 { + self.seconds() / (SECS_PER_MINUTE * MINS_PER_HOUR) + } + + pub fn hours_mod(&self) -> u64 { + self.hours() % HOURS_PER_DAY + } + + pub fn minutes(&self) -> u64 { + self.seconds() / MINS_PER_HOUR + } + + pub fn minutes_mod(&self) -> u64 { + self.minutes() % SECS_PER_MINUTE + } + + // deciseconds + pub fn decis(&self) -> u64 { + (self.inner.subsec_millis() / 100) as u64 + } + // milliseconds + pub fn millis(&self) -> u128 { + self.inner.as_millis() + } + + pub fn saturating_add(&self, ex: DurationEx) -> Self { + let inner = self.inner.saturating_add(ex.inner); + Self { inner } + } + + pub fn saturating_sub(&self, ex: DurationEx) -> Self { + let inner = self.inner.saturating_sub(ex.inner); + Self { inner } + } +} + +impl fmt::Display for DurationEx { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.hours() >= 10 { + write!( + f, + "{:02}:{:02}:{:02}", + self.hours_mod(), + self.minutes_mod(), + self.seconds_mod(), + ) + } else if self.hours() >= 1 { + write!( + f, + "{}:{:02}:{:02}", + self.hours(), + self.minutes_mod(), + self.seconds_mod() + ) + } else if self.minutes() >= 10 { + write!(f, "{:02}:{:02}", self.minutes_mod(), self.seconds_mod()) + } else if self.minutes() >= 1 { + write!(f, "{}:{:02}", self.minutes(), self.seconds_mod()) + } else if self.seconds() >= 10 { + write!(f, "{:02}", self.seconds_mod()) + } else { + write!(f, "{}", self.seconds()) + } + } +} + +#[cfg(test)] +mod tests { + + use super::*; + use std::time::Duration; + + #[test] + fn test_fmt() { + // hh:mm:ss + let ex: DurationEx = Duration::from_secs(36001).into(); + assert_eq!(format!("{}", ex), "10:00:01"); + // h:mm:ss + let ex: DurationEx = Duration::from_secs(3601).into(); + assert_eq!(format!("{}", ex), "1:00:01"); + // mm:ss + let ex: DurationEx = Duration::from_secs(71).into(); + assert_eq!(format!("{}", ex), "1:11"); + // m:ss + let ex: DurationEx = Duration::from_secs(61).into(); + assert_eq!(format!("{}", ex), "1:01"); + // ss + let ex: DurationEx = Duration::from_secs(11).into(); + assert_eq!(format!("{}", ex), "11"); + // s + let ex: DurationEx = Duration::from_secs(1).into(); + assert_eq!(format!("{}", ex), "1"); + } +} diff --git a/src/main.rs b/src/main.rs index 0be7bd3..68c70bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ mod events; mod logging; mod args; +mod duration; mod storage; mod terminal; mod utils; diff --git a/src/widgets/clock.rs b/src/widgets/clock.rs index 220cfd6..71b8e6b 100644 --- a/src/widgets/clock.rs +++ b/src/widgets/clock.rs @@ -12,7 +12,14 @@ use ratatui::{ widgets::StatefulWidget, }; -use crate::utils::center_horizontal; +use crate::{ + duration::{DurationEx, MINS_PER_HOUR, ONE_HOUR, ONE_MINUTE, ONE_SECOND, SECS_PER_MINUTE}, + utils::center_horizontal, +}; + +// max. 99:59:59 +const MAX_DURATION: Duration = + Duration::from_secs(100 * MINS_PER_HOUR * SECS_PER_MINUTE).saturating_sub(ONE_SECOND); #[derive(Debug, Copy, Clone, Display, PartialEq, Eq)] pub enum Time { @@ -49,24 +56,6 @@ impl fmt::Display for Mode { } } -// unstable -// https://doc.rust-lang.org/src/core/time.rs.html#32 -const SECS_PER_MINUTE: u64 = 60; -// unstable -// https://doc.rust-lang.org/src/core/time.rs.html#34 -const MINS_PER_HOUR: u64 = 60; -// unstable -// https://doc.rust-lang.org/src/core/time.rs.html#36 -const HOURS_PER_DAY: u64 = 24; - -// max. 99:59:59 -const MAX_DURATION: Duration = - Duration::from_secs(100 * MINS_PER_HOUR * SECS_PER_MINUTE).saturating_sub(ONE_SECOND); - -const ONE_SECOND: Duration = Duration::from_secs(1); -const ONE_MINUTE: Duration = Duration::from_secs(SECS_PER_MINUTE); -const ONE_HOUR: Duration = Duration::from_secs(MINS_PER_HOUR * SECS_PER_MINUTE); - #[derive(Debug, Copy, Clone, PartialEq, Eq, Display, PartialOrd, Ord)] pub enum Format { S, @@ -115,9 +104,9 @@ impl Style { #[derive(Debug, Clone)] pub struct Clock { - pub initial_value: Duration, - pub current_value: Duration, - tick_value: Duration, + initial_value: DurationEx, + current_value: DurationEx, + tick_value: DurationEx, mode: Mode, format: Format, pub style: Style, @@ -142,17 +131,25 @@ impl Clock { } } + pub fn get_initial_value(&self) -> &DurationEx { + &self.initial_value + } + + pub fn get_current_value(&self) -> &DurationEx { + &self.current_value + } + pub fn toggle_edit(&mut self) { self.mode = match self.mode.clone() { Mode::Editable(_, prev) => { let p = *prev; // special cases: Should `Mode` be updated? // 1. `Done` -> `Initial` ? - if p == Mode::Done && self.current_value.gt(&Duration::ZERO) { + if p == Mode::Done && self.current_value.gt(&Duration::ZERO.into()) { Mode::Initial } // 2. `_` -> `Done` ? - else if p != Mode::Done && self.current_value.eq(&Duration::ZERO) { + else if p != Mode::Done && self.current_value.eq(&Duration::ZERO.into()) { Mode::Done } // 3. `_` -> `_` (no change) @@ -171,14 +168,14 @@ impl Clock { } pub fn edit_current_up(&mut self) { - self.current_value = match self.mode { + match self.mode { Mode::Editable(Time::Seconds, _) => { if self .current_value // < 99:59:58 - .le(&MAX_DURATION.saturating_sub(ONE_SECOND)) + .le(&MAX_DURATION.saturating_sub(ONE_SECOND).into()) { - self.current_value.saturating_add(ONE_SECOND) + self.current_value.saturating_add(ONE_SECOND.into()) } else { self.current_value } @@ -187,9 +184,9 @@ impl Clock { if self .current_value // < 99:58:59 - .le(&MAX_DURATION.saturating_sub(ONE_MINUTE)) + .le(&MAX_DURATION.saturating_sub(ONE_MINUTE).into()) { - self.current_value.saturating_add(ONE_MINUTE) + self.current_value.saturating_add(ONE_MINUTE.into()) } else { self.current_value } @@ -198,9 +195,9 @@ impl Clock { if self .current_value // < 98:59:59 - .lt(&MAX_DURATION.saturating_sub(ONE_HOUR)) + .lt(&MAX_DURATION.saturating_sub(ONE_HOUR).into()) { - self.current_value.saturating_add(ONE_HOUR) + self.current_value.saturating_add(ONE_HOUR.into()) } else { self.current_value } @@ -211,9 +208,13 @@ impl Clock { } pub fn edit_current_down(&mut self) { self.current_value = match self.mode { - Mode::Editable(Time::Seconds, _) => self.current_value.saturating_sub(ONE_SECOND), - Mode::Editable(Time::Minutes, _) => self.current_value.saturating_sub(ONE_MINUTE), - Mode::Editable(Time::Hours, _) => self.current_value.saturating_sub(ONE_HOUR), + Mode::Editable(Time::Seconds, _) => { + self.current_value.saturating_sub(ONE_SECOND.into()) + } + Mode::Editable(Time::Minutes, _) => { + self.current_value.saturating_sub(ONE_MINUTE.into()) + } + Mode::Editable(Time::Hours, _) => self.current_value.saturating_sub(ONE_HOUR.into()), _ => self.current_value, }; self.update_format(); @@ -285,35 +286,6 @@ impl Clock { self.update_format(); } - fn current_hours(&self) -> u64 { - self.current_seconds() / (SECS_PER_MINUTE * MINS_PER_HOUR) - } - - fn current_hours_mod(&self) -> u64 { - self.current_hours() % HOURS_PER_DAY - } - - fn current_minutes(&self) -> u64 { - self.current_seconds() / MINS_PER_HOUR - } - - fn current_minutes_mod(&self) -> u64 { - self.current_minutes() % SECS_PER_MINUTE - } - - fn current_seconds(&self) -> u64 { - self.current_value.as_secs() - } - - fn current_seconds_mod(&self) -> u64 { - self.current_seconds() % SECS_PER_MINUTE - } - - // deciseconds - fn current_decis(&self) -> u64 { - (self.current_value.subsec_millis() / 100) as u64 - } - pub fn is_done(&self) -> bool { self.mode == Mode::Done } @@ -323,15 +295,15 @@ impl Clock { } pub fn get_format(&self) -> Format { - if self.current_hours() >= 10 { + if self.current_value.hours() >= 10 { Format::HhMmSs - } else if self.current_hours() >= 1 { + } else if self.current_value.hours() >= 1 { Format::HMmSs - } else if self.current_minutes() >= 10 { + } else if self.current_value.minutes() >= 10 { Format::MmSs - } else if self.current_minutes() >= 1 { + } else if self.current_value.minutes() >= 1 { Format::MSs - } else if self.current_seconds() >= 10 { + } else if self.current_value.seconds() >= 10 { Format::Ss } else { Format::S @@ -339,19 +311,6 @@ impl Clock { } } -impl fmt::Display for Clock { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{:02}:{:02}:{:02}.{}", - self.current_hours_mod(), - self.current_minutes_mod(), - self.current_seconds_mod(), - self.current_decis() - ) - } -} - #[derive(Debug, Clone)] pub struct Countdown {} @@ -365,9 +324,9 @@ impl Clock { with_decis, } = args; let mut instance = Self { - initial_value, - current_value, - tick_value, + initial_value: initial_value.into(), + current_value: current_value.into(), + tick_value: tick_value.into(), mode: if current_value == Duration::ZERO { Mode::Done } else if current_value == initial_value { @@ -394,19 +353,15 @@ impl Clock { } fn set_done(&mut self) { - if self.current_value.is_zero() { + if self.current_value.eq(&Duration::ZERO.into()) { self.mode = Mode::Done; } } pub fn get_percentage_done(&self) -> u16 { - let initial = self.initial_value.as_millis(); - let elapsed = self - .initial_value - .saturating_sub(self.current_value) - .as_millis(); + let elapsed = self.initial_value.saturating_sub(self.current_value); - (elapsed * 100 / initial) as u16 + (elapsed.millis() * 100 / self.initial_value.millis()) as u16 } pub fn edit_next(&mut self) { @@ -447,9 +402,9 @@ impl Clock { with_decis, } = args; let mut instance = Self { - initial_value, - current_value, - tick_value, + initial_value: initial_value.into(), + current_value: current_value.into(), + tick_value: tick_value.into(), mode: if current_value == initial_value { Mode::Initial } else if current_value >= MAX_DURATION { @@ -469,14 +424,14 @@ impl Clock { pub fn tick(&mut self) { if self.mode == Mode::Tick { - self.current_value = self.current_value.saturating_add(self.tick_value); + self.current_value.saturating_add(self.tick_value); self.set_done(); self.update_format(); } } fn set_done(&mut self) { - if self.current_value >= MAX_DURATION { + if self.current_value.ge(&MAX_DURATION.into()) { self.mode = Mode::Done; } } @@ -846,197 +801,341 @@ where Format::HhMmSs if with_decis => { let [hh, _, h, c_hm, mm, _, m, c_ms, ss, _, s, d, ds] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_hours() / 10, symbol, edit_hours, hh, buf); - self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf); + self.render_digit( + state.current_value.hours() / 10, + symbol, + edit_hours, + hh, + buf, + ); + self.render_digit(state.current_value.hours() % 10, symbol, edit_hours, h, buf); self.render_colon(symbol, c_hm, buf); self.render_digit( - state.current_minutes_mod() / 10, + state.current_value.minutes_mod() / 10, symbol, edit_minutes, mm, buf, ); self.render_digit( - state.current_minutes_mod() % 10, + state.current_value.minutes_mod() % 10, symbol, edit_minutes, m, buf, ); self.render_colon(symbol, c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); self.render_dot(symbol, d, buf); - self.render_digit(state.current_decis(), symbol, false, ds, buf); + self.render_digit(state.current_value.decis(), symbol, false, ds, buf); } Format::HhMmSs => { let [hh, _, h, c_hm, mm, _, m, c_ms, ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_hours() / 10, symbol, edit_hours, hh, buf); - self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf); + self.render_digit( + state.current_value.hours() / 10, + symbol, + edit_hours, + hh, + buf, + ); + self.render_digit(state.current_value.hours() % 10, symbol, edit_hours, h, buf); self.render_colon(symbol, c_hm, buf); self.render_digit( - state.current_minutes_mod() / 10, + state.current_value.minutes_mod() / 10, symbol, edit_minutes, mm, buf, ); self.render_digit( - state.current_minutes_mod() % 10, + state.current_value.minutes_mod() % 10, symbol, edit_minutes, m, buf, ); self.render_colon(symbol, c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); } Format::HMmSs if with_decis => { let [h, c_hm, mm, _, m, c_ms, ss, _, s, d, ds] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf); + self.render_digit(state.current_value.hours() % 10, symbol, edit_hours, h, buf); self.render_colon(symbol, c_hm, buf); self.render_digit( - state.current_minutes_mod() / 10, + state.current_value.minutes_mod() / 10, symbol, edit_minutes, mm, buf, ); self.render_digit( - state.current_minutes_mod() % 10, + state.current_value.minutes_mod() % 10, symbol, edit_minutes, m, buf, ); self.render_colon(symbol, c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); self.render_dot(symbol, d, buf); - self.render_digit(state.current_decis(), symbol, false, ds, buf); + self.render_digit(state.current_value.decis(), symbol, false, ds, buf); } Format::HMmSs => { let [h, c_hm, mm, _, m, c_ms, ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf); + self.render_digit(state.current_value.hours() % 10, symbol, edit_hours, h, buf); self.render_colon(symbol, c_hm, buf); self.render_digit( - state.current_minutes_mod() / 10, + state.current_value.minutes_mod() / 10, symbol, edit_minutes, mm, buf, ); self.render_digit( - state.current_minutes_mod() % 10, + state.current_value.minutes_mod() % 10, symbol, edit_minutes, m, buf, ); self.render_colon(symbol, c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); } Format::MmSs if with_decis => { let [mm, _, m, c_ms, ss, _, s, d, ds] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); self.render_digit( - state.current_minutes_mod() / 10, + state.current_value.minutes_mod() / 10, symbol, edit_minutes, mm, buf, ); self.render_digit( - state.current_minutes_mod() % 10, + state.current_value.minutes_mod() % 10, symbol, edit_minutes, m, buf, ); self.render_colon(symbol, c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); self.render_dot(symbol, d, buf); - self.render_digit(state.current_decis(), symbol, false, ds, buf); + self.render_digit(state.current_value.decis(), symbol, false, ds, buf); } Format::MmSs => { let [mm, _, m, c_ms, ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); self.render_digit( - state.current_minutes_mod() / 10, + state.current_value.minutes_mod() / 10, symbol, edit_minutes, mm, buf, ); self.render_digit( - state.current_minutes_mod() % 10, + state.current_value.minutes_mod() % 10, symbol, edit_minutes, m, buf, ); self.render_colon(symbol, c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); } Format::MSs if with_decis => { let [m, c_ms, ss, _, s, d, ds] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); self.render_digit( - state.current_minutes_mod() % 10, + state.current_value.minutes_mod() % 10, symbol, edit_minutes, m, buf, ); self.render_colon(symbol, c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); self.render_dot(symbol, d, buf); - self.render_digit(state.current_decis(), symbol, false, ds, buf); + self.render_digit(state.current_value.decis(), symbol, false, ds, buf); } Format::MSs => { let [m, c_ms, ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); self.render_digit( - state.current_minutes_mod() % 10, + state.current_value.minutes_mod() % 10, symbol, edit_minutes, m, buf, ); self.render_colon(symbol, c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); } Format::Ss if state.with_decis => { let [ss, _, s, d, ds] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); self.render_dot(symbol, d, buf); - self.render_digit(state.current_decis(), symbol, false, ds, buf); + self.render_digit(state.current_value.decis(), symbol, false, ds, buf); } Format::Ss => { let [ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() / 10, + symbol, + edit_secs, + ss, + buf, + ); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); } Format::S if with_decis => { let [s, d, ds] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); self.render_dot(symbol, d, buf); - self.render_digit(state.current_decis(), symbol, false, ds, buf); + self.render_digit(state.current_value.decis(), symbol, false, ds, buf); } Format::S => { let [s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_digit( + state.current_value.seconds_mod() % 10, + symbol, + edit_secs, + s, + buf, + ); } } }