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    /// Recursively convert to an owned version, doing so in-place when possible.
239    #[cfg(feature = "alloc")]
240    fn make_owned_in_place(&mut self) {
241        use alloc::borrow::ToOwned as _;
242        use alloc::boxed::Box;
243
244        match self {
245            Self::BorrowedLiteral(literal) => {
246                *self = Self::OwnedLiteral(literal.to_owned().into_boxed_str());
247            }
248            Self::BorrowedCompound(compound) => {
249                *self = Self::OwnedCompound(
250                    compound
251                        .iter()
252                        .cloned()
253                        .map(|item| item.into_owned())
254                        .collect(),
255                );
256            }
257            Self::BorrowedOptional { format, item } => {
258                *self = Self::OwnedOptional {
259                    format: *format,
260                    item: Box::new(item.clone().into_owned()),
261                };
262            }
263            Self::BorrowedFirst(items) => {
264                *self = Self::OwnedFirst(
265                    items
266                        .iter()
267                        .cloned()
268                        .map(|item| item.into_owned())
269                        .collect(),
270                );
271            }
272            Self::OwnedCompound(compound) => {
273                for item in compound {
274                    item.make_owned_in_place();
275                }
276            }
277            Self::OwnedOptional { format: _, item } => {
278                item.make_owned_in_place();
279            }
280            Self::OwnedFirst(items) => {
281                for item in items {
282                    item.make_owned_in_place();
283                }
284            }
285            FormatDescriptionV3Inner::Day(_)
286            | FormatDescriptionV3Inner::MonthShort(_)
287            | FormatDescriptionV3Inner::MonthLong(_)
288            | FormatDescriptionV3Inner::MonthNumerical(_)
289            | FormatDescriptionV3Inner::Ordinal(_)
290            | FormatDescriptionV3Inner::WeekdayShort(_)
291            | FormatDescriptionV3Inner::WeekdayLong(_)
292            | FormatDescriptionV3Inner::WeekdaySunday(_)
293            | FormatDescriptionV3Inner::WeekdayMonday(_)
294            | FormatDescriptionV3Inner::WeekNumberIso(_)
295            | FormatDescriptionV3Inner::WeekNumberSunday(_)
296            | FormatDescriptionV3Inner::WeekNumberMonday(_)
297            | FormatDescriptionV3Inner::CalendarYearFullExtendedRange(_)
298            | FormatDescriptionV3Inner::CalendarYearFullStandardRange(_)
299            | FormatDescriptionV3Inner::IsoYearFullExtendedRange(_)
300            | FormatDescriptionV3Inner::IsoYearFullStandardRange(_)
301            | FormatDescriptionV3Inner::CalendarYearCenturyExtendedRange(_)
302            | FormatDescriptionV3Inner::CalendarYearCenturyStandardRange(_)
303            | FormatDescriptionV3Inner::IsoYearCenturyExtendedRange(_)
304            | FormatDescriptionV3Inner::IsoYearCenturyStandardRange(_)
305            | FormatDescriptionV3Inner::CalendarYearLastTwo(_)
306            | FormatDescriptionV3Inner::IsoYearLastTwo(_)
307            | FormatDescriptionV3Inner::Hour12(_)
308            | FormatDescriptionV3Inner::Hour24(_)
309            | FormatDescriptionV3Inner::Minute(_)
310            | FormatDescriptionV3Inner::Period(_)
311            | FormatDescriptionV3Inner::Second(_)
312            | FormatDescriptionV3Inner::Subsecond(_)
313            | FormatDescriptionV3Inner::OffsetHour(_)
314            | FormatDescriptionV3Inner::OffsetMinute(_)
315            | FormatDescriptionV3Inner::OffsetSecond(_)
316            | FormatDescriptionV3Inner::Ignore(_)
317            | FormatDescriptionV3Inner::UnixTimestampSecond(_)
318            | FormatDescriptionV3Inner::UnixTimestampMillisecond(_)
319            | FormatDescriptionV3Inner::UnixTimestampMicrosecond(_)
320            | FormatDescriptionV3Inner::UnixTimestampNanosecond(_)
321            | FormatDescriptionV3Inner::End(_)
322            | FormatDescriptionV3Inner::OwnedLiteral(_) => {
323                // no-op, as these variants do not contain any references
324            }
325        }
326    }
327
328    /// Convert the format description to an owned version in place, replacing borrowed
329    /// components with their owned equivalents.
330    #[cfg(feature = "alloc")]
331    pub(super) fn into_owned(mut self) -> FormatDescriptionV3Inner<'static> {
332        self.make_owned_in_place();
333
334        // Safety: `make_owned_in_place` recursively eliminates all variants that contain
335        // references, so we can transmute between lifetimes freely. ADTs do not vary in layout when
336        // only the lifetime differs.
337        unsafe {
338            core::mem::transmute::<FormatDescriptionV3Inner<'a>, FormatDescriptionV3Inner<'static>>(
339                self,
340            )
341        }
342    }
343
344    /// Convert the inner `enum` to a `FormatDescriptionV3`.
345    #[inline]
346    pub const fn into_opaque(self) -> FormatDescriptionV3<'a> {
347        FormatDescriptionV3 {
348            #[cfg(feature = "formatting")]
349            max_bytes_needed: self.max_bytes_needed(),
350            inner: self,
351        }
352    }
353
354    /// Obtain the maximum number of bytes that are needed to format any value using this format
355    /// description.
356    #[cfg(feature = "formatting")]
357    const fn max_bytes_needed(&self) -> usize {
358        match self {
359            Self::Day(_) => 2,
360            Self::MonthShort(_) => 3,
361            Self::MonthLong(_) => 9,
362            Self::MonthNumerical(_) => 2,
363            Self::Ordinal(_) => 3,
364            Self::WeekdayShort(_) => 3,
365            Self::WeekdayLong(_) => 9,
366            Self::WeekdaySunday(_) | Self::WeekdayMonday(_) => 1,
367            Self::WeekNumberIso(_) | Self::WeekNumberSunday(_) | Self::WeekNumberMonday(_) => 2,
368            Self::CalendarYearFullExtendedRange(_) => 7,
369            Self::CalendarYearFullStandardRange(_) => 5,
370            Self::IsoYearFullExtendedRange(_) => 7,
371            Self::IsoYearFullStandardRange(_) => 5,
372            Self::CalendarYearCenturyExtendedRange(_) => 5,
373            Self::CalendarYearCenturyStandardRange(_) => 3,
374            Self::IsoYearCenturyExtendedRange(_) => 5,
375            Self::IsoYearCenturyStandardRange(_) => 3,
376            Self::CalendarYearLastTwo(_) => 2,
377            Self::IsoYearLastTwo(_) => 2,
378            Self::Hour12(_) | Self::Hour24(_) => 2,
379            Self::Minute(_) | Self::Period(_) | Self::Second(_) => 2,
380            Self::Subsecond(modifier) => match modifier.digits {
381                modifier::SubsecondDigits::One => 1,
382                modifier::SubsecondDigits::Two => 2,
383                modifier::SubsecondDigits::Three => 3,
384                modifier::SubsecondDigits::Four => 4,
385                modifier::SubsecondDigits::Five => 5,
386                modifier::SubsecondDigits::Six => 6,
387                modifier::SubsecondDigits::Seven => 7,
388                modifier::SubsecondDigits::Eight => 8,
389                modifier::SubsecondDigits::Nine => 9,
390                modifier::SubsecondDigits::OneOrMore => 9,
391            },
392            Self::OffsetHour(_) => 3,
393            Self::OffsetMinute(_) | Self::OffsetSecond(_) => 2,
394            #[cfg(feature = "large-dates")]
395            Self::UnixTimestampSecond(_) => 15,
396            #[cfg(not(feature = "large-dates"))]
397            Self::UnixTimestampSecond(_) => 13,
398            #[cfg(feature = "large-dates")]
399            Self::UnixTimestampMillisecond(_) => 18,
400            #[cfg(not(feature = "large-dates"))]
401            Self::UnixTimestampMillisecond(_) => 16,
402            #[cfg(feature = "large-dates")]
403            Self::UnixTimestampMicrosecond(_) => 21,
404            #[cfg(not(feature = "large-dates"))]
405            Self::UnixTimestampMicrosecond(_) => 19,
406            #[cfg(feature = "large-dates")]
407            Self::UnixTimestampNanosecond(_) => 24,
408            #[cfg(not(feature = "large-dates"))]
409            Self::UnixTimestampNanosecond(_) => 22,
410            Self::Ignore(_) | Self::End(_) => 0,
411            FormatDescriptionV3Inner::BorrowedLiteral(s) => s.len(),
412            FormatDescriptionV3Inner::BorrowedCompound(items) => {
413                let mut max_bytes_needed = 0;
414                let mut idx = 0;
415                while idx < items.len() {
416                    max_bytes_needed += items[idx].max_bytes_needed();
417                    idx += 1;
418                }
419                max_bytes_needed
420            }
421            FormatDescriptionV3Inner::BorrowedOptional { format, item } => {
422                if *format {
423                    item.max_bytes_needed()
424                } else {
425                    0
426                }
427            }
428            FormatDescriptionV3Inner::BorrowedFirst(items) => {
429                if items.is_empty() {
430                    0
431                } else {
432                    items[0].max_bytes_needed()
433                }
434            }
435            FormatDescriptionV3Inner::OwnedLiteral(s) => s.len(),
436            FormatDescriptionV3Inner::OwnedCompound(items) => {
437                let mut max_bytes_needed = 0;
438                let mut idx = 0;
439                while idx < items.len() {
440                    max_bytes_needed += items[idx].max_bytes_needed();
441                    idx += 1;
442                }
443                max_bytes_needed
444            }
445            FormatDescriptionV3Inner::OwnedOptional { format, item } => {
446                if *format {
447                    item.max_bytes_needed()
448                } else {
449                    0
450                }
451            }
452            FormatDescriptionV3Inner::OwnedFirst(items) => {
453                if items.is_empty() {
454                    0
455                } else {
456                    items[0].max_bytes_needed()
457                }
458            }
459        }
460    }
461}
462
463/// A component of a larger format description.
464// public via `crate::format_description::__private` for macro use
465#[non_exhaustive]
466#[derive(Debug, Clone, Copy)]
467pub enum Component {
468    /// Day of the month.
469    Day(modifier::Day),
470    /// Month of the year in the abbreviated form (e.g. "Jan").
471    MonthShort(modifier::MonthShort),
472    /// Month of the year in the full form (e.g. "January").
473    MonthLong(modifier::MonthLong),
474    /// Month of the year in the numerical form (e.g. "1" for January).
475    MonthNumerical(modifier::MonthNumerical),
476    /// Ordinal day of the year.
477    Ordinal(modifier::Ordinal),
478    /// Weekday in the abbreviated form (e.g. "Mon").
479    WeekdayShort(modifier::WeekdayShort),
480    /// Weekday in the full form (e.g. "Monday").
481    WeekdayLong(modifier::WeekdayLong),
482    /// Weekday number where Sunday is either 0 or 1 depending on the modifier.
483    WeekdaySunday(modifier::WeekdaySunday),
484    /// Weekday number where Monday is either 0 or 1 depending on the modifier.
485    WeekdayMonday(modifier::WeekdayMonday),
486    /// Week number of the year, where week 1 starts is the week beginning on Monday that contains
487    /// January 4.
488    WeekNumberIso(modifier::WeekNumberIso),
489    /// Week number of the year, where week 1 starts on the first Sunday of the calendar year.
490    WeekNumberSunday(modifier::WeekNumberSunday),
491    /// Week number of the year, where week 1 starts on the first Monday of the calendar year.
492    WeekNumberMonday(modifier::WeekNumberMonday),
493    /// The calendar year. Supports the extended range.
494    CalendarYearFullExtendedRange(modifier::CalendarYearFullExtendedRange),
495    /// The calendar year. Does not support the extended range.
496    CalendarYearFullStandardRange(modifier::CalendarYearFullStandardRange),
497    /// The ISO week-based year. Supports the extended range.
498    IsoYearFullExtendedRange(modifier::IsoYearFullExtendedRange),
499    /// The ISO week-based year. Does not support the extended range.
500    IsoYearFullStandardRange(modifier::IsoYearFullStandardRange),
501    /// The century of the calendar year. Supports the extended range.
502    CalendarYearCenturyExtendedRange(modifier::CalendarYearCenturyExtendedRange),
503    /// The century of the calendar year. Does not support the extended range.
504    CalendarYearCenturyStandardRange(modifier::CalendarYearCenturyStandardRange),
505    /// The century of the ISO week-based year. Supports the extended range.
506    IsoYearCenturyExtendedRange(modifier::IsoYearCenturyExtendedRange),
507    /// The century of the ISO week-based year. Does not support the extended range.
508    IsoYearCenturyStandardRange(modifier::IsoYearCenturyStandardRange),
509    /// The last two digits of the calendar year.
510    CalendarYearLastTwo(modifier::CalendarYearLastTwo),
511    /// The last two digits of the ISO week-based year.
512    IsoYearLastTwo(modifier::IsoYearLastTwo),
513    /// Hour of the day using the 12-hour clock.
514    Hour12(modifier::Hour12),
515    /// Hour of the day using the 24-hour clock.
516    Hour24(modifier::Hour24),
517    /// Minute within the hour.
518    Minute(modifier::Minute),
519    /// AM/PM part of the time.
520    Period(modifier::Period),
521    /// Second within the minute.
522    Second(modifier::Second),
523    /// Subsecond within the second.
524    Subsecond(modifier::Subsecond),
525    /// Hour of the UTC offset.
526    OffsetHour(modifier::OffsetHour),
527    /// Minute within the hour of the UTC offset.
528    OffsetMinute(modifier::OffsetMinute),
529    /// Second within the minute of the UTC offset.
530    OffsetSecond(modifier::OffsetSecond),
531    /// A number of bytes to ignore when parsing. This has no effect on formatting.
532    Ignore(modifier::Ignore),
533    /// A Unix timestamp in seconds.
534    UnixTimestampSecond(modifier::UnixTimestampSecond),
535    /// A Unix timestamp in milliseconds.
536    UnixTimestampMillisecond(modifier::UnixTimestampMillisecond),
537    /// A Unix timestamp in microseconds.
538    UnixTimestampMicrosecond(modifier::UnixTimestampMicrosecond),
539    /// A Unix timestamp in nanoseconds.
540    UnixTimestampNanosecond(modifier::UnixTimestampNanosecond),
541    /// The end of input. Parsing this component will fail if there is any input remaining. This
542    /// component neither affects formatting nor consumes any input when parsing.
543    End(modifier::End),
544}