summaryrefslogtreecommitdiffstats
path: root/third_party/rust/time/src/error
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/time/src/error
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/time/src/error')
-rw-r--r--third_party/rust/time/src/error/component_range.rs92
-rw-r--r--third_party/rust/time/src/error/conversion_range.rs36
-rw-r--r--third_party/rust/time/src/error/different_variant.rs34
-rw-r--r--third_party/rust/time/src/error/format.rs92
-rw-r--r--third_party/rust/time/src/error/indeterminate_offset.rs35
-rw-r--r--third_party/rust/time/src/error/invalid_format_description.rs128
-rw-r--r--third_party/rust/time/src/error/invalid_variant.rs34
-rw-r--r--third_party/rust/time/src/error/mod.rs112
-rw-r--r--third_party/rust/time/src/error/parse.rs97
-rw-r--r--third_party/rust/time/src/error/parse_from_description.rs47
-rw-r--r--third_party/rust/time/src/error/try_from_parsed.rs71
11 files changed, 778 insertions, 0 deletions
diff --git a/third_party/rust/time/src/error/component_range.rs b/third_party/rust/time/src/error/component_range.rs
new file mode 100644
index 0000000000..f399356f4d
--- /dev/null
+++ b/third_party/rust/time/src/error/component_range.rs
@@ -0,0 +1,92 @@
+//! Component range error
+
+use core::fmt;
+
+use crate::error;
+
+/// An error type indicating that a component provided to a method was out of range, causing a
+/// failure.
+// i64 is the narrowest type fitting all use cases. This eliminates the need for a type parameter.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct ComponentRange {
+ /// Name of the component.
+ pub(crate) name: &'static str,
+ /// Minimum allowed value, inclusive.
+ pub(crate) minimum: i64,
+ /// Maximum allowed value, inclusive.
+ pub(crate) maximum: i64,
+ /// Value that was provided.
+ pub(crate) value: i64,
+ /// The minimum and/or maximum value is conditional on the value of other
+ /// parameters.
+ pub(crate) conditional_range: bool,
+}
+
+impl ComponentRange {
+ /// Obtain the name of the component whose value was out of range.
+ pub const fn name(self) -> &'static str {
+ self.name
+ }
+
+ /// Whether the value's permitted range is conditional, i.e. whether an input with this
+ /// value could have succeeded if the values of other components were different.
+ pub const fn is_conditional(self) -> bool {
+ self.conditional_range
+ }
+}
+
+impl fmt::Display for ComponentRange {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "{} must be in the range {}..={}",
+ self.name, self.minimum, self.maximum
+ )?;
+
+ if self.conditional_range {
+ f.write_str(", given values of other parameters")?;
+ }
+
+ Ok(())
+ }
+}
+
+impl From<ComponentRange> for crate::Error {
+ fn from(original: ComponentRange) -> Self {
+ Self::ComponentRange(original)
+ }
+}
+
+impl TryFrom<crate::Error> for ComponentRange {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::ComponentRange(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
+
+/// **This trait implementation is deprecated and will be removed in a future breaking release.**
+#[cfg(feature = "serde")]
+impl serde::de::Expected for ComponentRange {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "a value in the range {}..={}",
+ self.minimum, self.maximum
+ )
+ }
+}
+
+#[cfg(feature = "serde")]
+impl ComponentRange {
+ /// Convert the error to a deserialization error.
+ pub(crate) fn into_de_error<E: serde::de::Error>(self) -> E {
+ E::invalid_value(serde::de::Unexpected::Signed(self.value), &self)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ComponentRange {}
diff --git a/third_party/rust/time/src/error/conversion_range.rs b/third_party/rust/time/src/error/conversion_range.rs
new file mode 100644
index 0000000000..d6d9243e13
--- /dev/null
+++ b/third_party/rust/time/src/error/conversion_range.rs
@@ -0,0 +1,36 @@
+//! Conversion range error
+
+use core::fmt;
+
+use crate::error;
+
+/// An error type indicating that a conversion failed because the target type could not store the
+/// initial value.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct ConversionRange;
+
+impl fmt::Display for ConversionRange {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str("Source value is out of range for the target type")
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ConversionRange {}
+
+impl From<ConversionRange> for crate::Error {
+ fn from(err: ConversionRange) -> Self {
+ Self::ConversionRange(err)
+ }
+}
+
+impl TryFrom<crate::Error> for ConversionRange {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::ConversionRange(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
diff --git a/third_party/rust/time/src/error/different_variant.rs b/third_party/rust/time/src/error/different_variant.rs
new file mode 100644
index 0000000000..22e21cb0c0
--- /dev/null
+++ b/third_party/rust/time/src/error/different_variant.rs
@@ -0,0 +1,34 @@
+//! Different variant error
+
+use core::fmt;
+
+/// An error type indicating that a [`TryFrom`](core::convert::TryFrom) call failed because the
+/// original value was of a different variant.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct DifferentVariant;
+
+impl fmt::Display for DifferentVariant {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "value was of a different variant than required")
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for DifferentVariant {}
+
+impl From<DifferentVariant> for crate::Error {
+ fn from(err: DifferentVariant) -> Self {
+ Self::DifferentVariant(err)
+ }
+}
+
+impl TryFrom<crate::Error> for DifferentVariant {
+ type Error = Self;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::DifferentVariant(err) => Ok(err),
+ _ => Err(Self),
+ }
+ }
+}
diff --git a/third_party/rust/time/src/error/format.rs b/third_party/rust/time/src/error/format.rs
new file mode 100644
index 0000000000..94d134363d
--- /dev/null
+++ b/third_party/rust/time/src/error/format.rs
@@ -0,0 +1,92 @@
+//! Error formatting a struct
+
+use core::fmt;
+use std::io;
+
+use crate::error;
+
+/// An error occurred when formatting.
+#[non_exhaustive]
+#[allow(missing_copy_implementations)]
+#[derive(Debug)]
+pub enum Format {
+ /// The type being formatted does not contain sufficient information to format a component.
+ #[non_exhaustive]
+ InsufficientTypeInformation,
+ /// The component named has a value that cannot be formatted into the requested format.
+ ///
+ /// This variant is only returned when using well-known formats.
+ InvalidComponent(&'static str),
+ /// A value of `std::io::Error` was returned internally.
+ StdIo(io::Error),
+}
+
+impl fmt::Display for Format {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::InsufficientTypeInformation => f.write_str(
+ "The type being formatted does not contain sufficient information to format a \
+ component.",
+ ),
+ Self::InvalidComponent(component) => write!(
+ f,
+ "The {component} component cannot be formatted into the requested format."
+ ),
+ Self::StdIo(err) => err.fmt(f),
+ }
+ }
+}
+
+impl From<io::Error> for Format {
+ fn from(err: io::Error) -> Self {
+ Self::StdIo(err)
+ }
+}
+
+impl TryFrom<Format> for io::Error {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: Format) -> Result<Self, Self::Error> {
+ match err {
+ Format::StdIo(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for Format {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match *self {
+ Self::InsufficientTypeInformation | Self::InvalidComponent(_) => None,
+ Self::StdIo(ref err) => Some(err),
+ }
+ }
+}
+
+impl From<Format> for crate::Error {
+ fn from(original: Format) -> Self {
+ Self::Format(original)
+ }
+}
+
+impl TryFrom<crate::Error> for Format {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::Format(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
+
+#[cfg(feature = "serde")]
+impl Format {
+ /// Obtain an error type for the serializer.
+ #[doc(hidden)] // Exposed only for the `declare_format_string` macro
+ pub fn into_invalid_serde_value<S: serde::Serializer>(self) -> S::Error {
+ use serde::ser::Error;
+ S::Error::custom(self)
+ }
+}
diff --git a/third_party/rust/time/src/error/indeterminate_offset.rs b/third_party/rust/time/src/error/indeterminate_offset.rs
new file mode 100644
index 0000000000..d25d4164ec
--- /dev/null
+++ b/third_party/rust/time/src/error/indeterminate_offset.rs
@@ -0,0 +1,35 @@
+//! Indeterminate offset
+
+use core::fmt;
+
+use crate::error;
+
+/// The system's UTC offset could not be determined at the given datetime.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct IndeterminateOffset;
+
+impl fmt::Display for IndeterminateOffset {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str("The system's UTC offset could not be determined")
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for IndeterminateOffset {}
+
+impl From<IndeterminateOffset> for crate::Error {
+ fn from(err: IndeterminateOffset) -> Self {
+ Self::IndeterminateOffset(err)
+ }
+}
+
+impl TryFrom<crate::Error> for IndeterminateOffset {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::IndeterminateOffset(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
diff --git a/third_party/rust/time/src/error/invalid_format_description.rs b/third_party/rust/time/src/error/invalid_format_description.rs
new file mode 100644
index 0000000000..4b312ce2d1
--- /dev/null
+++ b/third_party/rust/time/src/error/invalid_format_description.rs
@@ -0,0 +1,128 @@
+//! Invalid format description
+
+use alloc::string::String;
+use core::fmt;
+
+use crate::error;
+
+/// The format description provided was not valid.
+#[non_exhaustive]
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum InvalidFormatDescription {
+ /// There was a bracket pair that was opened but not closed.
+ #[non_exhaustive]
+ UnclosedOpeningBracket {
+ /// The zero-based index of the opening bracket.
+ index: usize,
+ },
+ /// A component name is not valid.
+ #[non_exhaustive]
+ InvalidComponentName {
+ /// The name of the invalid component name.
+ name: String,
+ /// The zero-based index the component name starts at.
+ index: usize,
+ },
+ /// A modifier is not valid.
+ #[non_exhaustive]
+ InvalidModifier {
+ /// The value of the invalid modifier.
+ value: String,
+ /// The zero-based index the modifier starts at.
+ index: usize,
+ },
+ /// A component name is missing.
+ #[non_exhaustive]
+ MissingComponentName {
+ /// The zero-based index where the component name should start.
+ index: usize,
+ },
+ /// A required modifier is missing.
+ #[non_exhaustive]
+ MissingRequiredModifier {
+ /// The name of the modifier that is missing.
+ name: &'static str,
+ /// The zero-based index of the component.
+ index: usize,
+ },
+ /// Something was expected, but not found.
+ #[non_exhaustive]
+ Expected {
+ /// What was expected to be present, but wasn't.
+ what: &'static str,
+ /// The zero-based index the item was expected to be found at.
+ index: usize,
+ },
+ /// Certain behavior is not supported in the given context.
+ #[non_exhaustive]
+ NotSupported {
+ /// The behavior that is not supported.
+ what: &'static str,
+ /// The context in which the behavior is not supported.
+ context: &'static str,
+ /// The zero-based index the error occurred at.
+ index: usize,
+ },
+}
+
+impl From<InvalidFormatDescription> for crate::Error {
+ fn from(original: InvalidFormatDescription) -> Self {
+ Self::InvalidFormatDescription(original)
+ }
+}
+
+impl TryFrom<crate::Error> for InvalidFormatDescription {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::InvalidFormatDescription(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
+
+impl fmt::Display for InvalidFormatDescription {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use InvalidFormatDescription::*;
+ match self {
+ UnclosedOpeningBracket { index } => {
+ write!(f, "unclosed opening bracket at byte index {index}")
+ }
+ InvalidComponentName { name, index } => {
+ write!(f, "invalid component name `{name}` at byte index {index}")
+ }
+ InvalidModifier { value, index } => {
+ write!(f, "invalid modifier `{value}` at byte index {index}")
+ }
+ MissingComponentName { index } => {
+ write!(f, "missing component name at byte index {index}")
+ }
+ MissingRequiredModifier { name, index } => {
+ write!(
+ f,
+ "missing required modifier `{name}` for component at byte index {index}"
+ )
+ }
+ Expected {
+ what: expected,
+ index,
+ } => {
+ write!(f, "expected {expected} at byte index {index}")
+ }
+ NotSupported {
+ what,
+ context,
+ index,
+ } => {
+ write!(
+ f,
+ "{what} is not supported in {context} at byte index {index}"
+ )
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for InvalidFormatDescription {}
diff --git a/third_party/rust/time/src/error/invalid_variant.rs b/third_party/rust/time/src/error/invalid_variant.rs
new file mode 100644
index 0000000000..396a749a29
--- /dev/null
+++ b/third_party/rust/time/src/error/invalid_variant.rs
@@ -0,0 +1,34 @@
+//! Invalid variant error
+
+use core::fmt;
+
+/// An error type indicating that a [`FromStr`](core::str::FromStr) call failed because the value
+/// was not a valid variant.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct InvalidVariant;
+
+impl fmt::Display for InvalidVariant {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "value was not a valid variant")
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for InvalidVariant {}
+
+impl From<InvalidVariant> for crate::Error {
+ fn from(err: InvalidVariant) -> Self {
+ Self::InvalidVariant(err)
+ }
+}
+
+impl TryFrom<crate::Error> for InvalidVariant {
+ type Error = crate::error::DifferentVariant;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::InvalidVariant(err) => Ok(err),
+ _ => Err(crate::error::DifferentVariant),
+ }
+ }
+}
diff --git a/third_party/rust/time/src/error/mod.rs b/third_party/rust/time/src/error/mod.rs
new file mode 100644
index 0000000000..346b89f748
--- /dev/null
+++ b/third_party/rust/time/src/error/mod.rs
@@ -0,0 +1,112 @@
+//! Various error types returned by methods in the time crate.
+
+mod component_range;
+mod conversion_range;
+mod different_variant;
+#[cfg(feature = "formatting")]
+mod format;
+#[cfg(feature = "local-offset")]
+mod indeterminate_offset;
+#[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))]
+mod invalid_format_description;
+mod invalid_variant;
+#[cfg(feature = "parsing")]
+mod parse;
+#[cfg(feature = "parsing")]
+mod parse_from_description;
+#[cfg(feature = "parsing")]
+mod try_from_parsed;
+
+use core::fmt;
+
+pub use component_range::ComponentRange;
+pub use conversion_range::ConversionRange;
+pub use different_variant::DifferentVariant;
+#[cfg(feature = "formatting")]
+pub use format::Format;
+#[cfg(feature = "local-offset")]
+pub use indeterminate_offset::IndeterminateOffset;
+#[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))]
+pub use invalid_format_description::InvalidFormatDescription;
+pub use invalid_variant::InvalidVariant;
+#[cfg(feature = "parsing")]
+pub use parse::Parse;
+#[cfg(feature = "parsing")]
+pub use parse_from_description::ParseFromDescription;
+#[cfg(feature = "parsing")]
+pub use try_from_parsed::TryFromParsed;
+
+/// A unified error type for anything returned by a method in the time crate.
+///
+/// This can be used when you either don't know or don't care about the exact error returned.
+/// `Result<_, time::Error>` (or its alias `time::Result<_>`) will work in these situations.
+#[allow(missing_copy_implementations, variant_size_differences)]
+#[allow(clippy::missing_docs_in_private_items)] // variants only
+#[non_exhaustive]
+#[derive(Debug)]
+pub enum Error {
+ ConversionRange(ConversionRange),
+ ComponentRange(ComponentRange),
+ #[cfg(feature = "local-offset")]
+ IndeterminateOffset(IndeterminateOffset),
+ #[cfg(feature = "formatting")]
+ Format(Format),
+ #[cfg(feature = "parsing")]
+ ParseFromDescription(ParseFromDescription),
+ #[cfg(feature = "parsing")]
+ #[non_exhaustive]
+ UnexpectedTrailingCharacters,
+ #[cfg(feature = "parsing")]
+ TryFromParsed(TryFromParsed),
+ #[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))]
+ InvalidFormatDescription(InvalidFormatDescription),
+ DifferentVariant(DifferentVariant),
+ InvalidVariant(InvalidVariant),
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::ConversionRange(e) => e.fmt(f),
+ Self::ComponentRange(e) => e.fmt(f),
+ #[cfg(feature = "local-offset")]
+ Self::IndeterminateOffset(e) => e.fmt(f),
+ #[cfg(feature = "formatting")]
+ Self::Format(e) => e.fmt(f),
+ #[cfg(feature = "parsing")]
+ Self::ParseFromDescription(e) => e.fmt(f),
+ #[cfg(feature = "parsing")]
+ Self::UnexpectedTrailingCharacters => f.write_str("unexpected trailing characters"),
+ #[cfg(feature = "parsing")]
+ Self::TryFromParsed(e) => e.fmt(f),
+ #[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))]
+ Self::InvalidFormatDescription(e) => e.fmt(f),
+ Self::DifferentVariant(e) => e.fmt(f),
+ Self::InvalidVariant(e) => e.fmt(f),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for Error {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Self::ConversionRange(err) => Some(err),
+ Self::ComponentRange(err) => Some(err),
+ #[cfg(feature = "local-offset")]
+ Self::IndeterminateOffset(err) => Some(err),
+ #[cfg(feature = "formatting")]
+ Self::Format(err) => Some(err),
+ #[cfg(feature = "parsing")]
+ Self::ParseFromDescription(err) => Some(err),
+ #[cfg(feature = "parsing")]
+ Self::UnexpectedTrailingCharacters => None,
+ #[cfg(feature = "parsing")]
+ Self::TryFromParsed(err) => Some(err),
+ #[cfg(all(any(feature = "formatting", feature = "parsing"), feature = "alloc"))]
+ Self::InvalidFormatDescription(err) => Some(err),
+ Self::DifferentVariant(err) => Some(err),
+ Self::InvalidVariant(err) => Some(err),
+ }
+ }
+}
diff --git a/third_party/rust/time/src/error/parse.rs b/third_party/rust/time/src/error/parse.rs
new file mode 100644
index 0000000000..b90ac74e73
--- /dev/null
+++ b/third_party/rust/time/src/error/parse.rs
@@ -0,0 +1,97 @@
+//! Error that occurred at some stage of parsing
+
+use core::fmt;
+
+use crate::error::{self, ParseFromDescription, TryFromParsed};
+
+/// An error that occurred at some stage of parsing.
+#[allow(variant_size_differences)]
+#[non_exhaustive]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum Parse {
+ #[allow(clippy::missing_docs_in_private_items)]
+ TryFromParsed(TryFromParsed),
+ #[allow(clippy::missing_docs_in_private_items)]
+ ParseFromDescription(ParseFromDescription),
+ /// The input should have ended, but there were characters remaining.
+ #[non_exhaustive]
+ UnexpectedTrailingCharacters,
+}
+
+impl fmt::Display for Parse {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::TryFromParsed(err) => err.fmt(f),
+ Self::ParseFromDescription(err) => err.fmt(f),
+ Self::UnexpectedTrailingCharacters => f.write_str("unexpected trailing characters"),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for Parse {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Self::TryFromParsed(err) => Some(err),
+ Self::ParseFromDescription(err) => Some(err),
+ Self::UnexpectedTrailingCharacters => None,
+ }
+ }
+}
+
+impl From<TryFromParsed> for Parse {
+ fn from(err: TryFromParsed) -> Self {
+ Self::TryFromParsed(err)
+ }
+}
+
+impl TryFrom<Parse> for TryFromParsed {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: Parse) -> Result<Self, Self::Error> {
+ match err {
+ Parse::TryFromParsed(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
+
+impl From<ParseFromDescription> for Parse {
+ fn from(err: ParseFromDescription) -> Self {
+ Self::ParseFromDescription(err)
+ }
+}
+
+impl TryFrom<Parse> for ParseFromDescription {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: Parse) -> Result<Self, Self::Error> {
+ match err {
+ Parse::ParseFromDescription(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
+
+impl From<Parse> for crate::Error {
+ fn from(err: Parse) -> Self {
+ match err {
+ Parse::TryFromParsed(err) => Self::TryFromParsed(err),
+ Parse::ParseFromDescription(err) => Self::ParseFromDescription(err),
+ Parse::UnexpectedTrailingCharacters => Self::UnexpectedTrailingCharacters,
+ }
+ }
+}
+
+impl TryFrom<crate::Error> for Parse {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::ParseFromDescription(err) => Ok(Self::ParseFromDescription(err)),
+ crate::Error::UnexpectedTrailingCharacters => Ok(Self::UnexpectedTrailingCharacters),
+ crate::Error::TryFromParsed(err) => Ok(Self::TryFromParsed(err)),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
diff --git a/third_party/rust/time/src/error/parse_from_description.rs b/third_party/rust/time/src/error/parse_from_description.rs
new file mode 100644
index 0000000000..772f10d173
--- /dev/null
+++ b/third_party/rust/time/src/error/parse_from_description.rs
@@ -0,0 +1,47 @@
+//! Error parsing an input into a [`Parsed`](crate::parsing::Parsed) struct
+
+use core::fmt;
+
+use crate::error;
+
+/// An error that occurred while parsing the input into a [`Parsed`](crate::parsing::Parsed) struct.
+#[non_exhaustive]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum ParseFromDescription {
+ /// A string literal was not what was expected.
+ #[non_exhaustive]
+ InvalidLiteral,
+ /// A dynamic component was not valid.
+ InvalidComponent(&'static str),
+}
+
+impl fmt::Display for ParseFromDescription {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::InvalidLiteral => f.write_str("a character literal was not valid"),
+ Self::InvalidComponent(name) => {
+ write!(f, "the '{name}' component could not be parsed")
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ParseFromDescription {}
+
+impl From<ParseFromDescription> for crate::Error {
+ fn from(original: ParseFromDescription) -> Self {
+ Self::ParseFromDescription(original)
+ }
+}
+
+impl TryFrom<crate::Error> for ParseFromDescription {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::ParseFromDescription(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
diff --git a/third_party/rust/time/src/error/try_from_parsed.rs b/third_party/rust/time/src/error/try_from_parsed.rs
new file mode 100644
index 0000000000..da8e6947a3
--- /dev/null
+++ b/third_party/rust/time/src/error/try_from_parsed.rs
@@ -0,0 +1,71 @@
+//! Error converting a [`Parsed`](crate::parsing::Parsed) struct to another type
+
+use core::fmt;
+
+use crate::error;
+
+/// An error that occurred when converting a [`Parsed`](crate::parsing::Parsed) to another type.
+#[non_exhaustive]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum TryFromParsed {
+ /// The [`Parsed`](crate::parsing::Parsed) did not include enough information to construct the
+ /// type.
+ InsufficientInformation,
+ /// Some component contained an invalid value for the type.
+ ComponentRange(error::ComponentRange),
+}
+
+impl fmt::Display for TryFromParsed {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::InsufficientInformation => f.write_str(
+ "the `Parsed` struct did not include enough information to construct the type",
+ ),
+ Self::ComponentRange(err) => err.fmt(f),
+ }
+ }
+}
+
+impl From<error::ComponentRange> for TryFromParsed {
+ fn from(v: error::ComponentRange) -> Self {
+ Self::ComponentRange(v)
+ }
+}
+
+impl TryFrom<TryFromParsed> for error::ComponentRange {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: TryFromParsed) -> Result<Self, Self::Error> {
+ match err {
+ TryFromParsed::ComponentRange(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for TryFromParsed {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Self::InsufficientInformation => None,
+ Self::ComponentRange(err) => Some(err),
+ }
+ }
+}
+
+impl From<TryFromParsed> for crate::Error {
+ fn from(original: TryFromParsed) -> Self {
+ Self::TryFromParsed(original)
+ }
+}
+
+impl TryFrom<crate::Error> for TryFromParsed {
+ type Error = error::DifferentVariant;
+
+ fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
+ match err {
+ crate::Error::TryFromParsed(err) => Ok(err),
+ _ => Err(error::DifferentVariant),
+ }
+ }
+}