Skip to main content

time/format_description/
format_description_v3.rs

1//! A version 3 format description.
2//!
3//! Unlike versions 1 and 2, this is opaque so as to permit any changes necessary without breaking
4//! downstream users. Other than `FormatDescriptionV3`, all items are internal.
5
6#[cfg(feature = "alloc")]
7use alloc::boxed::Box;
8use core::fmt;
9
10use crate::format_description::modifier;
11
12/// A complete description of how to format and parse a type.
13///
14/// Both for forwards compatibility and to enable optimizations, this type is deliberately opaque
15/// and cannot be constructed by users of the crate. Instead, it is returned by the
16/// `format_description!` macro (when `version=3` is used) as well as the `parse_borrowed` and
17/// `parse_owned` methods.
18#[derive(Clone)]
19pub struct FormatDescriptionV3<'a> {
20    /// The inner `enum` that controls all business logic.
21    pub(crate) inner: FormatDescriptionV3Inner<'a>,
22    /// The maximum number of bytes that are needed to format any value using this format
23    /// description.
24    #[cfg(feature = "formatting")]
25    pub(crate) max_bytes_needed: usize,
26}
27
28impl fmt::Debug for FormatDescriptionV3<'_> {
29    #[inline]
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        self.inner.fmt(f)
32    }
33}
34
35impl FormatDescriptionV3<'_> {
36    /// Convert the format description to an owned version, enabling it to be stored without regard
37    /// for lifetime.
38    #[cfg(feature = "alloc")]
39    #[inline]
40    pub fn to_owned(self) -> FormatDescriptionV3<'static> {
41        FormatDescriptionV3 {
42            inner: self.inner.into_owned(),
43            #[cfg(feature = "formatting")]
44            max_bytes_needed: self.max_bytes_needed,
45        }
46    }
47}
48
49/// The inner `enum` of a version 3 format description. Controls all business logic.
50// public via `crate::format_description::__private` for macro use
51#[non_exhaustive]
52#[derive(Clone)]
53pub enum FormatDescriptionV3Inner<'a> {
54    /// Day of the month.
55    Day(modifier::Day),
56    /// Month of the year in the abbreviated form (e.g. "Jan").
57    MonthShort(modifier::MonthShort),
58    /// Month of the year in the full form (e.g. "January").
59    MonthLong(modifier::MonthLong),
60    /// Month of the year in the numerical form (e.g. "1" for January).
61    MonthNumerical(modifier::MonthNumerical),
62    /// Ordinal day of the year.
63    Ordinal(modifier::Ordinal),
64    /// Weekday in the abbreviated form (e.g. "Mon").
65    WeekdayShort(modifier::WeekdayShort),
66    /// Weekday in the full form (e.g. "Monday").
67    WeekdayLong(modifier::WeekdayLong),
68    /// Weekday number where Sunday is either 0 or 1 depending on the modifier.
69    WeekdaySunday(modifier::WeekdaySunday),
70    /// Weekday number where Monday is either 0 or 1 depending on the modifier.
71    WeekdayMonday(modifier::WeekdayMonday),
72    /// Week number of the year, where week 1 starts is the week beginning on Monday that contains
73    /// January 4.
74    WeekNumberIso(modifier::WeekNumberIso),
75    /// Week number of the year, where week 1 starts on the first Sunday of the calendar year.
76    WeekNumberSunday(modifier::WeekNumberSunday),
77    /// Week number of the year, where week 1 starts on the first Monday of the calendar year.
78    WeekNumberMonday(modifier::WeekNumberMonday),
79    /// The calendar year. Supports the extended range.
80    CalendarYearFullExtendedRange(modifier::CalendarYearFullExtendedRange),
81    /// The calendar year. Does not support the extended range.
82    CalendarYearFullStandardRange(modifier::CalendarYearFullStandardRange),
83    /// The ISO week-based year. Supports the extended range.
84    IsoYearFullExtendedRange(modifier::IsoYearFullExtendedRange),
85    /// The ISO week-based year. Does not support the extended range.
86    IsoYearFullStandardRange(modifier::IsoYearFullStandardRange),
87    /// The century of the calendar year. Supports the extended range.
88    CalendarYearCenturyExtendedRange(modifier::CalendarYearCenturyExtendedRange),
89    /// The century of the calendar year. Does not support the extended range.
90    CalendarYearCenturyStandardRange(modifier::CalendarYearCenturyStandardRange),
91    /// The century of the ISO week-based year. Supports the extended range.
92    IsoYearCenturyExtendedRange(modifier::IsoYearCenturyExtendedRange),
93    /// The century of the ISO week-based year. Does not support the extended range.
94    IsoYearCenturyStandardRange(modifier::IsoYearCenturyStandardRange),
95    /// The last two digits of the calendar year.
96    CalendarYearLastTwo(modifier::CalendarYearLastTwo),
97    /// The last two digits of the ISO week-based year.
98    IsoYearLastTwo(modifier::IsoYearLastTwo),
99    /// Hour of the day using the 12-hour clock.
100    Hour12(modifier::Hour12),
101    /// Hour of the day using the 24-hour clock.
102    Hour24(modifier::Hour24),
103    /// Minute within the hour.
104    Minute(modifier::Minute),
105    /// AM/PM part of the time.
106    Period(modifier::Period),
107    /// Second within the minute.
108    Second(modifier::Second),
109    /// Subsecond within the second.
110    Subsecond(modifier::Subsecond),
111    /// Hour of the UTC offset.
112    OffsetHour(modifier::OffsetHour),
113    /// Minute within the hour of the UTC offset.
114    OffsetMinute(modifier::OffsetMinute),
115    /// Second within the minute of the UTC offset.
116    OffsetSecond(modifier::OffsetSecond),
117    /// A number of bytes to ignore when parsing. This has no effect on formatting.
118    Ignore(modifier::Ignore),
119    /// A Unix timestamp in seconds.
120    UnixTimestampSecond(modifier::UnixTimestampSecond),
121    /// A Unix timestamp in milliseconds.
122    UnixTimestampMillisecond(modifier::UnixTimestampMillisecond),
123    /// A Unix timestamp in microseconds.
124    UnixTimestampMicrosecond(modifier::UnixTimestampMicrosecond),
125    /// A Unix timestamp in nanoseconds.
126    UnixTimestampNanosecond(modifier::UnixTimestampNanosecond),
127    /// The end of input. Parsing this component will fail if there is any input remaining. This
128    /// component neither affects formatting nor consumes any input when parsing.
129    End(modifier::End),
130    /// A string that is formatted as-is.
131    BorrowedLiteral(&'a str),
132    /// A series of literals or components that collectively form a partial or complete description.
133    BorrowedCompound(&'a [Self]),
134    /// An item that may or may not be present when parsing. If parsing fails, there will be no
135    /// effect on the resulting `struct`.
136    BorrowedOptional {
137        /// Whether the item should be formatted.
138        format: bool,
139        /// The item in question.
140        item: &'a Self,
141    },
142    /// A series of items where, when parsing, the first successful parse is used. When formatting,
143    /// the first item is used. If no items are present, both formatting and parsing are no-ops.
144    BorrowedFirst(&'a [Self]),
145    /// A string that is formatted as-is.
146    #[cfg(feature = "alloc")]
147    OwnedLiteral(Box<str>),
148    /// A series of literals or components that collectively form a partial or complete description.
149    #[cfg(feature = "alloc")]
150    OwnedCompound(Box<[Self]>),
151    /// An item that may or may not be present when parsing. If parsing fails, there will be no
152    /// effect on the resulting `struct`.
153    #[cfg(feature = "alloc")]
154    OwnedOptional {
155        /// Whether the item should be formatted.
156        format: bool,
157        /// The item in question.
158        item: Box<Self>,
159    },
160    /// A series of items where, when parsing, the first successful parse is used. When formatting,
161    /// the first item is used. If no items are present, both formatting and parsing are no-ops.
162    #[cfg(feature = "alloc")]
163    OwnedFirst(Box<[Self]>),
164}
165
166impl fmt::Debug for FormatDescriptionV3Inner<'_> {
167    #[inline]
168    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169        match self {
170            Self::Day(modifier) => modifier.fmt(f),
171            Self::MonthShort(modifier) => modifier.fmt(f),
172            Self::MonthLong(modifier) => modifier.fmt(f),
173            Self::MonthNumerical(modifier) => modifier.fmt(f),
174            Self::Ordinal(modifier) => modifier.fmt(f),
175            Self::WeekdayShort(modifier) => modifier.fmt(f),
176            Self::WeekdayLong(modifier) => modifier.fmt(f),
177            Self::WeekdaySunday(modifier) => modifier.fmt(f),
178            Self::WeekdayMonday(modifier) => modifier.fmt(f),
179            Self::WeekNumberIso(modifier) => modifier.fmt(f),
180            Self::WeekNumberSunday(modifier) => modifier.fmt(f),
181            Self::WeekNumberMonday(modifier) => modifier.fmt(f),
182            Self::CalendarYearFullExtendedRange(modifier) => modifier.fmt(f),
183            Self::CalendarYearFullStandardRange(modifier) => modifier.fmt(f),
184            Self::IsoYearFullExtendedRange(modifier) => modifier.fmt(f),
185            Self::IsoYearFullStandardRange(modifier) => modifier.fmt(f),
186            Self::CalendarYearCenturyExtendedRange(modifier) => modifier.fmt(f),
187            Self::CalendarYearCenturyStandardRange(modifier) => modifier.fmt(f),
188            Self::IsoYearCenturyExtendedRange(modifier) => modifier.fmt(f),
189            Self::IsoYearCenturyStandardRange(modifier) => modifier.fmt(f),
190            Self::CalendarYearLastTwo(modifier) => modifier.fmt(f),
191            Self::IsoYearLastTwo(modifier) => modifier.fmt(f),
192            Self::Hour12(modifier) => modifier.fmt(f),
193            Self::Hour24(modifier) => modifier.fmt(f),
194            Self::Minute(modifier) => modifier.fmt(f),
195            Self::Period(modifier) => modifier.fmt(f),
196            Self::Second(modifier) => modifier.fmt(f),
197            Self::Subsecond(modifier) => modifier.fmt(f),
198            Self::OffsetHour(modifier) => modifier.fmt(f),
199            Self::OffsetMinute(modifier) => modifier.fmt(f),
200            Self::OffsetSecond(modifier) => modifier.fmt(f),
201            Self::Ignore(modifier) => modifier.fmt(f),
202            Self::UnixTimestampSecond(modifier) => modifier.fmt(f),
203            Self::UnixTimestampMillisecond(modifier) => modifier.fmt(f),
204            Self::UnixTimestampMicrosecond(modifier) => modifier.fmt(f),
205            Self::UnixTimestampNanosecond(modifier) => modifier.fmt(f),
206            Self::End(modifier) => modifier.fmt(f),
207            Self::BorrowedLiteral(literal) => f.debug_tuple("Literal").field(literal).finish(),
208            Self::BorrowedCompound(compound) => f.debug_tuple("Compound").field(compound).finish(),
209            Self::BorrowedOptional {
210                format: should_format,
211                item,
212            } => f
213                .debug_struct("Optional")
214                .field("should_format", should_format)
215                .field("item", item)
216                .finish(),
217            Self::BorrowedFirst(items) => f.debug_tuple("First").field(items).finish(),
218            #[cfg(feature = "alloc")]
219            Self::OwnedLiteral(literal) => f.debug_tuple("Literal").field(literal).finish(),
220            #[cfg(feature = "alloc")]
221            Self::OwnedCompound(compound) => f.debug_tuple("Compound").field(compound).finish(),
222            #[cfg(feature = "alloc")]
223            Self::OwnedOptional {
224                format: should_format,
225                item,
226            } => f
227                .debug_struct("Optional")
228                .field("should_format", should_format)
229                .field("item", item)
230                .finish(),
231            #[cfg(feature = "alloc")]
232            Self::OwnedFirst(items) => f.debug_tuple("First").field(items).finish(),
233        }
234    }
235}
236
237impl<'a> FormatDescriptionV3Inner<'a> {
238    /// Convert the format description to an owned version in place, replacing borrowed
239    /// components with their owned equivalents.
240    #[cfg(feature = "alloc")]
241    pub(super) fn into_owned(self) -> FormatDescriptionV3Inner<'static> {
242        use alloc::borrow::ToOwned as _;
243        use alloc::boxed::Box;
244
245        match self {
246            Self::BorrowedLiteral(literal) => {
247                FormatDescriptionV3Inner::OwnedLiteral(literal.to_owned().into_boxed_str())
248            }
249            Self::BorrowedCompound(compound) => {
250                let owned = compound
251                    .iter()
252                    .map(|item| item.clone().into_owned())
253                    .collect();
254                FormatDescriptionV3Inner::OwnedCompound(owned)
255            }
256            Self::BorrowedOptional { format, item } => FormatDescriptionV3Inner::OwnedOptional {
257                format,
258                item: Box::new(item.clone().into_owned()),
259            },
260            Self::BorrowedFirst(items) => {
261                let owned = items.iter().map(|item| item.clone().into_owned()).collect();
262                FormatDescriptionV3Inner::OwnedFirst(owned)
263            }
264            Self::OwnedCompound(mut compound) => {
265                let len = compound.len();
266                let compound_ptr = compound.as_mut_ptr();
267                for idx in 0..len {
268                    // Safety: We know that `idx` is in bounds because of the loop. Reading and
269                    // writing is valid because we have mutable access to `compound` and the items
270                    // are the same size and alignment.
271                    unsafe {
272                        let loc = compound_ptr.add(idx);
273                        let item = loc.read();
274                        loc.write(item.into_owned());
275                    }
276                }
277                // Safety: The only difference is the lifetime and all items have been converted to
278                // variants without lifetimes.
279                FormatDescriptionV3Inner::OwnedCompound(unsafe {
280                    core::mem::transmute::<
281                        Box<[FormatDescriptionV3Inner<'a>]>,
282                        Box<[FormatDescriptionV3Inner<'static>]>,
283                    >(compound)
284                })
285            }
286            Self::OwnedOptional { format, mut item } => {
287                let ptr = &raw mut *item;
288                // Safety: Reading and writing is valid because we have mutable access to `item` and
289                // the items are the same size and alignment.
290                unsafe {
291                    let item = ptr.read();
292                    ptr.write(item.into_owned());
293                }
294                FormatDescriptionV3Inner::OwnedOptional {
295                    format,
296                    // Safety: The only difference is the lifetime and the item has been converted
297                    // to a variant without lifetimes.
298                    item: unsafe {
299                        core::mem::transmute::<
300                            Box<FormatDescriptionV3Inner<'a>>,
301                            Box<FormatDescriptionV3Inner<'static>>,
302                        >(item)
303                    },
304                }
305            }
306            Self::OwnedFirst(mut items) => {
307                let len = items.len();
308                let ptr = items.as_mut_ptr();
309                for idx in 0..len {
310                    // Safety: We know that `idx` is in bounds because of the loop. Reading and
311                    // writing is valid because we have mutable access to `compound` and the items
312                    // are the same size and alignment.
313                    unsafe {
314                        let loc = ptr.add(idx);
315                        let item = loc.read();
316                        loc.write(item.into_owned());
317                    }
318                }
319                // Safety: The only difference is the lifetime and all items have been converted to
320                // variants without lifetimes.
321                FormatDescriptionV3Inner::OwnedFirst(unsafe {
322                    core::mem::transmute::<
323                        Box<[FormatDescriptionV3Inner<'a>]>,
324                        Box<[FormatDescriptionV3Inner<'static>]>,
325                    >(items)
326                })
327            }
328            FormatDescriptionV3Inner::Day(_)
329            | FormatDescriptionV3Inner::MonthShort(_)
330            | FormatDescriptionV3Inner::MonthLong(_)
331            | FormatDescriptionV3Inner::MonthNumerical(_)
332            | FormatDescriptionV3Inner::Ordinal(_)
333            | FormatDescriptionV3Inner::WeekdayShort(_)
334            | FormatDescriptionV3Inner::WeekdayLong(_)
335            | FormatDescriptionV3Inner::WeekdaySunday(_)
336            | FormatDescriptionV3Inner::WeekdayMonday(_)
337            | FormatDescriptionV3Inner::WeekNumberIso(_)
338            | FormatDescriptionV3Inner::WeekNumberSunday(_)
339            | FormatDescriptionV3Inner::WeekNumberMonday(_)
340            | FormatDescriptionV3Inner::CalendarYearFullExtendedRange(_)
341            | FormatDescriptionV3Inner::CalendarYearFullStandardRange(_)
342            | FormatDescriptionV3Inner::IsoYearFullExtendedRange(_)
343            | FormatDescriptionV3Inner::IsoYearFullStandardRange(_)
344            | FormatDescriptionV3Inner::CalendarYearCenturyExtendedRange(_)
345            | FormatDescriptionV3Inner::CalendarYearCenturyStandardRange(_)
346            | FormatDescriptionV3Inner::IsoYearCenturyExtendedRange(_)
347            | FormatDescriptionV3Inner::IsoYearCenturyStandardRange(_)
348            | FormatDescriptionV3Inner::CalendarYearLastTwo(_)
349            | FormatDescriptionV3Inner::IsoYearLastTwo(_)
350            | FormatDescriptionV3Inner::Hour12(_)
351            | FormatDescriptionV3Inner::Hour24(_)
352            | FormatDescriptionV3Inner::Minute(_)
353            | FormatDescriptionV3Inner::Period(_)
354            | FormatDescriptionV3Inner::Second(_)
355            | FormatDescriptionV3Inner::Subsecond(_)
356            | FormatDescriptionV3Inner::OffsetHour(_)
357            | FormatDescriptionV3Inner::OffsetMinute(_)
358            | FormatDescriptionV3Inner::OffsetSecond(_)
359            | FormatDescriptionV3Inner::Ignore(_)
360            | FormatDescriptionV3Inner::UnixTimestampSecond(_)
361            | FormatDescriptionV3Inner::UnixTimestampMillisecond(_)
362            | FormatDescriptionV3Inner::UnixTimestampMicrosecond(_)
363            | FormatDescriptionV3Inner::UnixTimestampNanosecond(_)
364            | FormatDescriptionV3Inner::End(_)
365            | FormatDescriptionV3Inner::OwnedLiteral(_) => {
366                // Safety: All of the variants listed do not contain any references, so the types
367                // are identical.
368                unsafe {
369                    core::mem::transmute::<
370                        FormatDescriptionV3Inner<'a>,
371                        FormatDescriptionV3Inner<'static>,
372                    >(self)
373                }
374            }
375        }
376    }
377
378    /// Convert the inner `enum` to a `FormatDescriptionV3`.
379    #[inline]
380    pub const fn into_opaque(self) -> FormatDescriptionV3<'a> {
381        FormatDescriptionV3 {
382            #[cfg(feature = "formatting")]
383            max_bytes_needed: self.max_bytes_needed(),
384            inner: self,
385        }
386    }
387
388    /// Obtain the maximum number of bytes that are needed to format any value using this format
389    /// description.
390    #[cfg(feature = "formatting")]
391    const fn max_bytes_needed(&self) -> usize {
392        match self {
393            Self::Day(_) => 2,
394            Self::MonthShort(_) => 3,
395            Self::MonthLong(_) => 9,
396            Self::MonthNumerical(_) => 2,
397            Self::Ordinal(_) => 3,
398            Self::WeekdayShort(_) => 3,
399            Self::WeekdayLong(_) => 9,
400            Self::WeekdaySunday(_) | Self::WeekdayMonday(_) => 1,
401            Self::WeekNumberIso(_) | Self::WeekNumberSunday(_) | Self::WeekNumberMonday(_) => 2,
402            Self::CalendarYearFullExtendedRange(_) => 7,
403            Self::CalendarYearFullStandardRange(_) => 5,
404            Self::IsoYearFullExtendedRange(_) => 7,
405            Self::IsoYearFullStandardRange(_) => 5,
406            Self::CalendarYearCenturyExtendedRange(_) => 5,
407            Self::CalendarYearCenturyStandardRange(_) => 3,
408            Self::IsoYearCenturyExtendedRange(_) => 5,
409            Self::IsoYearCenturyStandardRange(_) => 3,
410            Self::CalendarYearLastTwo(_) => 2,
411            Self::IsoYearLastTwo(_) => 2,
412            Self::Hour12(_) | Self::Hour24(_) => 2,
413            Self::Minute(_) | Self::Period(_) | Self::Second(_) => 2,
414            Self::Subsecond(modifier) => match modifier.digits {
415                modifier::SubsecondDigits::One => 1,
416                modifier::SubsecondDigits::Two => 2,
417                modifier::SubsecondDigits::Three => 3,
418                modifier::SubsecondDigits::Four => 4,
419                modifier::SubsecondDigits::Five => 5,
420                modifier::SubsecondDigits::Six => 6,
421                modifier::SubsecondDigits::Seven => 7,
422                modifier::SubsecondDigits::Eight => 8,
423                modifier::SubsecondDigits::Nine => 9,
424                modifier::SubsecondDigits::OneOrMore => 9,
425            },
426            Self::OffsetHour(_) => 3,
427            Self::OffsetMinute(_) | Self::OffsetSecond(_) => 2,
428            #[cfg(feature = "large-dates")]
429            Self::UnixTimestampSecond(_) => 15,
430            #[cfg(not(feature = "large-dates"))]
431            Self::UnixTimestampSecond(_) => 13,
432            #[cfg(feature = "large-dates")]
433            Self::UnixTimestampMillisecond(_) => 18,
434            #[cfg(not(feature = "large-dates"))]
435            Self::UnixTimestampMillisecond(_) => 16,
436            #[cfg(feature = "large-dates")]
437            Self::UnixTimestampMicrosecond(_) => 21,
438            #[cfg(not(feature = "large-dates"))]
439            Self::UnixTimestampMicrosecond(_) => 19,
440            #[cfg(feature = "large-dates")]
441            Self::UnixTimestampNanosecond(_) => 24,
442            #[cfg(not(feature = "large-dates"))]
443            Self::UnixTimestampNanosecond(_) => 22,
444            Self::Ignore(_) | Self::End(_) => 0,
445            FormatDescriptionV3Inner::BorrowedLiteral(s) => s.len(),
446            FormatDescriptionV3Inner::BorrowedCompound(items) => {
447                let mut max_bytes_needed = 0;
448                let mut idx = 0;
449                while idx < items.len() {
450                    max_bytes_needed += items[idx].max_bytes_needed();
451                    idx += 1;
452                }
453                max_bytes_needed
454            }
455            FormatDescriptionV3Inner::BorrowedOptional { format, item } => {
456                if *format {
457                    item.max_bytes_needed()
458                } else {
459                    0
460                }
461            }
462            FormatDescriptionV3Inner::BorrowedFirst(items) => {
463                if items.is_empty() {
464                    0
465                } else {
466                    items[0].max_bytes_needed()
467                }
468            }
469            FormatDescriptionV3Inner::OwnedLiteral(s) => s.len(),
470            FormatDescriptionV3Inner::OwnedCompound(items) => {
471                let mut max_bytes_needed = 0;
472                let mut idx = 0;
473                while idx < items.len() {
474                    max_bytes_needed += items[idx].max_bytes_needed();
475                    idx += 1;
476                }
477                max_bytes_needed
478            }
479            FormatDescriptionV3Inner::OwnedOptional { format, item } => {
480                if *format {
481                    item.max_bytes_needed()
482                } else {
483                    0
484                }
485            }
486            FormatDescriptionV3Inner::OwnedFirst(items) => {
487                if items.is_empty() {
488                    0
489                } else {
490                    items[0].max_bytes_needed()
491                }
492            }
493        }
494    }
495}
496
497/// A component of a larger format description.
498// public via `crate::format_description::__private` for macro use
499#[non_exhaustive]
500#[derive(Debug, Clone, Copy)]
501pub enum Component {
502    /// Day of the month.
503    Day(modifier::Day),
504    /// Month of the year in the abbreviated form (e.g. "Jan").
505    MonthShort(modifier::MonthShort),
506    /// Month of the year in the full form (e.g. "January").
507    MonthLong(modifier::MonthLong),
508    /// Month of the year in the numerical form (e.g. "1" for January).
509    MonthNumerical(modifier::MonthNumerical),
510    /// Ordinal day of the year.
511    Ordinal(modifier::Ordinal),
512    /// Weekday in the abbreviated form (e.g. "Mon").
513    WeekdayShort(modifier::WeekdayShort),
514    /// Weekday in the full form (e.g. "Monday").
515    WeekdayLong(modifier::WeekdayLong),
516    /// Weekday number where Sunday is either 0 or 1 depending on the modifier.
517    WeekdaySunday(modifier::WeekdaySunday),
518    /// Weekday number where Monday is either 0 or 1 depending on the modifier.
519    WeekdayMonday(modifier::WeekdayMonday),
520    /// Week number of the year, where week 1 starts is the week beginning on Monday that contains
521    /// January 4.
522    WeekNumberIso(modifier::WeekNumberIso),
523    /// Week number of the year, where week 1 starts on the first Sunday of the calendar year.
524    WeekNumberSunday(modifier::WeekNumberSunday),
525    /// Week number of the year, where week 1 starts on the first Monday of the calendar year.
526    WeekNumberMonday(modifier::WeekNumberMonday),
527    /// The calendar year. Supports the extended range.
528    CalendarYearFullExtendedRange(modifier::CalendarYearFullExtendedRange),
529    /// The calendar year. Does not support the extended range.
530    CalendarYearFullStandardRange(modifier::CalendarYearFullStandardRange),
531    /// The ISO week-based year. Supports the extended range.
532    IsoYearFullExtendedRange(modifier::IsoYearFullExtendedRange),
533    /// The ISO week-based year. Does not support the extended range.
534    IsoYearFullStandardRange(modifier::IsoYearFullStandardRange),
535    /// The century of the calendar year. Supports the extended range.
536    CalendarYearCenturyExtendedRange(modifier::CalendarYearCenturyExtendedRange),
537    /// The century of the calendar year. Does not support the extended range.
538    CalendarYearCenturyStandardRange(modifier::CalendarYearCenturyStandardRange),
539    /// The century of the ISO week-based year. Supports the extended range.
540    IsoYearCenturyExtendedRange(modifier::IsoYearCenturyExtendedRange),
541    /// The century of the ISO week-based year. Does not support the extended range.
542    IsoYearCenturyStandardRange(modifier::IsoYearCenturyStandardRange),
543    /// The last two digits of the calendar year.
544    CalendarYearLastTwo(modifier::CalendarYearLastTwo),
545    /// The last two digits of the ISO week-based year.
546    IsoYearLastTwo(modifier::IsoYearLastTwo),
547    /// Hour of the day using the 12-hour clock.
548    Hour12(modifier::Hour12),
549    /// Hour of the day using the 24-hour clock.
550    Hour24(modifier::Hour24),
551    /// Minute within the hour.
552    Minute(modifier::Minute),
553    /// AM/PM part of the time.
554    Period(modifier::Period),
555    /// Second within the minute.
556    Second(modifier::Second),
557    /// Subsecond within the second.
558    Subsecond(modifier::Subsecond),
559    /// Hour of the UTC offset.
560    OffsetHour(modifier::OffsetHour),
561    /// Minute within the hour of the UTC offset.
562    OffsetMinute(modifier::OffsetMinute),
563    /// Second within the minute of the UTC offset.
564    OffsetSecond(modifier::OffsetSecond),
565    /// A number of bytes to ignore when parsing. This has no effect on formatting.
566    Ignore(modifier::Ignore),
567    /// A Unix timestamp in seconds.
568    UnixTimestampSecond(modifier::UnixTimestampSecond),
569    /// A Unix timestamp in milliseconds.
570    UnixTimestampMillisecond(modifier::UnixTimestampMillisecond),
571    /// A Unix timestamp in microseconds.
572    UnixTimestampMicrosecond(modifier::UnixTimestampMicrosecond),
573    /// A Unix timestamp in nanoseconds.
574    UnixTimestampNanosecond(modifier::UnixTimestampNanosecond),
575    /// The end of input. Parsing this component will fail if there is any input remaining. This
576    /// component neither affects formatting nor consumes any input when parsing.
577    End(modifier::End),
578}