error: add Error::is_range predicate

I'm somewhat concerned that this doesn't cover all cases, but I think
this should be a good start.
This commit is contained in:
Andrew Gallant 2025-12-21 09:09:15 -05:00
parent 259e8134ef
commit 8e8033a29d
3 changed files with 25 additions and 3 deletions

View file

@ -1059,7 +1059,7 @@ impl Date {
let nth = t::SpanWeeks::try_new("nth weekday", nth)?;
if nth == C(0) {
Err(Error::from(E::NthWeekdayNonZero))
Err(Error::slim_range("nth weekday"))
} else if nth > C(0) {
let nth = nth.max(C(1));
let weekday_diff = weekday.since_ranged(self.weekday().next());

View file

@ -13,7 +13,6 @@ pub(crate) enum Error {
InvalidISOWeekNumber,
OverflowDaysDuration,
OverflowTimeNanoseconds,
NthWeekdayNonZero,
RoundMustUseDaysOrBigger { unit: Unit },
RoundMustUseHoursOrSmaller { unit: Unit },
}
@ -68,7 +67,6 @@ impl core::fmt::Display for Error {
OverflowTimeNanoseconds => {
f.write_str("adding duration to time overflowed")
}
NthWeekdayNonZero => f.write_str("nth weekday cannot be `0`"),
RoundMustUseDaysOrBigger { unit } => write!(
f,
"rounding the span between two dates must use days \

View file

@ -93,6 +93,23 @@ impl Error {
pub fn from_args<'a>(message: core::fmt::Arguments<'a>) -> Error {
Error::from(ErrorKind::Adhoc(AdhocError::from_args(message)))
}
/// Returns true when this error originated as a result of a value being
/// out of Jiff's supported range.
///
/// # Example
///
/// ```
/// use jiff::civil::Date;
///
/// assert!(Date::new(2025, 2, 29).unwrap_err().is_range());
/// assert!("2025-02-29".parse::<Date>().unwrap_err().is_range());
/// assert!(Date::strptime("%Y-%m-%d", "2025-02-29").unwrap_err().is_range());
/// ```
pub fn is_range(&self) -> bool {
use self::ErrorKind::*;
matches!(*self.root().kind(), Range(_) | SlimRange(_) | ITimeRange(_))
}
}
impl Error {
@ -218,6 +235,13 @@ impl Error {
}
}
/// Returns the root error in this chain.
fn root(&self) -> &Error {
// OK because `Error::chain` is guaranteed to return a non-empty
// iterator.
self.chain().last().unwrap()
}
/// Returns a chain of error values.
///
/// This starts with the most recent error added to the chain. That is,