summaryrefslogtreecommitdiffstats
path: root/vendor/time/src/format_description/well_known/iso8601.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/time/src/format_description/well_known/iso8601.rs')
-rw-r--r--vendor/time/src/format_description/well_known/iso8601.rs233
1 files changed, 233 insertions, 0 deletions
diff --git a/vendor/time/src/format_description/well_known/iso8601.rs b/vendor/time/src/format_description/well_known/iso8601.rs
new file mode 100644
index 000000000..f19181a92
--- /dev/null
+++ b/vendor/time/src/format_description/well_known/iso8601.rs
@@ -0,0 +1,233 @@
+//! The format described in ISO 8601.
+
+mod adt_hack;
+
+use core::num::NonZeroU8;
+
+pub use self::adt_hack::{DoNotRelyOnWhatThisIs, EncodedConfig};
+
+/// A configuration for [`Iso8601`] that only parses values.
+const PARSING_ONLY: EncodedConfig = Config {
+ formatted_components: FormattedComponents::None,
+ use_separators: false,
+ year_is_six_digits: false,
+ date_kind: DateKind::Calendar,
+ time_precision: TimePrecision::Hour {
+ decimal_digits: None,
+ },
+ offset_precision: OffsetPrecision::Hour,
+}
+.encode();
+
+/// The default configuration for [`Iso8601`].
+const DEFAULT_CONFIG: EncodedConfig = Config::DEFAULT.encode();
+
+/// The format described in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html).
+///
+/// This implementation is of ISO 8601-1:2019. It may not be compatible with other versions.
+///
+/// The const parameter `CONFIG` **must** be a value that was returned by [`Config::encode`].
+/// Passing any other value is **unspecified behavior**.
+///
+/// Example: 1997-11-21T09:55:06.000000000-06:00
+///
+/// # Examples
+#[cfg_attr(feature = "formatting", doc = "```rust")]
+#[cfg_attr(not(feature = "formatting"), doc = "```rust,ignore")]
+/// # use time::format_description::well_known::Iso8601;
+/// # use time_macros::datetime;
+/// assert_eq!(
+/// datetime!(1997-11-12 9:55:06 -6:00).format(&Iso8601::DEFAULT)?,
+/// "1997-11-12T09:55:06.000000000-06:00"
+/// );
+/// # Ok::<_, time::Error>(())
+/// ```
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct Iso8601<const CONFIG: EncodedConfig = DEFAULT_CONFIG>;
+
+impl<const CONFIG: EncodedConfig> core::fmt::Debug for Iso8601<CONFIG> {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ f.debug_struct("Iso8601")
+ .field("config", &Config::decode(CONFIG))
+ .finish()
+ }
+}
+
+impl Iso8601<DEFAULT_CONFIG> {
+ /// An [`Iso8601`] with the default configuration.
+ ///
+ /// The following is the default behavior:
+ ///
+ /// - The configuration can be used for both formatting and parsing.
+ /// - The date, time, and UTC offset are all formatted.
+ /// - Separators (such as `-` and `:`) are included.
+ /// - The year contains four digits, such that the year must be between 0 and 9999.
+ /// - The date uses the calendar format.
+ /// - The time has precision to the second and nine decimal digits.
+ /// - The UTC offset has precision to the minute.
+ ///
+ /// If you need different behavior, use [`Config::DEFAULT`] and [`Config`]'s methods to create
+ /// a custom configuration.
+ pub const DEFAULT: Self = Self;
+}
+
+impl Iso8601<PARSING_ONLY> {
+ /// An [`Iso8601`] that can only be used for parsing. Using this to format a value is
+ /// unspecified behavior.
+ pub const PARSING: Self = Self;
+}
+
+/// Which components to format.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum FormattedComponents {
+ /// The configuration can only be used for parsing. Using this to format a value is
+ /// unspecified behavior.
+ None,
+ /// Format only the date.
+ Date,
+ /// Format only the time.
+ Time,
+ /// Format only the UTC offset.
+ Offset,
+ /// Format the date and time.
+ DateTime,
+ /// Format the date, time, and UTC offset.
+ DateTimeOffset,
+ /// Format the time and UTC offset.
+ TimeOffset,
+}
+
+/// Which format to use for the date.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum DateKind {
+ /// Use the year-month-day format.
+ Calendar,
+ /// Use the year-week-weekday format.
+ Week,
+ /// Use the week-ordinal format.
+ Ordinal,
+}
+
+/// The precision and number of decimal digits present for the time.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum TimePrecision {
+ /// Format the hour only. Minutes, seconds, and nanoseconds will be represented with the
+ /// specified number of decimal digits, if any.
+ Hour {
+ #[allow(clippy::missing_docs_in_private_items)]
+ decimal_digits: Option<NonZeroU8>,
+ },
+ /// Format the hour and minute. Seconds and nanoseconds will be represented with the specified
+ /// number of decimal digits, if any.
+ Minute {
+ #[allow(clippy::missing_docs_in_private_items)]
+ decimal_digits: Option<NonZeroU8>,
+ },
+ /// Format the hour, minute, and second. Nanoseconds will be represented with the specified
+ /// number of decimal digits, if any.
+ Second {
+ #[allow(clippy::missing_docs_in_private_items)]
+ decimal_digits: Option<NonZeroU8>,
+ },
+}
+
+/// The precision for the UTC offset.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum OffsetPrecision {
+ /// Format only the offset hour. Requires the offset minute to be zero.
+ Hour,
+ /// Format both the offset hour and minute.
+ Minute,
+}
+
+/// Configuration for [`Iso8601`].
+// This is only used as a const generic, so there's no need to have a number of implementations on
+// it.
+#[allow(missing_copy_implementations)]
+#[doc(alias = "EncodedConfig")] // People will likely search for `EncodedConfig`, so show them this.
+#[derive(Debug)]
+pub struct Config {
+ /// Which components, if any, will be formatted.
+ pub(crate) formatted_components: FormattedComponents,
+ /// Whether the format contains separators (such as `-` or `:`).
+ pub(crate) use_separators: bool,
+ /// Whether the year is six digits.
+ pub(crate) year_is_six_digits: bool,
+ /// The format used for the date.
+ pub(crate) date_kind: DateKind,
+ /// The precision and number of decimal digits present for the time.
+ pub(crate) time_precision: TimePrecision,
+ /// The precision for the UTC offset.
+ pub(crate) offset_precision: OffsetPrecision,
+}
+
+impl Config {
+ /// A configuration for the [`Iso8601`] format.
+ ///
+ /// The following is the default behavior:
+ ///
+ /// - The configuration can be used for both formatting and parsing.
+ /// - The date, time, and UTC offset are all formatted.
+ /// - Separators (such as `-` and `:`) are included.
+ /// - The year contains four digits, such that the year must be between 0 and 9999.
+ /// - The date uses the calendar format.
+ /// - The time has precision to the second and nine decimal digits.
+ /// - The UTC offset has precision to the minute.
+ ///
+ /// If you need different behavior, use the setter methods on this struct.
+ pub const DEFAULT: Self = Self {
+ formatted_components: FormattedComponents::DateTimeOffset,
+ use_separators: true,
+ year_is_six_digits: false,
+ date_kind: DateKind::Calendar,
+ time_precision: TimePrecision::Second {
+ decimal_digits: NonZeroU8::new(9),
+ },
+ offset_precision: OffsetPrecision::Minute,
+ };
+
+ /// Set whether the format the date, time, and/or UTC offset.
+ pub const fn set_formatted_components(self, formatted_components: FormattedComponents) -> Self {
+ Self {
+ formatted_components,
+ ..self
+ }
+ }
+
+ /// Set whether the format contains separators (such as `-` or `:`).
+ pub const fn set_use_separators(self, use_separators: bool) -> Self {
+ Self {
+ use_separators,
+ ..self
+ }
+ }
+
+ /// Set whether the year is six digits.
+ pub const fn set_year_is_six_digits(self, year_is_six_digits: bool) -> Self {
+ Self {
+ year_is_six_digits,
+ ..self
+ }
+ }
+
+ /// Set the format used for the date.
+ pub const fn set_date_kind(self, date_kind: DateKind) -> Self {
+ Self { date_kind, ..self }
+ }
+
+ /// Set the precision and number of decimal digits present for the time.
+ pub const fn set_time_precision(self, time_precision: TimePrecision) -> Self {
+ Self {
+ time_precision,
+ ..self
+ }
+ }
+
+ /// Set the precision for the UTC offset.
+ pub const fn set_offset_precision(self, offset_precision: OffsetPrecision) -> Self {
+ Self {
+ offset_precision,
+ ..self
+ }
+ }
+}