Skip to content

Commit

Permalink
Allow durations without leading 0s in the hour (#74)
Browse files Browse the repository at this point in the history
* add passing tests for durations without leading 0s, as produced by python timedelta

* fix parsing of day time durations without leading zeros on the hour

* do not allow days in both the day and hour part

* add setup-python to fix lint CI

* fix unused import
  • Loading branch information
mrob95 authored Oct 21, 2024
1 parent d15ac62 commit 680566a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 4 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ jobs:

- uses: Swatinem/rust-cache@v2

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- uses: pre-commit/action@v3.0.1
with:
extra_args: --all-files --verbose
Expand Down
10 changes: 7 additions & 3 deletions src/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::cmp::Ordering;
use std::fmt;
use std::str::FromStr;

use crate::{time::TimeConfig, ParseError, Time, TimeConfigBuilder};
use crate::{time::TimeConfig, ParseError, TimeConfigBuilder};

/// A Duration
///
Expand Down Expand Up @@ -491,12 +491,16 @@ impl Duration {

match bytes.get(position).copied() {
Some(_) => {
let t = Time::parse_bytes_offset(bytes, position, &TimeConfigBuilder::new().build())?;
let t = Self::parse_time(bytes, position, &TimeConfigBuilder::new().build())?;
if t.day > 0 {
// 1d 24:00:00 is not allowed
return Err(ParseError::DurationHourValueTooLarge);
}

Ok(Self {
positive: false, // is set above
day,
second: t.hour as u32 * 3_600 + t.minute as u32 * 60 + t.second as u32,
second: t.second,
microsecond: t.microsecond,
})
}
Expand Down
8 changes: 7 additions & 1 deletion tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1169,8 +1169,11 @@ param_tests! {
duration_invalid_day_unit1: err => "P1X", DurationInvalidDateUnit;
duration_invalid_day_unit2: err => "P1", DurationInvalidDateUnit;
duration_time_42s: ok => "00:00:42", "PT42S";
duration_time_42s_no_leading_0: ok => "0:00:42", "PT42S";
duration_time_1m: ok => "00:01", "PT1M";
duration_time_1m_no_leading_0: ok => "0:01:00", "PT1M";
duration_time_1h_2m_3s: ok => "01:02:03", "PT1H2M3S";
duration_time_1h_2m_3s_no_leading_0: ok => "1:02:03", "PT1H2M3S";
duration_time_fraction: ok => "00:01:03.123", "PT1M3.123S";
duration_time_extra: err => "00:01:03.123x", ExtraCharacters;
duration_time_timezone: err => "00:01:03x", ExtraCharacters;
Expand Down Expand Up @@ -1204,11 +1207,14 @@ param_tests! {
duration_days_pos: ok => "+1 day", "P1D";
duration_days_123days: ok => "123days", "P123D";
duration_days_time: ok => "1 day 00:00:42", "P1DT42S";
duration_days_time_no_leading_0: ok => "1 day 1:00:42", "P1DT1H42S";
duration_days_time_comma_no_leading_0: ok => "1 day, 1:00:42", "P1DT1H42S";
duration_days_time_neg: ok => "-1 day 00:00:42", "-P1DT42S";
duration_exceeds_day: ok => "PT86500S", "P1DT1M40S";
duration_days_time_too_short: err => "1 day 00:", TooShort;
duration_days_time_wrong: err => "1 day 00:xx", InvalidCharMinute;
duration_days_time_extra: err => "1 day 00:00:00.123 ", InvalidCharTzSign;
duration_days_time_extra: err => "1 day 00:00:00.123 ", ExtraCharacters;
duration_days_time_more_than_24_hour: err => "1d 24:01:03", DurationHourValueTooLarge;
duration_overflow: err => "18446744073709551616 day 12:00", DurationValueTooLarge;
duration_fuzz1: err => "P18446744073709551611DT8031M1M1M1M", DurationValueTooLarge;
duration_fuzz2: err => "P18446744073709550PT9970442H6R15D1D", DurationValueTooLarge;
Expand Down

0 comments on commit 680566a

Please sign in to comment.