Skip to content

Commit 4d27862

Browse files
Ekleogpitdicker
authored andcommitted
Add Duration::try_* builders
1 parent a434523 commit 4d27862

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

src/duration.rs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,15 @@ impl Duration {
7676
#[inline]
7777
#[must_use]
7878
pub fn weeks(weeks: i64) -> Duration {
79-
let secs = weeks.checked_mul(SECS_PER_WEEK).expect("Duration::weeks out of bounds");
80-
Duration::seconds(secs)
79+
Duration::try_weeks(weeks).expect("Duration::weeks out of bounds")
80+
}
81+
82+
/// Makes a new `Duration` with given number of weeks.
83+
/// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60)` with overflow checks.
84+
/// Returns None when the duration is out of bounds.
85+
#[inline]
86+
pub fn try_weeks(weeks: i64) -> Option<Duration> {
87+
weeks.checked_mul(SECS_PER_WEEK).and_then(Duration::try_seconds)
8188
}
8289

8390
/// Makes a new `Duration` with given number of days.
@@ -86,8 +93,15 @@ impl Duration {
8693
#[inline]
8794
#[must_use]
8895
pub fn days(days: i64) -> Duration {
89-
let secs = days.checked_mul(SECS_PER_DAY).expect("Duration::days out of bounds");
90-
Duration::seconds(secs)
96+
Duration::try_days(days).expect("Duration::days out of bounds")
97+
}
98+
99+
/// Makes a new `Duration` with given number of days.
100+
/// Equivalent to `Duration::seconds(days * 24 * 60 * 60)` with overflow checks.
101+
/// Returns None when the duration is out of bounds.
102+
#[inline]
103+
pub fn try_days(days: i64) -> Option<Duration> {
104+
days.checked_mul(SECS_PER_DAY).and_then(Duration::try_seconds)
91105
}
92106

93107
/// Makes a new `Duration` with given number of hours.
@@ -96,8 +110,15 @@ impl Duration {
96110
#[inline]
97111
#[must_use]
98112
pub fn hours(hours: i64) -> Duration {
99-
let secs = hours.checked_mul(SECS_PER_HOUR).expect("Duration::hours ouf of bounds");
100-
Duration::seconds(secs)
113+
Duration::try_hours(hours).expect("Duration::hours ouf of bounds")
114+
}
115+
116+
/// Makes a new `Duration` with given number of hours.
117+
/// Equivalent to `Duration::seconds(hours * 60 * 60)` with overflow checks.
118+
/// Returns None when the duration is out of bounds.
119+
#[inline]
120+
pub fn try_hours(hours: i64) -> Option<Duration> {
121+
hours.checked_mul(SECS_PER_HOUR).and_then(Duration::try_seconds)
101122
}
102123

103124
/// Makes a new `Duration` with given number of minutes.
@@ -106,8 +127,15 @@ impl Duration {
106127
#[inline]
107128
#[must_use]
108129
pub fn minutes(minutes: i64) -> Duration {
109-
let secs = minutes.checked_mul(SECS_PER_MINUTE).expect("Duration::minutes out of bounds");
110-
Duration::seconds(secs)
130+
Duration::try_minutes(minutes).expect("Duration::minutes out of bounds")
131+
}
132+
133+
/// Makes a new `Duration` with given number of minutes.
134+
/// Equivalent to `Duration::seconds(minutes * 60)` with overflow checks.
135+
/// Returns None when the duration is out of bounds.
136+
#[inline]
137+
pub fn try_minutes(minutes: i64) -> Option<Duration> {
138+
minutes.checked_mul(SECS_PER_MINUTE).and_then(Duration::try_seconds)
111139
}
112140

113141
/// Makes a new `Duration` with given number of seconds.
@@ -116,11 +144,19 @@ impl Duration {
116144
#[inline]
117145
#[must_use]
118146
pub fn seconds(seconds: i64) -> Duration {
147+
Duration::try_seconds(seconds).expect("Duration::seconds out of bounds")
148+
}
149+
150+
/// Makes a new `Duration` with given number of seconds.
151+
/// Returns None when the duration is more than `i64::MAX` milliseconds
152+
/// or less than `i64::MIN` milliseconds.
153+
#[inline]
154+
pub fn try_seconds(seconds: i64) -> Option<Duration> {
119155
let d = Duration { secs: seconds, nanos: 0 };
120156
if d < MIN || d > MAX {
121-
panic!("Duration::seconds out of bounds");
157+
return None;
122158
}
123-
d
159+
Some(d)
124160
}
125161

126162
/// Makes a new `Duration` with given number of milliseconds.

src/naive/date.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -768,11 +768,7 @@ impl NaiveDate {
768768
}
769769

770770
fn diff_days(self, days: i64) -> Option<Self> {
771-
let secs = days.checked_mul(86400)?; // 86400 seconds in one day
772-
if secs >= core::i64::MAX / 1000 || secs <= core::i64::MIN / 1000 {
773-
return None; // See the `time` 0.1 crate. Outside these bounds, `Duration::seconds` will panic
774-
}
775-
self.checked_add_signed(Duration::seconds(secs))
771+
self.checked_add_signed(Duration::try_days(days)?)
776772
}
777773

778774
/// Makes a new `NaiveDateTime` from the current date and given `NaiveTime`.

0 commit comments

Comments
 (0)