inrease MAX_DURATION to 9999y 364d 23:59:59.9 (#128)
This commit is contained in:
parent
51f83e5b06
commit
d2f41e04e2
@ -6,6 +6,7 @@
|
||||
|
||||
- (event) New `event` screen to count custom date times in the future or past. [#117](https://github.com/sectore/timr-tui/pull/117), [#120](https://github.com/sectore/timr-tui/pull/120), [#122](https://github.com/sectore/timr-tui/pull/122), [#123](https://github.com/sectore/timr-tui/pull/123), [#124](https://github.com/sectore/timr-tui/pull/124), [#125](https://github.com/sectore/timr-tui/pull/125)
|
||||
- (screens) switch by `←` or `→` keys [#127](https://github.com/sectore/timr-tui/pull/127)
|
||||
- (duration) inrease `MAX_DURATION` to `9999y 364d 23:59:59.9` [#128](https://github.com/sectore/timr-tui/pull/128)
|
||||
|
||||
### Breaking change
|
||||
|
||||
|
||||
@ -31,9 +31,9 @@ pub const ONE_YEAR: Duration =
|
||||
// ^ https://www.math.net/days-in-a-year
|
||||
const DAYS_PER_YEAR: u64 = 365; // ignore leap year of 366 days
|
||||
|
||||
// max. 999y 364d 23:59:59.9 (1000 years - 1 decisecond)
|
||||
// max. 9999y 364d 23:59:59.9 (10k years - 1 decisecond)
|
||||
pub const MAX_DURATION: Duration = ONE_YEAR
|
||||
.saturating_mul(1000)
|
||||
.saturating_mul(10000)
|
||||
.saturating_sub(ONE_DECI_SECOND);
|
||||
|
||||
/// Trait for duration types that can be displayed in clock widgets.
|
||||
@ -678,11 +678,11 @@ mod tests {
|
||||
);
|
||||
|
||||
// MAX_DURATION clamping
|
||||
assert_eq!(parse_long_duration("1000y").unwrap(), MAX_DURATION);
|
||||
assert_eq!(parse_long_duration("10000y").unwrap(), MAX_DURATION);
|
||||
assert_eq!(
|
||||
parse_long_duration("999y 364d 23:59:59").unwrap(),
|
||||
parse_long_duration("9999y 364d 23:59:59").unwrap(),
|
||||
Duration::from_secs(
|
||||
999 * YEAR_IN_SECONDS
|
||||
9999 * YEAR_IN_SECONDS
|
||||
+ 364 * DAY_IN_SECONDS
|
||||
+ 23 * HOUR_IN_SECONDS
|
||||
+ 59 * MINUTE_IN_SECONDS
|
||||
|
||||
@ -11,6 +11,7 @@ use ratatui::{
|
||||
widgets::{StatefulWidget, Widget},
|
||||
};
|
||||
|
||||
use crate::widgets::clock_elements::FOUR_DIGITS_WIDTH;
|
||||
use crate::{
|
||||
common::{ClockTypeId, Style as DigitStyle},
|
||||
duration::{
|
||||
@ -88,10 +89,19 @@ pub enum Format {
|
||||
YyyDHhMmSs,
|
||||
YyyDdHhMmSs,
|
||||
YyyDddHhMmSs,
|
||||
YyyyDHhMmSs,
|
||||
YyyyDdHhMmSs,
|
||||
YyyyDddHhMmSs,
|
||||
}
|
||||
|
||||
pub fn format_by_duration<D: ClockDuration>(d: &D) -> Format {
|
||||
if d.years() >= 100 && d.days_mod() >= 100 {
|
||||
if d.years() >= 1000 && d.days_mod() >= 100 {
|
||||
Format::YyyyDddHhMmSs
|
||||
} else if d.years() >= 1000 && d.days_mod() >= 10 {
|
||||
Format::YyyyDdHhMmSs
|
||||
} else if d.years() >= 1000 && d.days() >= 1 {
|
||||
Format::YyyyDHhMmSs
|
||||
} else if d.years() >= 100 && d.days_mod() >= 100 {
|
||||
Format::YyyDddHhMmSs
|
||||
} else if d.years() >= 100 && d.days_mod() >= 10 {
|
||||
Format::YyyDdHhMmSs
|
||||
@ -140,7 +150,10 @@ pub fn time_by_format(format: &Format) -> Time {
|
||||
| Format::YyDHhMmSs
|
||||
| Format::YyyDddHhMmSs
|
||||
| Format::YyyDdHhMmSs
|
||||
| Format::YyyDHhMmSs => Time::Years,
|
||||
| Format::YyyDHhMmSs
|
||||
| Format::YyyyDddHhMmSs
|
||||
| Format::YyyyDdHhMmSs
|
||||
| Format::YyyyDHhMmSs => Time::Years,
|
||||
Format::DddHhMmSs | Format::DdHhMmSs | Format::DHhMmSs => Time::Days,
|
||||
Format::HhMmSs | Format::HMmSs => Time::Hours,
|
||||
Format::MmSs | Format::MSs => Time::Minutes,
|
||||
@ -677,6 +690,48 @@ pub fn clock_horizontal_lengths(format: &Format, with_decis: bool) -> Vec<u16> {
|
||||
const LABEL_WIDTH: u16 = DIGIT_LABEL_WIDTH + DIGIT_SPACE_WIDTH;
|
||||
|
||||
match format {
|
||||
Format::YyyyDddHhMmSs => add_decis(
|
||||
vec![
|
||||
FOUR_DIGITS_WIDTH, // y_y_y_y
|
||||
LABEL_WIDTH, // _l__
|
||||
THREE_DIGITS_WIDTH, // d_d_d
|
||||
LABEL_WIDTH, // _l__
|
||||
TWO_DIGITS_WIDTH, // h_h
|
||||
COLON_WIDTH, // :
|
||||
TWO_DIGITS_WIDTH, // m_m
|
||||
COLON_WIDTH, // :
|
||||
TWO_DIGITS_WIDTH, // s_s
|
||||
],
|
||||
with_decis,
|
||||
),
|
||||
Format::YyyyDdHhMmSs => add_decis(
|
||||
vec![
|
||||
FOUR_DIGITS_WIDTH, // y_y_y_y
|
||||
LABEL_WIDTH, // _l__
|
||||
TWO_DIGITS_WIDTH, // d_d
|
||||
LABEL_WIDTH, // _l__
|
||||
TWO_DIGITS_WIDTH, // h_h
|
||||
COLON_WIDTH, // :
|
||||
TWO_DIGITS_WIDTH, // m_m
|
||||
COLON_WIDTH, // :
|
||||
TWO_DIGITS_WIDTH, // s_s
|
||||
],
|
||||
with_decis,
|
||||
),
|
||||
Format::YyyyDHhMmSs => add_decis(
|
||||
vec![
|
||||
FOUR_DIGITS_WIDTH, // y_y_y_y
|
||||
LABEL_WIDTH, // _l__
|
||||
DIGIT_WIDTH, // d
|
||||
LABEL_WIDTH, // _l__
|
||||
TWO_DIGITS_WIDTH, // h_h
|
||||
COLON_WIDTH, // :
|
||||
TWO_DIGITS_WIDTH, // m_m
|
||||
COLON_WIDTH, // :
|
||||
TWO_DIGITS_WIDTH, // s_s
|
||||
],
|
||||
with_decis,
|
||||
),
|
||||
Format::YyyDddHhMmSs => add_decis(
|
||||
vec![
|
||||
THREE_DIGITS_WIDTH, // y_y_y
|
||||
@ -922,6 +977,20 @@ pub fn render_clock<D: ClockDuration>(area: Rect, buf: &mut Buffer, state: Rende
|
||||
let edit_secs = matches!(editable_time, Some(Time::Seconds));
|
||||
let edit_decis = matches!(editable_time, Some(Time::Decis));
|
||||
|
||||
let render_four_digits = |d1, d2, d3, d4, editable, area, buf: &mut Buffer| {
|
||||
let [a1, a2, a3, a4] = Layout::horizontal(Constraint::from_lengths([
|
||||
DIGIT_WIDTH + DIGIT_SPACE_WIDTH,
|
||||
DIGIT_WIDTH + DIGIT_SPACE_WIDTH,
|
||||
DIGIT_WIDTH + DIGIT_SPACE_WIDTH,
|
||||
DIGIT_WIDTH,
|
||||
]))
|
||||
.areas(area);
|
||||
Digit::new(d1, editable, symbol).render(a1, buf);
|
||||
Digit::new(d2, editable, symbol).render(a2, buf);
|
||||
Digit::new(d3, editable, symbol).render(a3, buf);
|
||||
Digit::new(d4, editable, symbol).render(a4, buf);
|
||||
};
|
||||
|
||||
let render_three_digits = |d1, d2, d3, editable, area, buf: &mut Buffer| {
|
||||
let [a1, a2, a3] = Layout::horizontal(Constraint::from_lengths([
|
||||
DIGIT_WIDTH + DIGIT_SPACE_WIDTH,
|
||||
@ -952,6 +1021,18 @@ pub fn render_clock<D: ClockDuration>(area: Rect, buf: &mut Buffer, state: Rende
|
||||
Dot::new(symbol).render(area, buf);
|
||||
};
|
||||
|
||||
let render_yyyy = |area, buf| {
|
||||
render_four_digits(
|
||||
(duration.years() / 1000) % 10,
|
||||
(duration.years() / 100) % 10,
|
||||
(duration.years() / 10) % 10,
|
||||
duration.years() % 10,
|
||||
edit_years,
|
||||
area,
|
||||
buf,
|
||||
);
|
||||
};
|
||||
|
||||
let render_yyy = |area, buf| {
|
||||
render_three_digits(
|
||||
(duration.years() / 100) % 10,
|
||||
@ -1065,6 +1146,90 @@ pub fn render_clock<D: ClockDuration>(area: Rect, buf: &mut Buffer, state: Rende
|
||||
};
|
||||
|
||||
match format {
|
||||
Format::YyyyDddHhMmSs if with_decis => {
|
||||
let [y_y_y_y, ly, d_d_d, ld, h_h, c_hm, m_m, c_ms, s_s, dot, ds] =
|
||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||
render_yyyy(y_y_y_y, buf);
|
||||
render_label_y(ly, buf);
|
||||
render_ddd(d_d_d, buf);
|
||||
render_label_d(ld, buf);
|
||||
render_hh(h_h, buf);
|
||||
render_colon(c_hm, buf);
|
||||
render_mm(m_m, buf);
|
||||
render_colon(c_ms, buf);
|
||||
render_ss(s_s, buf);
|
||||
render_dot(dot, buf);
|
||||
render_ds(ds, buf);
|
||||
}
|
||||
Format::YyyyDddHhMmSs => {
|
||||
let [y_y_y_y, ly, d_d_d, ld, h_h, c_hm, m_m, c_ms, s_s] =
|
||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||
render_yyyy(y_y_y_y, buf);
|
||||
render_label_y(ly, buf);
|
||||
render_ddd(d_d_d, buf);
|
||||
render_label_d(ld, buf);
|
||||
render_hh(h_h, buf);
|
||||
render_colon(c_hm, buf);
|
||||
render_mm(m_m, buf);
|
||||
render_colon(c_ms, buf);
|
||||
render_ss(s_s, buf);
|
||||
}
|
||||
Format::YyyyDdHhMmSs if with_decis => {
|
||||
let [y_y_y_y, ly, d_d, ld, h_h, c_hm, m_m, c_ms, s_s, dot, ds] =
|
||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||
render_yyyy(y_y_y_y, buf);
|
||||
render_label_y(ly, buf);
|
||||
render_dd(d_d, buf);
|
||||
render_label_d(ld, buf);
|
||||
render_hh(h_h, buf);
|
||||
render_colon(c_hm, buf);
|
||||
render_mm(m_m, buf);
|
||||
render_colon(c_ms, buf);
|
||||
render_ss(s_s, buf);
|
||||
render_dot(dot, buf);
|
||||
render_ds(ds, buf);
|
||||
}
|
||||
Format::YyyyDdHhMmSs => {
|
||||
let [y_y_y_y, ly, d_d, ld, h_h, c_hm, m_m, c_ms, s_s] =
|
||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||
render_yyyy(y_y_y_y, buf);
|
||||
render_label_y(ly, buf);
|
||||
render_dd(d_d, buf);
|
||||
render_label_d(ld, buf);
|
||||
render_hh(h_h, buf);
|
||||
render_colon(c_hm, buf);
|
||||
render_mm(m_m, buf);
|
||||
render_colon(c_ms, buf);
|
||||
render_ss(s_s, buf);
|
||||
}
|
||||
Format::YyyyDHhMmSs if with_decis => {
|
||||
let [y_y_y_y, ly, d, ld, h_h, c_hm, m_m, c_ms, s_s, dot, ds] =
|
||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||
render_yyyy(y_y_y_y, buf);
|
||||
render_label_y(ly, buf);
|
||||
render_d(d, buf);
|
||||
render_label_d(ld, buf);
|
||||
render_hh(h_h, buf);
|
||||
render_colon(c_hm, buf);
|
||||
render_mm(m_m, buf);
|
||||
render_colon(c_ms, buf);
|
||||
render_ss(s_s, buf);
|
||||
render_dot(dot, buf);
|
||||
render_ds(ds, buf);
|
||||
}
|
||||
Format::YyyyDHhMmSs => {
|
||||
let [y_y_y_y, ly, d, ld, h_h, c_hm, m_m, c_ms, s_s] =
|
||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||
render_yyyy(y_y_y_y, buf);
|
||||
render_label_y(ly, buf);
|
||||
render_d(d, buf);
|
||||
render_label_d(ld, buf);
|
||||
render_hh(h_h, buf);
|
||||
render_colon(c_hm, buf);
|
||||
render_mm(m_m, buf);
|
||||
render_colon(c_ms, buf);
|
||||
render_ss(s_s, buf);
|
||||
}
|
||||
Format::YyyDddHhMmSs if with_decis => {
|
||||
let [y_y_y, ly, d_d_d, ld, h_h, c_hm, m_m, c_ms, s_s, dot, ds] =
|
||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||
|
||||
@ -8,8 +8,8 @@ pub const DIGIT_SIZE: usize = 5;
|
||||
pub const DIGIT_WIDTH: u16 = DIGIT_SIZE as u16;
|
||||
pub const DIGIT_HEIGHT: u16 = DIGIT_SIZE as u16 + 1 /* border height */;
|
||||
pub const TWO_DIGITS_WIDTH: u16 = DIGIT_WIDTH + DIGIT_SPACE_WIDTH + DIGIT_WIDTH; // digit-space-digit
|
||||
pub const THREE_DIGITS_WIDTH: u16 =
|
||||
DIGIT_WIDTH + DIGIT_SPACE_WIDTH + DIGIT_WIDTH + DIGIT_SPACE_WIDTH + DIGIT_WIDTH; // digit-space-digit-space-digit
|
||||
pub const THREE_DIGITS_WIDTH: u16 = TWO_DIGITS_WIDTH + DIGIT_SPACE_WIDTH + DIGIT_WIDTH; // digit-space-digit-space-digit
|
||||
pub const FOUR_DIGITS_WIDTH: u16 = THREE_DIGITS_WIDTH + DIGIT_SPACE_WIDTH + DIGIT_WIDTH; // digit-space-digit-space-digit-space-digit
|
||||
pub const COLON_WIDTH: u16 = 4; // incl. padding left + padding right
|
||||
pub const DOT_WIDTH: u16 = 4; // incl. padding left + padding right
|
||||
pub const DIGIT_SPACE_WIDTH: u16 = 1; // space between digits
|
||||
|
||||
@ -202,6 +202,24 @@ fn test_format_by_duration_boundaries() {
|
||||
format_by_duration::<DurationEx>(&(100 * ONE_YEAR + 100 * ONE_DAY).into()),
|
||||
Format::YyyDddHhMmSs
|
||||
);
|
||||
|
||||
// YyyDdHhMmSs
|
||||
assert_eq!(
|
||||
format_by_duration::<DurationEx>(&(1000 * ONE_YEAR + 10 * ONE_DAY).into()),
|
||||
Format::YyyyDdHhMmSs
|
||||
);
|
||||
// YyyyDdHhMmSs
|
||||
assert_eq!(
|
||||
format_by_duration::<DurationEx>(
|
||||
&(1000 * ONE_YEAR + (100 * ONE_DAY).saturating_sub(ONE_SECOND)).into()
|
||||
),
|
||||
Format::YyyyDdHhMmSs
|
||||
);
|
||||
// YyyyDddHhMmSs
|
||||
assert_eq!(
|
||||
format_by_duration::<DurationEx>(&(1000 * ONE_YEAR + 100 * ONE_DAY).into()),
|
||||
Format::YyyyDddHhMmSs
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user