From dbb3c6b9f6c5bd92a521cbb36faddfd1a2cb58b3 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Thu, 7 Mar 2024 07:44:34 +0100 Subject: [PATCH 1/3] Merge `ParseError` with `Error`, convert to alias --- src/error.rs | 34 ++++++++++++++++++ src/format/mod.rs | 83 +++++--------------------------------------- src/format/parse.rs | 2 +- src/format/parsed.rs | 18 +++------- 4 files changed, 49 insertions(+), 88 deletions(-) diff --git a/src/error.rs b/src/error.rs index 770e2ef715..b7ed853b02 100644 --- a/src/error.rs +++ b/src/error.rs @@ -5,6 +5,12 @@ use core::fmt; #[non_exhaustive] #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Error { + /// There is not enough information to create a date/time. + /// + /// An example is parsing a string with not enough date/time fields, or the result of a + /// time that is ambiguous during a time zone transition (due to for example DST). + Ambiguous, + /// A date or datetime does not exist. /// /// Examples are: @@ -14,25 +20,53 @@ pub enum Error { /// - a leap second on a non-minute boundary. DoesNotExist, + /// Some of the date or time components are not consistent with each other. + /// + /// An example is parsing 'Sunday 2023-04-21', while that date is a Friday. + Inconsistent, + /// One or more of the arguments to a function are invalid. /// /// An example is creating a `NaiveTime` with 25 as the hour value. InvalidArgument, + /// Character does not match with the expected format (during parsing). + InvalidCharacter, + /// The result, or an intermediate value necessary for calculating a result, would be out of /// range. /// /// An example is a date for the year 500.000, which is out of the range supported by chrono's /// types. OutOfRange, + + /// All formatting items have been read but there is a remaining input. + TooLong, + + /// The input string has been prematurely ended. + // TEMPORARY + TooShort, + + /// The format string contains a formatting specifier that is not supported. + UnsupportedSpecifier, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { + Error::Ambiguous => write!(f, "not enough information for a unique date and time"), Error::DoesNotExist => write!(f, "date or datetime does not exist"), + Error::Inconsistent => { + write!(f, "some of the date or time components are not consistent with each other") + } Error::InvalidArgument => write!(f, "invalid parameter"), + Error::InvalidCharacter => write!(f, "input doesn't match with the expected format"), Error::OutOfRange => write!(f, "date outside of the supported range"), + Error::TooLong => write!(f, "trailing input"), + Error::TooShort => write!(f, "premature end of input"), + Error::UnsupportedSpecifier => { + write!(f, "format string contains a formatting specifier that is not supported") + } } } } diff --git a/src/format/mod.rs b/src/format/mod.rs index 79eb0c6195..556715daf4 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -35,10 +35,8 @@ use alloc::boxed::Box; use core::fmt; use core::str::FromStr; -#[cfg(feature = "std")] -use std::error::Error; -use crate::{Month, ParseMonthError, ParseWeekdayError, Weekday}; +use crate::{Error, Month, ParseMonthError, ParseWeekdayError, Weekday}; mod formatting; mod parsed; @@ -382,82 +380,19 @@ impl<'a> Item<'a> { } /// An error from the `parse` function. -#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)] -pub struct ParseError(ParseErrorKind); - -impl ParseError { - /// The category of parse error - pub const fn kind(&self) -> ParseErrorKind { - self.0 - } -} - -/// The category of parse error -#[non_exhaustive] -#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)] -pub enum ParseErrorKind { - /// Given field is out of permitted range. - OutOfRange, - - /// There is no possible date and time value with given set of fields. - /// - /// This does not include the out-of-range conditions, which are trivially invalid. - /// It includes the case that there are one or more fields that are inconsistent to each other. - Impossible, - - /// Given set of fields is not enough to make a requested date and time value. - /// - /// Note that there *may* be a case that given fields constrain the possible values so much - /// that there is a unique possible value. Chrono only tries to be correct for - /// most useful sets of fields however, as such constraint solving can be expensive. - NotEnough, - - /// The input string has some invalid character sequence for given formatting items. - Invalid, - - /// The input string has been prematurely ended. - TooShort, - - /// All formatting items have been read but there is a remaining input. - TooLong, - - /// There was an error on the formatting string, or there were non-supported formating items. - BadFormat, -} +pub type ParseError = Error; /// Same as `Result`. pub type ParseResult = Result; -impl fmt::Display for ParseError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.0 { - ParseErrorKind::OutOfRange => write!(f, "input is out of range"), - ParseErrorKind::Impossible => write!(f, "no possible date and time matching input"), - ParseErrorKind::NotEnough => write!(f, "input is not enough for unique date and time"), - ParseErrorKind::Invalid => write!(f, "input contains invalid characters"), - ParseErrorKind::TooShort => write!(f, "premature end of input"), - ParseErrorKind::TooLong => write!(f, "trailing input"), - ParseErrorKind::BadFormat => write!(f, "bad or unsupported format string"), - } - } -} - -#[cfg(feature = "std")] -impl Error for ParseError { - #[allow(deprecated)] - fn description(&self) -> &str { - "parser error, see to_string() for details" - } -} - // to be used in this module and submodules -pub(crate) const OUT_OF_RANGE: ParseError = ParseError(ParseErrorKind::OutOfRange); -const IMPOSSIBLE: ParseError = ParseError(ParseErrorKind::Impossible); -const NOT_ENOUGH: ParseError = ParseError(ParseErrorKind::NotEnough); -const INVALID: ParseError = ParseError(ParseErrorKind::Invalid); -const TOO_SHORT: ParseError = ParseError(ParseErrorKind::TooShort); -pub(crate) const TOO_LONG: ParseError = ParseError(ParseErrorKind::TooLong); -const BAD_FORMAT: ParseError = ParseError(ParseErrorKind::BadFormat); +pub(crate) const OUT_OF_RANGE: Error = Error::InvalidArgument; +const IMPOSSIBLE: Error = Error::Inconsistent; +const NOT_ENOUGH: Error = Error::Ambiguous; +const INVALID: Error = Error::InvalidCharacter; +const TOO_SHORT: Error = Error::TooShort; +pub(crate) const TOO_LONG: Error = Error::TooLong; +const BAD_FORMAT: Error = Error::UnsupportedSpecifier; // this implementation is here only because we need some private code from `scan` diff --git a/src/format/parse.rs b/src/format/parse.rs index 3422b629fb..7f46c9d442 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -1832,6 +1832,6 @@ mod tests { fn test_issue_1010() { let dt = crate::NaiveDateTime::parse_from_str("\u{c}SUN\u{e}\u{3000}\0m@J\u{3000}\0\u{3000}\0m\u{c}!\u{c}\u{b}\u{c}\u{c}\u{c}\u{c}%A\u{c}\u{b}\0SU\u{c}\u{c}", "\u{c}\u{c}%A\u{c}\u{b}\0SUN\u{c}\u{c}\u{c}SUNN\u{c}\u{c}\u{c}SUN\u{c}\u{c}!\u{c}\u{b}\u{c}\u{c}\u{c}\u{c}%A\u{c}\u{b}%a"); - assert_eq!(dt, Err(ParseError(ParseErrorKind::Invalid))); + assert_eq!(dt, Err(Error::InvalidCharacter)); } } diff --git a/src/format/parsed.rs b/src/format/parsed.rs index 3627124d24..c8ab105e2f 100644 --- a/src/format/parsed.rs +++ b/src/format/parsed.rs @@ -7,7 +7,7 @@ use super::{ParseResult, IMPOSSIBLE, NOT_ENOUGH, OUT_OF_RANGE}; use crate::naive::{NaiveDate, NaiveDateTime, NaiveTime}; use crate::offset::{FixedOffset, MappedLocalTime, Offset, TimeZone}; -use crate::{DateTime, Datelike, TimeDelta, Timelike, Weekday}; +use crate::{DateTime, Datelike, Error, TimeDelta, Timelike, Weekday}; /// A type to hold parsed fields of date and time that can check all fields are consistent. /// @@ -59,8 +59,8 @@ use crate::{DateTime, Datelike, TimeDelta, Timelike, Weekday}; /// /// ``` /// # #[cfg(feature = "alloc")] { -/// use chrono::format::{ParseErrorKind, Parsed}; -/// use chrono::Weekday; +/// use chrono::format::Parsed; +/// use chrono::{Error, Weekday}; /// /// let mut parsed = Parsed::default(); /// parsed @@ -85,12 +85,7 @@ use crate::{DateTime, Datelike, TimeDelta, Timelike, Weekday}; /// .set_minute(26)? /// .set_second(40)? /// .set_offset(0)?; -/// let result = parsed.to_datetime(); -/// -/// assert!(result.is_err()); -/// if let Err(error) = result { -/// assert_eq!(error.kind(), ParseErrorKind::Impossible); -/// } +/// assert_eq!(parsed.to_datetime(), Err(Error::Inconsistent)); /// # } /// # Ok::<(), chrono::ParseError>(()) /// ``` @@ -768,16 +763,13 @@ impl Parsed { Ok(datetime) } else if let Some(timestamp) = self.timestamp { - use super::ParseError as PE; - use super::ParseErrorKind; - // If the date fields are inconsistent, out of range, or if the date does not exist, // there is no point proceeding. // // If the date or time fields are not enough it is not an error (which is the only error // `to_naive_time` can return, so no need to check). match date { - Err(PE(ParseErrorKind::NotEnough)) => {} + Err(Error::Ambiguous) => {} Err(e) => return Err(e), _ => {} } From 83ea30fb6d94c9bff93d9216bd919677f580e025 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Tue, 12 Mar 2024 14:33:06 +0100 Subject: [PATCH 2/3] Replace `ParseError` with `Error` --- src/datetime/mod.rs | 12 ++++++------ src/format/mod.rs | 9 +++------ src/format/parse.rs | 20 ++++++++++---------- src/format/parsed.rs | 10 +++++----- src/format/strftime.rs | 18 ++++++++++-------- src/lib.rs | 2 +- src/naive/date/mod.rs | 6 +++--- src/naive/datetime/mod.rs | 4 ++-- src/naive/time/mod.rs | 6 +++--- src/offset/fixed.rs | 5 +++-- 10 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/datetime/mod.rs b/src/datetime/mod.rs index da94f5037d..1aec79f359 100644 --- a/src/datetime/mod.rs +++ b/src/datetime/mod.rs @@ -17,8 +17,8 @@ use std::time::{SystemTime, UNIX_EPOCH}; #[cfg(all(feature = "unstable-locales", feature = "alloc"))] use crate::format::Locale; use crate::format::{ - parse, parse_and_remainder, parse_rfc3339, Fixed, Item, ParseError, ParseResult, Parsed, - StrftimeItems, TOO_LONG, + parse, parse_and_remainder, parse_rfc3339, Fixed, Item, ParseResult, Parsed, StrftimeItems, + TOO_LONG, }; #[cfg(feature = "alloc")] use crate::format::{write_rfc2822, write_rfc3339, DelayedFormat, SecondsFormat}; @@ -1633,10 +1633,10 @@ where /// "2012-12-12 12:12:12Z".parse::>()?; /// "2012-12-12 12:12:12+0000".parse::>()?; /// "2012-12-12 12:12:12+00:00".parse::>()?; -/// # Ok::<(), chrono::ParseError>(()) +/// # Ok::<(), chrono::Error>(()) /// ``` impl str::FromStr for DateTime { - type Err = ParseError; + type Err = Error; fn from_str(s: &str) -> ParseResult> { s.parse::>().map(|dt| dt.with_timezone(&Utc)) @@ -1654,11 +1654,11 @@ impl str::FromStr for DateTime { /// "2012-12-12 12:12:12Z".parse::>()?; /// "2012-12-12 12:12:12+0000".parse::>()?; /// "2012-12-12 12:12:12+00:00".parse::>()?; -/// # Ok::<(), chrono::ParseError>(()) +/// # Ok::<(), chrono::Error>(()) /// ``` #[cfg(feature = "clock")] impl str::FromStr for DateTime { - type Err = ParseError; + type Err = Error; fn from_str(s: &str) -> ParseResult> { s.parse::>().map(|dt| dt.with_timezone(&Local)) diff --git a/src/format/mod.rs b/src/format/mod.rs index 556715daf4..8a473c689b 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -28,7 +28,7 @@ //! let parsed = NaiveDateTime::parse_from_str(&formatted, "%Y-%m-%d %H:%M:%S")?.in_utc(); //! assert_eq!(parsed, date_time); //! # } -//! # Ok::<(), chrono::ParseError>(()) +//! # Ok::<(), chrono::Error>(()) //! ``` #[cfg(all(feature = "alloc", not(feature = "std"), not(test)))] @@ -379,11 +379,8 @@ impl<'a> Item<'a> { } } -/// An error from the `parse` function. -pub type ParseError = Error; - -/// Same as `Result`. -pub type ParseResult = Result; +/// Same as `Result`. +pub type ParseResult = Result; // to be used in this module and submodules pub(crate) const OUT_OF_RANGE: Error = Error::InvalidArgument; diff --git a/src/format/parse.rs b/src/format/parse.rs index 7f46c9d442..9b3b0bc35d 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -9,10 +9,10 @@ use core::str; use core::usize; use super::scan; +use super::ParseResult; use super::{Fixed, InternalFixed, InternalInternal, Item, Numeric, Pad, Parsed}; -use super::{ParseError, ParseResult}; use super::{BAD_FORMAT, INVALID, OUT_OF_RANGE, TOO_LONG, TOO_SHORT}; -use crate::{DateTime, FixedOffset, Weekday}; +use crate::{DateTime, Error, FixedOffset, Weekday}; fn set_weekday_with_num_days_from_sunday(p: &mut Parsed, v: i64) -> ParseResult<&mut Parsed> { p.set_weekday(match v { @@ -288,7 +288,7 @@ fn parse_internal<'a, 'b, I, B>( parsed: &mut Parsed, mut s: &'b str, items: I, -) -> Result<&'b str, ParseError> +) -> Result<&'b str, Error> where I: Iterator, B: Borrow>, @@ -521,10 +521,10 @@ where /// "2012-12-12T12:12:12Z".parse::>()?; /// "2012-12-12 12:12:12Z".parse::>()?; /// "2012- 12-12T12: 12:12Z".parse::>()?; -/// # Ok::<(), chrono::ParseError>(()) +/// # Ok::<(), chrono::Error>(()) /// ``` impl str::FromStr for DateTime { - type Err = ParseError; + type Err = Error; fn from_str(s: &str) -> ParseResult> { let mut parsed = Parsed::default(); @@ -718,7 +718,7 @@ mod tests { } #[test] - fn test_parse_numeric() -> Result<(), ParseError> { + fn test_parse_numeric() -> Result<(), Error> { use crate::format::Item::{Literal, Space}; use crate::format::Numeric::*; @@ -845,7 +845,7 @@ mod tests { } #[test] - fn test_parse_fixed() -> Result<(), ParseError> { + fn test_parse_fixed() -> Result<(), Error> { use crate::format::Fixed::*; use crate::format::Item::{Literal, Space}; @@ -914,7 +914,7 @@ mod tests { } #[test] - fn test_parse_fixed_nanosecond() -> Result<(), ParseError> { + fn test_parse_fixed_nanosecond() -> Result<(), Error> { use crate::format::Fixed::Nanosecond; use crate::format::InternalInternal::*; use crate::format::Item::Literal; @@ -1015,7 +1015,7 @@ mod tests { } #[test] - fn test_parse_fixed_timezone_offset() -> Result<(), ParseError> { + fn test_parse_fixed_timezone_offset() -> Result<(), Error> { use crate::format::Fixed::*; use crate::format::InternalInternal::*; use crate::format::Item::Literal; @@ -1452,7 +1452,7 @@ mod tests { #[test] #[rustfmt::skip] - fn test_parse_practical_examples() -> Result<(), ParseError> { + fn test_parse_practical_examples() -> Result<(), Error> { use crate::format::InternalInternal::*; use crate::format::Item::{Literal, Space}; use crate::format::Numeric::*; diff --git a/src/format/parsed.rs b/src/format/parsed.rs index c8ab105e2f..f0a9583582 100644 --- a/src/format/parsed.rs +++ b/src/format/parsed.rs @@ -87,7 +87,7 @@ use crate::{DateTime, Datelike, Error, TimeDelta, Timelike, Weekday}; /// .set_offset(0)?; /// assert_eq!(parsed.to_datetime(), Err(Error::Inconsistent)); /// # } -/// # Ok::<(), chrono::ParseError>(()) +/// # Ok::<(), chrono::Error>(()) /// ``` /// /// The same using chrono's build-in parser for RFC 2822 (the [RFC2822 formatting item]) and @@ -119,7 +119,7 @@ use crate::{DateTime, Datelike, Error, TimeDelta, Timelike, Weekday}; /// assert_eq!(parsed.weekday(), Some(Weekday::Thu)); /// } /// # } -/// # Ok::<(), chrono::ParseError>(()) +/// # Ok::<(), chrono::Error>(()) /// ``` #[derive(Clone, PartialEq, Eq, Debug, Default, Hash)] pub struct Parsed { @@ -1123,12 +1123,12 @@ fn resolve_week_date( #[cfg(test)] mod tests { - use super::super::{ParseError, IMPOSSIBLE, NOT_ENOUGH, OUT_OF_RANGE}; + use super::super::{IMPOSSIBLE, NOT_ENOUGH, OUT_OF_RANGE}; use super::Parsed; use crate::naive::{NaiveDate, NaiveTime}; use crate::offset::{FixedOffset, TimeZone, Utc}; - use crate::Datelike; use crate::Weekday::*; + use crate::{Datelike, Error}; #[test] fn test_parsed_set_fields() { @@ -1751,7 +1751,7 @@ mod tests { } #[test] - fn issue_551() -> Result<(), ParseError> { + fn issue_551() -> Result<(), Error> { use crate::Weekday; assert_eq!( NaiveDate::from_ymd(2002, 6, 3).unwrap(), diff --git a/src/format/strftime.rs b/src/format/strftime.rs index 1ffcbe16bb..61629aafc7 100644 --- a/src/format/strftime.rs +++ b/src/format/strftime.rs @@ -159,12 +159,14 @@ Notes: #[cfg(feature = "alloc")] extern crate alloc; +#[cfg(any(feature = "alloc", feature = "std"))] +use super::BAD_FORMAT; use super::{fixed, internal_fixed, num, num0, nums}; #[cfg(feature = "unstable-locales")] use super::{locales, Locale}; use super::{Fixed, InternalInternal, Item, Numeric, Pad}; #[cfg(any(feature = "alloc", feature = "std"))] -use super::{ParseError, BAD_FORMAT}; +use crate::Error; #[cfg(all(feature = "alloc", not(feature = "std"), not(test)))] use alloc::vec::Vec; @@ -325,10 +327,10 @@ impl<'a> StrftimeItems<'a> { /// parse(&mut parsed, "11 Jul 2023 9.00", fmt_items.as_slice().iter())?; /// let parsed_dt = parsed.to_naive_datetime_with_offset(0)?; /// assert_eq!(parsed_dt, datetime); - /// # Ok::<(), chrono::ParseError>(()) + /// # Ok::<(), chrono::Error>(()) /// ``` #[cfg(any(feature = "alloc", feature = "std"))] - pub fn parse(self) -> Result>, ParseError> { + pub fn parse(self) -> Result>, Error> { self.into_iter() .map(|item| match item == Item::Error { false => Ok(item), @@ -352,10 +354,10 @@ impl<'a> StrftimeItems<'a> { /// # Example /// /// ``` - /// use chrono::format::{Item, ParseError, StrftimeItems}; - /// use chrono::NaiveDate; + /// use chrono::format::{Item, StrftimeItems}; + /// use chrono::{Error, NaiveDate}; /// - /// fn format_items(date_fmt: &str, time_fmt: &str) -> Result>, ParseError> { + /// fn format_items(date_fmt: &str, time_fmt: &str) -> Result>, Error> { /// // `fmt_string` is dropped at the end of this function. /// let fmt_string = format!("{} {}", date_fmt, time_fmt); /// StrftimeItems::new(&fmt_string).parse_to_owned() @@ -368,10 +370,10 @@ impl<'a> StrftimeItems<'a> { /// datetime.format_with_items(fmt_items.as_slice().iter()).to_string(), /// "11 Jul 2023 9.00" /// ); - /// # Ok::<(), ParseError>(()) + /// # Ok::<(), Error>(()) /// ``` #[cfg(any(feature = "alloc", feature = "std"))] - pub fn parse_to_owned(self) -> Result>, ParseError> { + pub fn parse_to_owned(self) -> Result>, Error> { self.into_iter() .map(|item| match item == Item::Error { false => Ok(item.to_owned()), diff --git a/src/lib.rs b/src/lib.rs index 3e51564b45..486ff12858 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -511,7 +511,7 @@ pub mod format; /// L10n locales. #[cfg(feature = "unstable-locales")] pub use format::Locale; -pub use format::{ParseError, ParseResult, SecondsFormat}; +pub use format::{ParseResult, SecondsFormat}; pub mod naive; #[doc(inline)] diff --git a/src/naive/date/mod.rs b/src/naive/date/mod.rs index c96030fdbb..a1cdbc6aaf 100644 --- a/src/naive/date/mod.rs +++ b/src/naive/date/mod.rs @@ -30,8 +30,8 @@ use pure_rust_locales::Locale; #[cfg(feature = "alloc")] use crate::format::DelayedFormat; use crate::format::{ - parse, parse_and_remainder, write_hundreds, Item, Numeric, Pad, ParseError, ParseResult, - Parsed, StrftimeItems, + parse, parse_and_remainder, write_hundreds, Item, Numeric, Pad, ParseResult, Parsed, + StrftimeItems, }; use crate::month::Months; use crate::naive::{Days, IsoWeek, NaiveDateTime, NaiveTime, NaiveWeek}; @@ -1962,7 +1962,7 @@ impl fmt::Display for NaiveDate { /// assert!("foo".parse::().is_err()); /// ``` impl str::FromStr for NaiveDate { - type Err = ParseError; + type Err = Error; fn from_str(s: &str) -> ParseResult { const ITEMS: &[Item<'static>] = &[ diff --git a/src/naive/datetime/mod.rs b/src/naive/datetime/mod.rs index 650b268046..82e8ecdc5c 100644 --- a/src/naive/datetime/mod.rs +++ b/src/naive/datetime/mod.rs @@ -15,7 +15,7 @@ use rkyv::{Archive, Deserialize, Serialize}; #[cfg(feature = "alloc")] use crate::format::DelayedFormat; -use crate::format::{parse, parse_and_remainder, ParseError, ParseResult, Parsed, StrftimeItems}; +use crate::format::{parse, parse_and_remainder, ParseResult, Parsed, StrftimeItems}; use crate::format::{Fixed, Item, Numeric, Pad}; use crate::naive::{Days, IsoWeek, NaiveDate, NaiveTime}; use crate::offset::Utc; @@ -1710,7 +1710,7 @@ impl fmt::Display for NaiveDateTime { /// assert!("foo".parse::().is_err()); /// ``` impl str::FromStr for NaiveDateTime { - type Err = ParseError; + type Err = Error; fn from_str(s: &str) -> ParseResult { const ITEMS: &[Item<'static>] = &[ diff --git a/src/naive/time/mod.rs b/src/naive/time/mod.rs index a65b50ad06..6d63dd5534 100644 --- a/src/naive/time/mod.rs +++ b/src/naive/time/mod.rs @@ -15,8 +15,8 @@ use rkyv::{Archive, Deserialize, Serialize}; #[cfg(feature = "alloc")] use crate::format::DelayedFormat; use crate::format::{ - parse, parse_and_remainder, write_hundreds, Fixed, Item, Numeric, Pad, ParseError, ParseResult, - Parsed, StrftimeItems, + parse, parse_and_remainder, write_hundreds, Fixed, Item, Numeric, Pad, ParseResult, Parsed, + StrftimeItems, }; use crate::{expect, try_ok_or}; use crate::{Error, FixedOffset, TimeDelta, Timelike}; @@ -1488,7 +1488,7 @@ impl fmt::Display for NaiveTime { /// assert!("foo".parse::().is_err()); /// ``` impl str::FromStr for NaiveTime { - type Err = ParseError; + type Err = Error; fn from_str(s: &str) -> ParseResult { const HOUR_AND_MINUTE: &[Item<'static>] = &[ diff --git a/src/offset/fixed.rs b/src/offset/fixed.rs index bb19faebf8..7b85c095f5 100644 --- a/src/offset/fixed.rs +++ b/src/offset/fixed.rs @@ -11,7 +11,7 @@ use rkyv::{Archive, Deserialize, Serialize}; use super::{MappedLocalTime, Offset, TimeZone}; use crate::format::{scan, OUT_OF_RANGE}; -use crate::{Error, NaiveDateTime, ParseError}; +use crate::{Error, NaiveDateTime}; /// The time zone with fixed offset, from UTC-23:59:59 to UTC+23:59:59. /// @@ -97,7 +97,8 @@ impl FixedOffset { /// Parsing a `str` into a `FixedOffset` uses the format [`%z`](crate::format::strftime). impl FromStr for FixedOffset { - type Err = ParseError; + type Err = Error; + fn from_str(s: &str) -> Result { let (_, offset) = scan::timezone_offset(s, scan::consume_colon_maybe, false, false, true)?; Self::east(offset).map_err(|_| OUT_OF_RANGE) From 36def24828d054a97096566d10f62d0415995547 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sun, 25 Feb 2024 18:31:56 +0100 Subject: [PATCH 3/3] Fully convert `Parsed::set_*` to new error type --- src/format/parse.rs | 10 +- src/format/parsed.rs | 301 +++++++++++++++++++++++-------------------- 2 files changed, 163 insertions(+), 148 deletions(-) diff --git a/src/format/parse.rs b/src/format/parse.rs index 9b3b0bc35d..55c4b583c9 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -14,7 +14,7 @@ use super::{Fixed, InternalFixed, InternalInternal, Item, Numeric, Pad, Parsed}; use super::{BAD_FORMAT, INVALID, OUT_OF_RANGE, TOO_LONG, TOO_SHORT}; use crate::{DateTime, Error, FixedOffset, Weekday}; -fn set_weekday_with_num_days_from_sunday(p: &mut Parsed, v: i64) -> ParseResult<&mut Parsed> { +fn set_weekday_with_num_days_from_sunday(p: &mut Parsed, v: i64) -> Result<&mut Parsed, Error> { p.set_weekday(match v { 0 => Weekday::Sun, 1 => Weekday::Mon, @@ -23,11 +23,11 @@ fn set_weekday_with_num_days_from_sunday(p: &mut Parsed, v: i64) -> ParseResult< 4 => Weekday::Thu, 5 => Weekday::Fri, 6 => Weekday::Sat, - _ => return Err(OUT_OF_RANGE), + _ => return Err(Error::InvalidArgument), }) } -fn set_weekday_with_number_from_monday(p: &mut Parsed, v: i64) -> ParseResult<&mut Parsed> { +fn set_weekday_with_number_from_monday(p: &mut Parsed, v: i64) -> Result<&mut Parsed, Error> { p.set_weekday(match v { 1 => Weekday::Mon, 2 => Weekday::Tue, @@ -36,7 +36,7 @@ fn set_weekday_with_number_from_monday(p: &mut Parsed, v: i64) -> ParseResult<&m 5 => Weekday::Fri, 6 => Weekday::Sat, 7 => Weekday::Sun, - _ => return Err(OUT_OF_RANGE), + _ => return Err(Error::InvalidArgument), }) } @@ -339,7 +339,7 @@ where Item::Numeric(ref spec, ref _pad) => { use super::Numeric::*; - type Setter = fn(&mut Parsed, i64) -> ParseResult<&mut Parsed>; + type Setter = fn(&mut Parsed, i64) -> Result<&mut Parsed, Error>; let (width, signed, set): (usize, bool, Setter) = match *spec { Year => (4, true, Parsed::set_year), diff --git a/src/format/parsed.rs b/src/format/parsed.rs index f0a9583582..446042e34c 100644 --- a/src/format/parsed.rs +++ b/src/format/parsed.rs @@ -148,12 +148,12 @@ pub struct Parsed { /// Checks if `old` is either empty or has the same value as `new` (i.e. "consistent"), /// and if it is empty, set `old` to `new` as well. #[inline] -fn set_if_consistent(old: &mut Option, new: T) -> ParseResult<()> { +fn set_if_consistent(old: &mut Option, new: T) -> Result<(), Error> { if let Some(ref old) = *old { if *old == new { Ok(()) } else { - Err(IMPOSSIBLE) + Err(Error::Inconsistent) } } else { *old = Some(new); @@ -169,12 +169,15 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is outside the range of an `i32`. + /// Returns [`Error::InvalidArgument`] if `value` is outside the range of an `i32`. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_year(&mut self, value: i64) -> ParseResult<&mut Self> { - set_if_consistent(&mut self.year, i32::try_from(value).map_err(|_| OUT_OF_RANGE)?)?; + pub fn set_year(&mut self, value: i64) -> Result<&mut Self, Error> { + set_if_consistent( + &mut self.year, + i32::try_from(value).map_err(|_| Error::InvalidArgument)?, + )?; Ok(self) } @@ -182,13 +185,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is negative or if it is greater than `i32::MAX`. + /// Returns [`Error::InvalidArgument`] if `value` is negative or if it is greater than `i32::MAX`. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_year_div_100(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_year_div_100(&mut self, value: i64) -> Result<&mut Self, Error> { if !(0..=i32::MAX as i64).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.year_div_100, value as i32)?; Ok(self) @@ -205,13 +208,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is negative or if it is greater than 99. + /// Return [`Error::InvalidArgument`] if `value` is negative or if it is greater than 99. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_year_mod_100(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_year_mod_100(&mut self, value: i64) -> Result<&mut Self, Error> { if !(0..100).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.year_mod_100, value as i32)?; Ok(self) @@ -227,12 +230,15 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is outside the range of an `i32`. + /// Returns [`Error::InvalidArgument`] if `value` is outside the range of an `i32`. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_isoyear(&mut self, value: i64) -> ParseResult<&mut Self> { - set_if_consistent(&mut self.isoyear, i32::try_from(value).map_err(|_| OUT_OF_RANGE)?)?; + pub fn set_isoyear(&mut self, value: i64) -> Result<&mut Self, Error> { + set_if_consistent( + &mut self.isoyear, + i32::try_from(value).map_err(|_| Error::InvalidArgument)?, + )?; Ok(self) } @@ -243,13 +249,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is negative or if it is greater than `i32::MAX`. + /// Returns [`Error::InvalidArgument`] if `value` is negative or if it is greater than `i32::MAX`. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_isoyear_div_100(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_isoyear_div_100(&mut self, value: i64) -> Result<&mut Self, Error> { if !(0..=i32::MAX as i64).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.isoyear_div_100, value as i32)?; Ok(self) @@ -269,13 +275,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is negative or if it is greater than 99. + /// Returns [`Error::InvalidArgument`] if `value` is negative or if it is greater than 99. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_isoyear_mod_100(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_isoyear_mod_100(&mut self, value: i64) -> Result<&mut Self, Error> { if !(0..100).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.isoyear_mod_100, value as i32)?; Ok(self) @@ -285,13 +291,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 1-12. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 1-12. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_month(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_month(&mut self, value: i64) -> Result<&mut Self, Error> { if !(1..=12).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.month, value as u32)?; Ok(self) @@ -303,13 +309,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 0-53. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 0-53. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_week_from_sun(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_week_from_sun(&mut self, value: i64) -> Result<&mut Self, Error> { if !(0..=53).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.week_from_sun, value as u32)?; Ok(self) @@ -322,13 +328,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 0-53. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 0-53. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_week_from_mon(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_week_from_mon(&mut self, value: i64) -> Result<&mut Self, Error> { if !(0..=53).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.week_from_mon, value as u32)?; Ok(self) @@ -340,13 +346,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 1-53. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 1-53. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_isoweek(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_isoweek(&mut self, value: i64) -> Result<&mut Self, Error> { if !(1..=53).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.isoweek, value as u32)?; Ok(self) @@ -356,9 +362,9 @@ impl Parsed { /// /// # Errors /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_weekday(&mut self, value: Weekday) -> ParseResult<&mut Self> { + pub fn set_weekday(&mut self, value: Weekday) -> Result<&mut Self, Error> { set_if_consistent(&mut self.weekday, value)?; Ok(self) } @@ -367,13 +373,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 1-366. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 1-366. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_ordinal(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_ordinal(&mut self, value: i64) -> Result<&mut Self, Error> { if !(1..=366).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.ordinal, value as u32)?; Ok(self) @@ -383,13 +389,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 1-31. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 1-31. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_day(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_day(&mut self, value: i64) -> Result<&mut Self, Error> { if !(1..=31).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.day, value as u32)?; Ok(self) @@ -401,9 +407,9 @@ impl Parsed { /// /// # Errors /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_ampm(&mut self, value: bool) -> ParseResult<&mut Self> { + pub fn set_ampm(&mut self, value: bool) -> Result<&mut Self, Error> { set_if_consistent(&mut self.hour_div_12, value as u32)?; Ok(self) } @@ -416,13 +422,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 1-12. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 1-12. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_hour12(&mut self, mut value: i64) -> ParseResult<&mut Self> { + pub fn set_hour12(&mut self, mut value: i64) -> Result<&mut Self, Error> { if !(1..=12).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } if value == 12 { value = 0 @@ -436,16 +442,16 @@ impl Parsed { /// /// # Errors /// - /// May return `OUT_OF_RANGE` if `value` is not in the range 0-23. + /// May return [`Error::InvalidArgument`] if `value` is not in the range 0-23. /// Currently only checks the value is not out of range for a `u32`. /// - /// Returns `IMPOSSIBLE` one of the fields was already set to a different value. + /// Returns [`Error::Inconsistent`] one of the fields was already set to a different value. #[inline] - pub fn set_hour(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_hour(&mut self, value: i64) -> Result<&mut Self, Error> { let (hour_div_12, hour_mod_12) = match value { hour @ 0..=11 => (0, hour as u32), hour @ 12..=23 => (1, hour as u32 - 12), - _ => return Err(OUT_OF_RANGE), + _ => return Err(Error::InvalidArgument), }; set_if_consistent(&mut self.hour_div_12, hour_div_12)?; set_if_consistent(&mut self.hour_mod_12, hour_mod_12)?; @@ -456,13 +462,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 0-59. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 0-59. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_minute(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_minute(&mut self, value: i64) -> Result<&mut Self, Error> { if !(0..=59).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.minute, value as u32)?; Ok(self) @@ -474,13 +480,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 0-60. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 0-60. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_second(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_second(&mut self, value: i64) -> Result<&mut Self, Error> { if !(0..=60).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.second, value as u32)?; Ok(self) @@ -492,13 +498,13 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is not in the range 0-999,999,999. + /// Returns [`Error::InvalidArgument`] if `value` is not in the range 0-999,999,999. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_nanosecond(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_nanosecond(&mut self, value: i64) -> Result<&mut Self, Error> { if !(0..=999_999_999).contains(&value) { - return Err(OUT_OF_RANGE); + return Err(Error::InvalidArgument); } set_if_consistent(&mut self.nanosecond, value as u32)?; Ok(self) @@ -511,9 +517,9 @@ impl Parsed { /// /// # Errors /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_timestamp(&mut self, value: i64) -> ParseResult<&mut Self> { + pub fn set_timestamp(&mut self, value: i64) -> Result<&mut Self, Error> { set_if_consistent(&mut self.timestamp, value)?; Ok(self) } @@ -524,12 +530,15 @@ impl Parsed { /// /// # Errors /// - /// Returns `OUT_OF_RANGE` if `value` is ouside the range of an `i32`. + /// Returns [`Error::InvalidArgument`] if `value` is ouside the range of an `i32`. /// - /// Returns `IMPOSSIBLE` if this field was already set to a different value. + /// Returns [`Error::Inconsistent`] if this field was already set to a different value. #[inline] - pub fn set_offset(&mut self, value: i64) -> ParseResult<&mut Self> { - set_if_consistent(&mut self.offset, i32::try_from(value).map_err(|_| OUT_OF_RANGE)?)?; + pub fn set_offset(&mut self, value: i64) -> Result<&mut Self, Error> { + set_if_consistent( + &mut self.offset, + i32::try_from(value).map_err(|_| Error::InvalidArgument)?, + )?; Ok(self) } @@ -1135,15 +1144,15 @@ mod tests { // year*, isoyear* let mut p = Parsed::default(); assert!(p.set_year(1987).is_ok()); - assert_eq!(p.set_year(1986), Err(IMPOSSIBLE)); - assert_eq!(p.set_year(1988), Err(IMPOSSIBLE)); + assert_eq!(p.set_year(1986), Err(Error::Inconsistent)); + assert_eq!(p.set_year(1988), Err(Error::Inconsistent)); assert!(p.set_year(1987).is_ok()); assert!(p.set_year_div_100(20).is_ok()); // independent to `year` - assert_eq!(p.set_year_div_100(21), Err(IMPOSSIBLE)); - assert_eq!(p.set_year_div_100(19), Err(IMPOSSIBLE)); + assert_eq!(p.set_year_div_100(21), Err(Error::Inconsistent)); + assert_eq!(p.set_year_div_100(19), Err(Error::Inconsistent)); assert!(p.set_year_mod_100(37).is_ok()); // ditto - assert_eq!(p.set_year_mod_100(38), Err(IMPOSSIBLE)); - assert_eq!(p.set_year_mod_100(36), Err(IMPOSSIBLE)); + assert_eq!(p.set_year_mod_100(38), Err(Error::Inconsistent)); + assert_eq!(p.set_year_mod_100(36), Err(Error::Inconsistent)); let mut p = Parsed::default(); assert!(p.set_year(0).is_ok()); @@ -1151,150 +1160,156 @@ mod tests { assert!(p.set_year_mod_100(0).is_ok()); let mut p = Parsed::default(); - assert_eq!(p.set_year_div_100(-1), Err(OUT_OF_RANGE)); - assert_eq!(p.set_year_mod_100(-1), Err(OUT_OF_RANGE)); + assert_eq!(p.set_year_div_100(-1), Err(Error::InvalidArgument)); + assert_eq!(p.set_year_mod_100(-1), Err(Error::InvalidArgument)); assert!(p.set_year(-1).is_ok()); - assert_eq!(p.set_year(-2), Err(IMPOSSIBLE)); - assert_eq!(p.set_year(0), Err(IMPOSSIBLE)); + assert_eq!(p.set_year(-2), Err(Error::Inconsistent)); + assert_eq!(p.set_year(0), Err(Error::Inconsistent)); let mut p = Parsed::default(); - assert_eq!(p.set_year_div_100(0x1_0000_0008), Err(OUT_OF_RANGE)); + assert_eq!(p.set_year_div_100(0x1_0000_0008), Err(Error::InvalidArgument)); assert!(p.set_year_div_100(8).is_ok()); - assert_eq!(p.set_year_div_100(0x1_0000_0008), Err(OUT_OF_RANGE)); + assert_eq!(p.set_year_div_100(0x1_0000_0008), Err(Error::InvalidArgument)); // month, week*, isoweek, ordinal, day, minute, second, nanosecond, offset let mut p = Parsed::default(); assert!(p.set_month(7).is_ok()); - assert_eq!(p.set_month(1), Err(IMPOSSIBLE)); - assert_eq!(p.set_month(6), Err(IMPOSSIBLE)); - assert_eq!(p.set_month(8), Err(IMPOSSIBLE)); - assert_eq!(p.set_month(12), Err(IMPOSSIBLE)); + assert_eq!(p.set_month(1), Err(Error::Inconsistent)); + assert_eq!(p.set_month(6), Err(Error::Inconsistent)); + assert_eq!(p.set_month(8), Err(Error::Inconsistent)); + assert_eq!(p.set_month(12), Err(Error::Inconsistent)); let mut p = Parsed::default(); assert!(p.set_month(8).is_ok()); - assert_eq!(p.set_month(0x1_0000_0008), Err(OUT_OF_RANGE)); + assert_eq!(p.set_month(0x1_0000_0008), Err(Error::InvalidArgument)); // hour let mut p = Parsed::default(); assert!(p.set_hour(12).is_ok()); - assert_eq!(p.set_hour(11), Err(IMPOSSIBLE)); - assert_eq!(p.set_hour(13), Err(IMPOSSIBLE)); + assert_eq!(p.set_hour(11), Err(Error::Inconsistent)); + assert_eq!(p.set_hour(13), Err(Error::Inconsistent)); assert!(p.set_hour(12).is_ok()); - assert_eq!(p.set_ampm(false), Err(IMPOSSIBLE)); + assert_eq!(p.set_ampm(false), Err(Error::Inconsistent)); assert!(p.set_ampm(true).is_ok()); assert!(p.set_hour12(12).is_ok()); - assert_eq!(p.set_hour12(0), Err(OUT_OF_RANGE)); // requires canonical representation - assert_eq!(p.set_hour12(1), Err(IMPOSSIBLE)); - assert_eq!(p.set_hour12(11), Err(IMPOSSIBLE)); + assert_eq!(p.set_hour12(0), Err(Error::InvalidArgument)); // requires canonical representation + assert_eq!(p.set_hour12(1), Err(Error::Inconsistent)); + assert_eq!(p.set_hour12(11), Err(Error::Inconsistent)); let mut p = Parsed::default(); assert!(p.set_ampm(true).is_ok()); assert!(p.set_hour12(7).is_ok()); - assert_eq!(p.set_hour(7), Err(IMPOSSIBLE)); - assert_eq!(p.set_hour(18), Err(IMPOSSIBLE)); + assert_eq!(p.set_hour(7), Err(Error::Inconsistent)); + assert_eq!(p.set_hour(18), Err(Error::Inconsistent)); assert!(p.set_hour(19).is_ok()); // timestamp let mut p = Parsed::default(); assert!(p.set_timestamp(1_234_567_890).is_ok()); - assert_eq!(p.set_timestamp(1_234_567_889), Err(IMPOSSIBLE)); - assert_eq!(p.set_timestamp(1_234_567_891), Err(IMPOSSIBLE)); + assert_eq!(p.set_timestamp(1_234_567_889), Err(Error::Inconsistent)); + assert_eq!(p.set_timestamp(1_234_567_891), Err(Error::Inconsistent)); } #[test] fn test_parsed_set_range() { - assert_eq!(Parsed::default().set_year(i32::MIN as i64 - 1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_year(i32::MIN as i64 - 1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_year(i32::MIN as i64).is_ok()); assert!(Parsed::default().set_year(i32::MAX as i64).is_ok()); - assert_eq!(Parsed::default().set_year(i32::MAX as i64 + 1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_year(i32::MAX as i64 + 1), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_year_div_100(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_year_div_100(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_year_div_100(0).is_ok()); assert!(Parsed::default().set_year_div_100(i32::MAX as i64).is_ok()); - assert_eq!(Parsed::default().set_year_div_100(i32::MAX as i64 + 1), Err(OUT_OF_RANGE)); + assert_eq!( + Parsed::default().set_year_div_100(i32::MAX as i64 + 1), + Err(Error::InvalidArgument) + ); - assert_eq!(Parsed::default().set_year_mod_100(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_year_mod_100(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_year_mod_100(0).is_ok()); assert!(Parsed::default().set_year_mod_100(99).is_ok()); - assert_eq!(Parsed::default().set_year_mod_100(100), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_year_mod_100(100), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_isoyear(i32::MIN as i64 - 1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_isoyear(i32::MIN as i64 - 1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_isoyear(i32::MIN as i64).is_ok()); assert!(Parsed::default().set_isoyear(i32::MAX as i64).is_ok()); - assert_eq!(Parsed::default().set_isoyear(i32::MAX as i64 + 1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_isoyear(i32::MAX as i64 + 1), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_isoyear_div_100(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_isoyear_div_100(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_isoyear_div_100(0).is_ok()); assert!(Parsed::default().set_isoyear_div_100(99).is_ok()); - assert_eq!(Parsed::default().set_isoyear_div_100(i32::MAX as i64 + 1), Err(OUT_OF_RANGE)); + assert_eq!( + Parsed::default().set_isoyear_div_100(i32::MAX as i64 + 1), + Err(Error::InvalidArgument) + ); - assert_eq!(Parsed::default().set_isoyear_mod_100(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_isoyear_mod_100(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_isoyear_mod_100(0).is_ok()); assert!(Parsed::default().set_isoyear_mod_100(99).is_ok()); - assert_eq!(Parsed::default().set_isoyear_mod_100(100), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_isoyear_mod_100(100), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_month(0), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_month(0), Err(Error::InvalidArgument)); assert!(Parsed::default().set_month(1).is_ok()); assert!(Parsed::default().set_month(12).is_ok()); - assert_eq!(Parsed::default().set_month(13), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_month(13), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_week_from_sun(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_week_from_sun(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_week_from_sun(0).is_ok()); assert!(Parsed::default().set_week_from_sun(53).is_ok()); - assert_eq!(Parsed::default().set_week_from_sun(54), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_week_from_sun(54), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_week_from_mon(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_week_from_mon(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_week_from_mon(0).is_ok()); assert!(Parsed::default().set_week_from_mon(53).is_ok()); - assert_eq!(Parsed::default().set_week_from_mon(54), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_week_from_mon(54), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_isoweek(0), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_isoweek(0), Err(Error::InvalidArgument)); assert!(Parsed::default().set_isoweek(1).is_ok()); assert!(Parsed::default().set_isoweek(53).is_ok()); - assert_eq!(Parsed::default().set_isoweek(54), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_isoweek(54), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_ordinal(0), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_ordinal(0), Err(Error::InvalidArgument)); assert!(Parsed::default().set_ordinal(1).is_ok()); assert!(Parsed::default().set_ordinal(366).is_ok()); - assert_eq!(Parsed::default().set_ordinal(367), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_ordinal(367), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_day(0), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_day(0), Err(Error::InvalidArgument)); assert!(Parsed::default().set_day(1).is_ok()); assert!(Parsed::default().set_day(31).is_ok()); - assert_eq!(Parsed::default().set_day(32), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_day(32), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_hour12(0), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_hour12(0), Err(Error::InvalidArgument)); assert!(Parsed::default().set_hour12(1).is_ok()); assert!(Parsed::default().set_hour12(12).is_ok()); - assert_eq!(Parsed::default().set_hour12(13), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_hour12(13), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_hour(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_hour(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_hour(0).is_ok()); assert!(Parsed::default().set_hour(23).is_ok()); - assert_eq!(Parsed::default().set_hour(24), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_hour(24), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_minute(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_minute(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_minute(0).is_ok()); assert!(Parsed::default().set_minute(59).is_ok()); - assert_eq!(Parsed::default().set_minute(60), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_minute(60), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_second(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_second(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_second(0).is_ok()); assert!(Parsed::default().set_second(60).is_ok()); - assert_eq!(Parsed::default().set_second(61), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_second(61), Err(Error::InvalidArgument)); - assert_eq!(Parsed::default().set_nanosecond(-1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_nanosecond(-1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_nanosecond(0).is_ok()); assert!(Parsed::default().set_nanosecond(999_999_999).is_ok()); - assert_eq!(Parsed::default().set_nanosecond(1_000_000_000), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_nanosecond(1_000_000_000), Err(Error::InvalidArgument)); assert!(Parsed::default().set_timestamp(i64::MIN).is_ok()); assert!(Parsed::default().set_timestamp(i64::MAX).is_ok()); - assert_eq!(Parsed::default().set_offset(i32::MIN as i64 - 1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_offset(i32::MIN as i64 - 1), Err(Error::InvalidArgument)); assert!(Parsed::default().set_offset(i32::MIN as i64).is_ok()); assert!(Parsed::default().set_offset(i32::MAX as i64).is_ok()); - assert_eq!(Parsed::default().set_offset(i32::MAX as i64 + 1), Err(OUT_OF_RANGE)); + assert_eq!(Parsed::default().set_offset(i32::MAX as i64 + 1), Err(Error::InvalidArgument)); } #[test]