diff --git a/src/error.rs b/src/error.rs index 6acae2d0e8..2c067eb560 100644 --- a/src/error.rs +++ b/src/error.rs @@ -17,16 +17,16 @@ pub enum Error { /// /// An example is a date for the year 500.000, which is out of the range supported by chrono's /// types. - OutOfRange, + DateOutOfRange, - /// A date or datetime does not exist. + /// A date or datetime does is invalid. /// /// Examples are: /// - April 31, /// - February 29 in a non-leap year, /// - a time that falls in the gap created by moving the clock forward during a DST transition, /// - a leap second on a non-minute boundary. - DoesNotExist, + InvalidDate, /// Some of the date or time components are not consistent with each other. /// @@ -50,14 +50,42 @@ pub enum Error { /// /// Contains the byte index of the formatting specifier within the format string. UnsupportedSpecifier(u32), + + /// Given field is out of permitted range. + FieldOutOfRange, + + /// 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. + FieldImpossible, + + /// 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. + FieldNotEnough, + + /// The input string has some invalid character sequence for given formatting items. + InvalidInput, + + /// The input string has been prematurely ended. + InputTooShort, + + /// All formatting items have been read but there is a remaining input. + InputTooLong, + + /// There was an error on the formatting string, or there were non-supported formating items. + BadFormat, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Error::InvalidParameter => write!(f, "invalid parameter"), - Error::OutOfRange => write!(f, "date outside of the supported range"), - Error::DoesNotExist => write!(f, "date or datetime does not exist"), + Error::DateOutOfRange => write!(f, "date outside of the supported range"), + Error::InvalidDate => 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") } @@ -70,6 +98,13 @@ impl fmt::Display for Error { Error::UnsupportedSpecifier(_) => { write!(f, "format string contains a formatting specifier that is not supported") } + Error::FieldOutOfRange => write!(f, "input is out of range"), + Error::FieldImpossible => write!(f, "no possible date and time matching input"), + Error::FieldNotEnough => write!(f, "input is not enough for unique date and time"), + Error::InvalidInput => write!(f, "input contains invalid characters"), + Error::InputTooShort => write!(f, "premature end of input"), + Error::InputTooLong => write!(f, "trailing input"), + Error::BadFormat => write!(f, "bad or unsupported format string"), } } } @@ -77,5 +112,13 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error {} -pub(crate) const INVALID: Error = Error::InvalidParameter; -pub(crate) const DOES_NOT_EXIST: Error = Error::DoesNotExist; +pub(crate) const INVALID_PARAM: Error = Error::InvalidParameter; +pub(crate) const INVALID_DATE: Error = Error::InvalidDate; + +pub(crate) const FIELD_OUT_OF_RANGE: Error = Error::FieldOutOfRange; +pub(crate) const FIELD_IMPOSSIBLE: Error = Error::FieldImpossible; +pub(crate) const FIELD_NOT_ENOUGH: Error = Error::FieldNotEnough; +pub(crate) const INVALID_INPUT: Error = Error::InvalidInput; +pub(crate) const INPUT_TOO_SHORT: Error = Error::InputTooShort; +pub(crate) const INPUT_TOO_LONG: Error = Error::InputTooLong; +pub(crate) const BAD_FORMAT: Error = Error::BadFormat; \ No newline at end of file diff --git a/src/naive/date.rs b/src/naive/date.rs index 236deecc2f..1ad6d37a40 100644 --- a/src/naive/date.rs +++ b/src/naive/date.rs @@ -780,7 +780,7 @@ impl NaiveDate { /// /// Returns [`Error::InvalidParameter`] on invalid hour, minute, second and/or millisecond. /// - /// Returns [`Error::DoesNotExist`] if the millisecond part to represent a leap second is not on + /// Returns [`Error::InvalidDate`] if the millisecond part to represent a leap second is not on /// a minute boundary. /// /// # Example @@ -817,7 +817,7 @@ impl NaiveDate { /// /// Returns [`Error::InvalidParameter`] on invalid hour, minute, second and/or microsecond. /// - /// Returns [`Error::DoesNotExist`] if the microsecond part to represent a leap second is not on + /// Returns [`Error::InvalidDate`] if the microsecond part to represent a leap second is not on /// a minute boundary. /// /// # Example @@ -854,7 +854,7 @@ impl NaiveDate { /// /// Returns [`Error::InvalidParameter`] on invalid hour, minute, second and/or nanosecond. /// - /// Returns [`Error::DoesNotExist`] if the nanosecond part to represent a leap second is not on + /// Returns [`Error::InvalidDate`] if the nanosecond part to represent a leap second is not on /// a minute boundary. /// /// # Example diff --git a/src/naive/time/mod.rs b/src/naive/time/mod.rs index b58e85df15..05e4cc7ce5 100644 --- a/src/naive/time/mod.rs +++ b/src/naive/time/mod.rs @@ -12,7 +12,7 @@ use core::{fmt, str}; #[cfg(any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"))] use rkyv::{Archive, Deserialize, Serialize}; -use crate::error::{Error, DOES_NOT_EXIST, INVALID}; +use crate::error::{Error, INVALID_PARAM, INVALID_DATE}; use crate::expect; #[cfg(feature = "alloc")] use crate::format::DelayedFormat; @@ -265,7 +265,7 @@ impl NaiveTime { /// /// Returns [`Error::InvalidParameter`] on invalid hour, minute, second and/or millisecond. /// - /// Returns [`Error::DoesNotExist`] if the millisecond part to represent a leap second is not on + /// Returns [`Error::InvalidDate`] if the millisecond part to represent a leap second is not on /// a minute boundary. /// /// # Example @@ -282,7 +282,7 @@ impl NaiveTime { /// assert_eq!(from_hms_milli(23, 60, 0, 0), Err(Error::InvalidParameter)); /// assert_eq!(from_hms_milli(23, 59, 60, 0), Err(Error::InvalidParameter)); /// assert_eq!(from_hms_milli(23, 59, 59, 2_000), Err(Error::InvalidParameter)); - /// assert_eq!(from_hms_milli(23, 59, 30, 1_999), Err(Error::DoesNotExist)); + /// assert_eq!(from_hms_milli(23, 59, 30, 1_999), Err(Error::InvalidDate)); /// ``` #[inline] pub const fn from_hms_milli( @@ -293,7 +293,7 @@ impl NaiveTime { ) -> Result { let nano = match milli.checked_mul(1_000_000) { Some(nano) => nano, - None => return Err(INVALID), + None => return Err(INVALID_PARAM), }; NaiveTime::from_hms_nano(hour, min, sec, nano) } @@ -307,7 +307,7 @@ impl NaiveTime { /// /// Returns [`Error::InvalidParameter`] on invalid hour, minute, second and/or microsecond. /// - /// Returns [`Error::DoesNotExist`] if the microsecond part to represent a leap second is not on + /// Returns [`Error::InvalidDate`] if the microsecond part to represent a leap second is not on /// a minute boundary. /// /// # Example @@ -324,7 +324,7 @@ impl NaiveTime { /// assert_eq!(from_hms_micro(23, 60, 0, 0), Err(Error::InvalidParameter)); /// assert_eq!(from_hms_micro(23, 59, 60, 0), Err(Error::InvalidParameter)); /// assert_eq!(from_hms_micro(23, 59, 59, 2_000_000), Err(Error::InvalidParameter)); - /// assert_eq!(from_hms_micro(23, 59, 30, 1_999_999), Err(Error::DoesNotExist)); + /// assert_eq!(from_hms_micro(23, 59, 30, 1_999_999), Err(Error::InvalidDate)); /// ``` #[inline] pub const fn from_hms_micro( @@ -335,7 +335,7 @@ impl NaiveTime { ) -> Result { let nano = match micro.checked_mul(1_000) { Some(nano) => nano, - None => return Err(INVALID), + None => return Err(INVALID_PARAM), }; NaiveTime::from_hms_nano(hour, min, sec, nano) } @@ -349,7 +349,7 @@ impl NaiveTime { /// /// Returns [`Error::InvalidParameter`] on invalid hour, minute, second and/or nanosecond. /// - /// Returns [`Error::DoesNotExist`] if the nanosecond part to represent a leap second is not on + /// Returns [`Error::InvalidDate`] if the nanosecond part to represent a leap second is not on /// a minute boundary. /// /// # Example @@ -366,7 +366,7 @@ impl NaiveTime { /// assert_eq!(from_hms_nano(23, 60, 0, 0), Err(Error::InvalidParameter)); /// assert_eq!(from_hms_nano(23, 59, 60, 0), Err(Error::InvalidParameter)); /// assert_eq!(from_hms_nano(23, 59, 59, 2_000_000_000), Err(Error::InvalidParameter)); - /// assert_eq!(from_hms_nano(23, 59, 30, 1_999_999_999), Err(Error::DoesNotExist)); + /// assert_eq!(from_hms_nano(23, 59, 30, 1_999_999_999), Err(Error::InvalidDate)); /// ``` #[inline] pub const fn from_hms_nano( @@ -376,9 +376,9 @@ impl NaiveTime { nano: u32, ) -> Result { if hour >= 24 || min >= 60 || sec >= 60 || nano >= 2_000_000_000 { - return Err(INVALID); + return Err(INVALID_PARAM); } else if nano >= 1_000_000_000 && sec != 59 { - return Err(DOES_NOT_EXIST); + return Err(INVALID_DATE); } let secs = hour * 3600 + min * 60 + sec; Ok(NaiveTime { secs, frac: nano }) @@ -393,7 +393,7 @@ impl NaiveTime { /// /// Returns `[`Error::InvalidParameter`]` on invalid number of seconds and/or nanosecond. /// - /// Returns [`Error::DoesNotExist`] if the nanosecond part to represent a leap second is not on + /// Returns [`Error::InvalidDate`] if the nanosecond part to represent a leap second is not on /// a minute boundary. /// /// # Example @@ -408,14 +408,14 @@ impl NaiveTime { /// assert!(from_nsecs(86399, 1_999_999_999).is_ok()); // a leap second after 23:59:59 /// assert_eq!(from_nsecs(86_400, 0), Err(Error::InvalidParameter)); /// assert_eq!(from_nsecs(86399, 2_000_000_000), Err(Error::InvalidParameter)); - /// assert_eq!(from_nsecs(1, 1_999_999_999), Err(Error::DoesNotExist)); + /// assert_eq!(from_nsecs(1, 1_999_999_999), Err(Error::InvalidDate)); /// ``` #[inline] pub const fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> Result { if secs >= 86_400 || nano >= 2_000_000_000 { - return Err(INVALID); + return Err(INVALID_PARAM); } else if nano >= 1_000_000_000 && secs % 60 != 59 { - return Err(DOES_NOT_EXIST); + return Err(INVALID_DATE); } Ok(NaiveTime { secs, frac: nano }) } diff --git a/src/offset/local/tz_info/rule.rs b/src/offset/local/tz_info/rule.rs index 369e317a42..ab2566689c 100644 --- a/src/offset/local/tz_info/rule.rs +++ b/src/offset/local/tz_info/rule.rs @@ -1033,11 +1033,11 @@ mod tests { assert!(matches!( transition_rule_1.find_local_time_type(min_unix_time), - Err(Error::OutOfRange(_)) + Err(Error::DateOutOfRange(_)) )); assert!(matches!( transition_rule_2.find_local_time_type(max_unix_time), - Err(Error::OutOfRange(_)) + Err(Error::DateOutOfRange(_)) )); Ok(())