summaryrefslogtreecommitdiffstats
path: root/vendor/time/src/parsing
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/time/src/parsing
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/time/src/parsing')
-rw-r--r--vendor/time/src/parsing/component.rs46
-rw-r--r--vendor/time/src/parsing/parsable.rs44
-rw-r--r--vendor/time/src/parsing/parsed.rs179
-rw-r--r--vendor/time/src/parsing/shim.rs2
4 files changed, 195 insertions, 76 deletions
diff --git a/vendor/time/src/parsing/component.rs b/vendor/time/src/parsing/component.rs
index 38d632a0d..e7b852706 100644
--- a/vendor/time/src/parsing/component.rs
+++ b/vendor/time/src/parsing/component.rs
@@ -6,7 +6,7 @@ use crate::format_description::modifier;
#[cfg(feature = "large-dates")]
use crate::parsing::combinator::n_to_m_digits_padded;
use crate::parsing::combinator::{
- any_digit, exactly_n_digits, exactly_n_digits_padded, first_match, opt, sign,
+ any_digit, exactly_n_digits, exactly_n_digits_padded, first_match, n_to_m_digits, opt, sign,
};
use crate::parsing::ParsedItem;
use crate::{Month, Weekday};
@@ -259,16 +259,18 @@ pub(crate) fn parse_subsecond(
// region: offset components
/// Parse the "hour" component of a `UtcOffset`.
+///
+/// Returns the value and whether the value is negative. This is used for when "-0" is parsed.
pub(crate) fn parse_offset_hour(
input: &[u8],
modifiers: modifier::OffsetHour,
-) -> Option<ParsedItem<'_, i8>> {
+) -> Option<ParsedItem<'_, (i8, bool)>> {
let ParsedItem(input, sign) = opt(sign)(input);
let ParsedItem(input, hour) = exactly_n_digits_padded::<2, u8>(modifiers.padding)(input)?;
match sign {
- Some(b'-') => Some(ParsedItem(input, -(hour as i8))),
+ Some(b'-') => Some(ParsedItem(input, (-(hour as i8), true))),
None if modifiers.sign_is_mandatory => None,
- _ => Some(ParsedItem(input, hour as i8)),
+ _ => Some(ParsedItem(input, (hour as i8, false))),
}
}
@@ -294,3 +296,39 @@ pub(crate) fn parse_offset_second(
)
}
// endregion offset components
+
+/// Ignore the given number of bytes.
+pub(crate) fn parse_ignore(
+ input: &[u8],
+ modifiers: modifier::Ignore,
+) -> Option<ParsedItem<'_, ()>> {
+ let modifier::Ignore { count } = modifiers;
+ let input = input.get((count.get() as usize)..)?;
+ Some(ParsedItem(input, ()))
+}
+
+/// Parse the Unix timestamp component.
+pub(crate) fn parse_unix_timestamp(
+ input: &[u8],
+ modifiers: modifier::UnixTimestamp,
+) -> Option<ParsedItem<'_, i128>> {
+ let ParsedItem(input, sign) = opt(sign)(input);
+ let ParsedItem(input, nano_timestamp) = match modifiers.precision {
+ modifier::UnixTimestampPrecision::Second => {
+ n_to_m_digits::<1, 14, u128>(input)?.map(|val| val * 1_000_000_000)
+ }
+ modifier::UnixTimestampPrecision::Millisecond => {
+ n_to_m_digits::<1, 17, u128>(input)?.map(|val| val * 1_000_000)
+ }
+ modifier::UnixTimestampPrecision::Microsecond => {
+ n_to_m_digits::<1, 20, u128>(input)?.map(|val| val * 1_000)
+ }
+ modifier::UnixTimestampPrecision::Nanosecond => n_to_m_digits::<1, 23, _>(input)?,
+ };
+
+ match sign {
+ Some(b'-') => Some(ParsedItem(input, -(nano_timestamp as i128))),
+ None if modifiers.sign_is_mandatory => None,
+ _ => Some(ParsedItem(input, nano_timestamp as _)),
+ }
+}
diff --git a/vendor/time/src/parsing/parsable.rs b/vendor/time/src/parsing/parsable.rs
index badb63808..78bbe64f0 100644
--- a/vendor/time/src/parsing/parsable.rs
+++ b/vendor/time/src/parsing/parsable.rs
@@ -2,6 +2,7 @@
use core::ops::Deref;
+use crate::date_time::{maybe_offset_from_offset, MaybeOffset};
use crate::error::TryFromParsed;
use crate::format_description::well_known::iso8601::EncodedConfig;
use crate::format_description::well_known::{Iso8601, Rfc2822, Rfc3339};
@@ -9,7 +10,7 @@ use crate::format_description::FormatItem;
#[cfg(feature = "alloc")]
use crate::format_description::OwnedFormatItem;
use crate::parsing::{Parsed, ParsedItem};
-use crate::{error, Date, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday};
+use crate::{error, Date, DateTime, Month, Time, UtcOffset, Weekday};
/// A type that can be parsed.
#[cfg_attr(__time_03_docs, doc(notable_trait))]
@@ -28,7 +29,6 @@ impl<T: Deref> Parsable for T where T::Target: Parsable {}
/// Seal the trait to prevent downstream users from implementing it, while still allowing it to
/// exist in generic bounds.
mod sealed {
-
#[allow(clippy::wildcard_imports)]
use super::*;
@@ -71,13 +71,11 @@ mod sealed {
Ok(self.parse(input)?.try_into()?)
}
- /// Parse a [`PrimitiveDateTime`] from the format description.
- fn parse_date_time(&self, input: &[u8]) -> Result<PrimitiveDateTime, error::Parse> {
- Ok(self.parse(input)?.try_into()?)
- }
-
- /// Parse a [`OffsetDateTime`] from the format description.
- fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> {
+ /// Parse a [`DateTime`] from the format description.
+ fn parse_date_time<O: MaybeOffset>(
+ &self,
+ input: &[u8],
+ ) -> Result<DateTime<O>, error::Parse> {
Ok(self.parse(input)?.try_into()?)
}
}
@@ -239,7 +237,7 @@ impl sealed::Sealed for Rfc2822 {
};
// The RFC explicitly allows leap seconds.
- parsed.set_leap_second_allowed(true);
+ parsed.set_flag(Parsed::LEAP_SECOND_ALLOWED_FLAG, true);
#[allow(clippy::unnecessary_lazy_evaluations)] // rust-lang/rust-clippy#8522
let zone_literal = first_match(
@@ -299,7 +297,7 @@ impl sealed::Sealed for Rfc2822 {
Ok(input)
}
- fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> {
+ fn parse_date_time<O: MaybeOffset>(&self, input: &[u8]) -> Result<DateTime<O>, error::Parse> {
use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral};
use crate::parsing::combinator::rfc::rfc2822::{cfws, fws};
use crate::parsing::combinator::{
@@ -436,7 +434,9 @@ impl sealed::Sealed for Rfc2822 {
}
let mut nanosecond = 0;
- let leap_second_input = if second == 60 {
+ let leap_second_input = if !O::HAS_LOGICAL_OFFSET {
+ false
+ } else if second == 60 {
second = 59;
nanosecond = 999_999_999;
true
@@ -448,7 +448,11 @@ impl sealed::Sealed for Rfc2822 {
let date = Date::from_calendar_date(year as _, month, day)?;
let time = Time::from_hms_nano(hour, minute, second, nanosecond)?;
let offset = UtcOffset::from_hms(offset_hour, offset_minute, 0)?;
- Ok(date.with_time(time).assume_offset(offset))
+ Ok(DateTime {
+ date,
+ time,
+ offset: maybe_offset_from_offset::<O>(offset),
+ })
})()
.map_err(TryFromParsed::ComponentRange)?;
@@ -529,7 +533,7 @@ impl sealed::Sealed for Rfc3339 {
};
// The RFC explicitly allows leap seconds.
- parsed.set_leap_second_allowed(true);
+ parsed.set_flag(Parsed::LEAP_SECOND_ALLOWED_FLAG, true);
if let Some(ParsedItem(input, ())) = ascii_char_ignore_case::<b'Z'>(input) {
parsed
@@ -574,7 +578,7 @@ impl sealed::Sealed for Rfc3339 {
Ok(input)
}
- fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> {
+ fn parse_date_time<O: MaybeOffset>(&self, input: &[u8]) -> Result<DateTime<O>, error::Parse> {
use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral};
use crate::parsing::combinator::{
any_digit, ascii_char, ascii_char_ignore_case, exactly_n_digits, sign,
@@ -672,11 +676,13 @@ impl sealed::Sealed for Rfc3339 {
false
};
- let dt = Month::from_number(month)
+ let date = Month::from_number(month)
.and_then(|month| Date::from_calendar_date(year as _, month, day))
- .and_then(|date| date.with_hms_nano(hour, minute, second, nanosecond))
- .map(|date| date.assume_offset(offset))
.map_err(TryFromParsed::ComponentRange)?;
+ let time = Time::from_hms_nano(hour, minute, second, nanosecond)
+ .map_err(TryFromParsed::ComponentRange)?;
+ let offset = maybe_offset_from_offset::<O>(offset);
+ let dt = DateTime { date, time, offset };
if leap_second_input && !dt.is_valid_leap_second_stand_in() {
return Err(error::Parse::TryFromParsed(TryFromParsed::ComponentRange(
@@ -744,7 +750,7 @@ impl<const CONFIG: EncodedConfig> sealed::Sealed for Iso8601<CONFIG> {
if !date_is_present && !time_is_present && !offset_is_present {
match first_error {
Some(err) => return Err(err),
- None => unreachable!("an error should be present if no components were parsed"),
+ None => bug!("an error should be present if no components were parsed"),
}
}
diff --git a/vendor/time/src/parsing/parsed.rs b/vendor/time/src/parsing/parsed.rs
index 7b2279cbb..26405cb11 100644
--- a/vendor/time/src/parsing/parsed.rs
+++ b/vendor/time/src/parsing/parsed.rs
@@ -3,15 +3,16 @@
use core::mem::MaybeUninit;
use core::num::{NonZeroU16, NonZeroU8};
+use crate::date_time::{maybe_offset_from_offset, offset_kind, DateTime, MaybeOffset};
use crate::error::TryFromParsed::InsufficientInformation;
use crate::format_description::modifier::{WeekNumberRepr, YearRepr};
#[cfg(feature = "alloc")]
use crate::format_description::OwnedFormatItem;
use crate::format_description::{Component, FormatItem};
use crate::parsing::component::{
- parse_day, parse_hour, parse_minute, parse_month, parse_offset_hour, parse_offset_minute,
- parse_offset_second, parse_ordinal, parse_period, parse_second, parse_subsecond,
- parse_week_number, parse_weekday, parse_year, Period,
+ parse_day, parse_hour, parse_ignore, parse_minute, parse_month, parse_offset_hour,
+ parse_offset_minute, parse_offset_second, parse_ordinal, parse_period, parse_second,
+ parse_subsecond, parse_unix_timestamp, parse_week_number, parse_weekday, parse_year, Period,
};
use crate::parsing::ParsedItem;
use crate::{error, Date, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday};
@@ -98,6 +99,10 @@ impl sealed::AnyFormatItem for OwnedFormatItem {
}
}
+/// The type of the `flags` field in [`Parsed`]. Allows for changing a single location and having it
+/// effect all uses.
+type Flag = u32;
+
/// All information parsed.
///
/// This information is directly used to construct the final values.
@@ -107,7 +112,7 @@ impl sealed::AnyFormatItem for OwnedFormatItem {
#[derive(Debug, Clone, Copy)]
pub struct Parsed {
/// Bitflags indicating whether a particular field is present.
- flags: u16,
+ flags: Flag,
/// Calendar year.
year: MaybeUninit<i32>,
/// The last two digits of the calendar year.
@@ -149,26 +154,35 @@ pub struct Parsed {
offset_minute: MaybeUninit<i8>,
/// Seconds within the minute of the UTC offset.
offset_second: MaybeUninit<i8>,
+ /// The Unix timestamp in nanoseconds.
+ unix_timestamp_nanos: MaybeUninit<i128>,
}
#[allow(clippy::missing_docs_in_private_items)]
impl Parsed {
- const YEAR_FLAG: u16 = 1 << 0;
- const YEAR_LAST_TWO_FLAG: u16 = 1 << 1;
- const ISO_YEAR_FLAG: u16 = 1 << 2;
- const ISO_YEAR_LAST_TWO_FLAG: u16 = 1 << 3;
- const SUNDAY_WEEK_NUMBER_FLAG: u16 = 1 << 4;
- const MONDAY_WEEK_NUMBER_FLAG: u16 = 1 << 5;
- const HOUR_24_FLAG: u16 = 1 << 6;
- const MINUTE_FLAG: u16 = 1 << 7;
- const SECOND_FLAG: u16 = 1 << 8;
- const SUBSECOND_FLAG: u16 = 1 << 9;
- const OFFSET_HOUR_FLAG: u16 = 1 << 10;
- const OFFSET_MINUTE_FLAG: u16 = 1 << 11;
- const OFFSET_SECOND_FLAG: u16 = 1 << 12;
+ const YEAR_FLAG: Flag = 1 << 0;
+ const YEAR_LAST_TWO_FLAG: Flag = 1 << 1;
+ const ISO_YEAR_FLAG: Flag = 1 << 2;
+ const ISO_YEAR_LAST_TWO_FLAG: Flag = 1 << 3;
+ const SUNDAY_WEEK_NUMBER_FLAG: Flag = 1 << 4;
+ const MONDAY_WEEK_NUMBER_FLAG: Flag = 1 << 5;
+ const HOUR_24_FLAG: Flag = 1 << 6;
+ const MINUTE_FLAG: Flag = 1 << 7;
+ const SECOND_FLAG: Flag = 1 << 8;
+ const SUBSECOND_FLAG: Flag = 1 << 9;
+ const OFFSET_HOUR_FLAG: Flag = 1 << 10;
+ const OFFSET_MINUTE_FLAG: Flag = 1 << 11;
+ const OFFSET_SECOND_FLAG: Flag = 1 << 12;
/// Indicates whether a leap second is permitted to be parsed. This is required by some
/// well-known formats.
- const LEAP_SECOND_ALLOWED_FLAG: u16 = 1 << 13;
+ pub(super) const LEAP_SECOND_ALLOWED_FLAG: Flag = 1 << 13;
+ /// Indicates whether the `UtcOffset` is negative. This information is obtained when parsing the
+ /// offset hour, but may not otherwise be stored due to "-0" being equivalent to "0".
+ const OFFSET_IS_NEGATIVE_FLAG: Flag = 1 << 14;
+ /// Does the value at `OFFSET_IS_NEGATIVE_FLAG` have any semantic meaning, or is it just the
+ /// default value? If the latter, the value should be considered to have no meaning.
+ const OFFSET_IS_NEGATIVE_FLAG_IS_INITIALIZED: Flag = 1 << 15;
+ const UNIX_TIMESTAMP_NANOS_FLAG: Flag = 1 << 16;
}
impl Parsed {
@@ -196,6 +210,7 @@ impl Parsed {
offset_hour: MaybeUninit::uninit(),
offset_minute: MaybeUninit::uninit(),
offset_second: MaybeUninit::uninit(),
+ unix_timestamp_nanos: MaybeUninit::uninit(),
}
}
@@ -315,7 +330,13 @@ impl Parsed {
.and_then(|parsed| parsed.consume_value(|value| self.set_subsecond(value)))
.ok_or(InvalidComponent("subsecond")),
Component::OffsetHour(modifiers) => parse_offset_hour(input, modifiers)
- .and_then(|parsed| parsed.consume_value(|value| self.set_offset_hour(value)))
+ .and_then(|parsed| {
+ parsed.consume_value(|(value, is_negative)| {
+ self.set_flag(Self::OFFSET_IS_NEGATIVE_FLAG_IS_INITIALIZED, true);
+ self.set_flag(Self::OFFSET_IS_NEGATIVE_FLAG, is_negative);
+ self.set_offset_hour(value)
+ })
+ })
.ok_or(InvalidComponent("offset hour")),
Component::OffsetMinute(modifiers) => parse_offset_minute(input, modifiers)
.and_then(|parsed| {
@@ -327,6 +348,28 @@ impl Parsed {
parsed.consume_value(|value| self.set_offset_second_signed(value))
})
.ok_or(InvalidComponent("offset second")),
+ Component::Ignore(modifiers) => parse_ignore(input, modifiers)
+ .map(ParsedItem::<()>::into_inner)
+ .ok_or(InvalidComponent("ignore")),
+ Component::UnixTimestamp(modifiers) => parse_unix_timestamp(input, modifiers)
+ .and_then(|parsed| {
+ parsed.consume_value(|value| self.set_unix_timestamp_nanos(value))
+ })
+ .ok_or(InvalidComponent("unix_timestamp")),
+ }
+ }
+
+ /// Get the value of the provided flag.
+ const fn get_flag(&self, flag: Flag) -> bool {
+ self.flags & flag == flag
+ }
+
+ /// Set the value of the provided flag.
+ pub(super) fn set_flag(&mut self, flag: Flag, value: bool) {
+ if value {
+ self.flags |= flag;
+ } else {
+ self.flags &= !flag;
}
}
}
@@ -345,7 +388,7 @@ macro_rules! getters {
(! @$flag:ident $name:ident : $ty:ty) => {
/// Obtain the named component.
pub const fn $name(&self) -> Option<$ty> {
- if self.flags & Self::$flag != Self::$flag {
+ if !self.get_flag(Self::$flag) {
None
} else {
// SAFETY: We just checked if the field is present.
@@ -376,6 +419,7 @@ impl Parsed {
@SECOND_FLAG second: u8,
@SUBSECOND_FLAG subsecond: u32,
@OFFSET_HOUR_FLAG offset_hour: i8,
+ @UNIX_TIMESTAMP_NANOS_FLAG unix_timestamp_nanos: i128,
}
/// Obtain the absolute value of the offset minute.
@@ -386,11 +430,19 @@ impl Parsed {
/// Obtain the offset minute as an `i8`.
pub const fn offset_minute_signed(&self) -> Option<i8> {
- if self.flags & Self::OFFSET_MINUTE_FLAG != Self::OFFSET_MINUTE_FLAG {
+ if !self.get_flag(Self::OFFSET_MINUTE_FLAG) {
None
} else {
// SAFETY: We just checked if the field is present.
- Some(unsafe { self.offset_minute.assume_init() })
+ let value = unsafe { self.offset_minute.assume_init() };
+
+ if self.get_flag(Self::OFFSET_IS_NEGATIVE_FLAG_IS_INITIALIZED)
+ && (value.is_negative() != self.get_flag(Self::OFFSET_IS_NEGATIVE_FLAG))
+ {
+ Some(-value)
+ } else {
+ Some(value)
+ }
}
}
@@ -402,17 +454,20 @@ impl Parsed {
/// Obtain the offset second as an `i8`.
pub const fn offset_second_signed(&self) -> Option<i8> {
- if self.flags & Self::OFFSET_SECOND_FLAG != Self::OFFSET_SECOND_FLAG {
+ if !self.get_flag(Self::OFFSET_SECOND_FLAG) {
None
} else {
// SAFETY: We just checked if the field is present.
- Some(unsafe { self.offset_second.assume_init() })
- }
- }
+ let value = unsafe { self.offset_second.assume_init() };
- /// Obtain whether leap seconds are permitted in the current format.
- pub(crate) const fn leap_second_allowed(&self) -> bool {
- self.flags & Self::LEAP_SECOND_ALLOWED_FLAG == Self::LEAP_SECOND_ALLOWED_FLAG
+ if self.get_flag(Self::OFFSET_IS_NEGATIVE_FLAG_IS_INITIALIZED)
+ && (value.is_negative() != self.get_flag(Self::OFFSET_IS_NEGATIVE_FLAG))
+ {
+ Some(-value)
+ } else {
+ Some(value)
+ }
+ }
}
}
@@ -434,7 +489,7 @@ macro_rules! setters {
/// Set the named component.
pub fn $setter_name(&mut self, value: $ty) -> Option<()> {
self.$name = MaybeUninit::new(value);
- self.flags |= Self::$flag;
+ self.set_flag(Self::$flag, true);
Some(())
}
};
@@ -464,6 +519,7 @@ impl Parsed {
@SECOND_FLAG set_second second: u8,
@SUBSECOND_FLAG set_subsecond subsecond: u32,
@OFFSET_HOUR_FLAG set_offset_hour offset_hour: i8,
+ @UNIX_TIMESTAMP_NANOS_FLAG set_unix_timestamp_nanos unix_timestamp_nanos: i128,
}
/// Set the named component.
@@ -482,7 +538,7 @@ impl Parsed {
/// Set the `offset_minute` component.
pub fn set_offset_minute_signed(&mut self, value: i8) -> Option<()> {
self.offset_minute = MaybeUninit::new(value);
- self.flags |= Self::OFFSET_MINUTE_FLAG;
+ self.set_flag(Self::OFFSET_MINUTE_FLAG, true);
Some(())
}
@@ -502,18 +558,9 @@ impl Parsed {
/// Set the `offset_second` component.
pub fn set_offset_second_signed(&mut self, value: i8) -> Option<()> {
self.offset_second = MaybeUninit::new(value);
- self.flags |= Self::OFFSET_SECOND_FLAG;
+ self.set_flag(Self::OFFSET_SECOND_FLAG, true);
Some(())
}
-
- /// Set the leap second allowed flag.
- pub(crate) fn set_leap_second_allowed(&mut self, value: bool) {
- if value {
- self.flags |= Self::LEAP_SECOND_ALLOWED_FLAG;
- } else {
- self.flags &= !Self::LEAP_SECOND_ALLOWED_FLAG;
- }
- }
}
/// Generate build methods for each of the fields.
@@ -564,6 +611,7 @@ impl Parsed {
@SECOND_FLAG with_second second: u8,
@SUBSECOND_FLAG with_subsecond subsecond: u32,
@OFFSET_HOUR_FLAG with_offset_hour offset_hour: i8,
+ @UNIX_TIMESTAMP_NANOS_FLAG with_unix_timestamp_nanos unix_timestamp_nanos: i128,
}
/// Set the named component and return `self`.
@@ -718,31 +766,58 @@ impl TryFrom<Parsed> for UtcOffset {
}
impl TryFrom<Parsed> for PrimitiveDateTime {
- type Error = error::TryFromParsed;
+ type Error = <DateTime<offset_kind::None> as TryFrom<Parsed>>::Error;
fn try_from(parsed: Parsed) -> Result<Self, Self::Error> {
- Ok(Self::new(parsed.try_into()?, parsed.try_into()?))
+ parsed.try_into().map(Self)
}
}
impl TryFrom<Parsed> for OffsetDateTime {
+ type Error = <DateTime<offset_kind::Fixed> as TryFrom<Parsed>>::Error;
+
+ fn try_from(parsed: Parsed) -> Result<Self, Self::Error> {
+ parsed.try_into().map(Self)
+ }
+}
+
+impl<O: MaybeOffset> TryFrom<Parsed> for DateTime<O> {
type Error = error::TryFromParsed;
#[allow(clippy::unwrap_in_result)] // We know the values are valid.
fn try_from(mut parsed: Parsed) -> Result<Self, Self::Error> {
+ if O::HAS_LOGICAL_OFFSET {
+ if let Some(timestamp) = parsed.unix_timestamp_nanos() {
+ let DateTime { date, time, offset } =
+ DateTime::<offset_kind::Fixed>::from_unix_timestamp_nanos(timestamp)?;
+ return Ok(Self {
+ date,
+ time,
+ offset: maybe_offset_from_offset::<O>(offset),
+ });
+ }
+ }
+
// Some well-known formats explicitly allow leap seconds. We don't currently support them,
// so treat it as the nearest preceding moment that can be represented. Because leap seconds
// always fall at the end of a month UTC, reject any that are at other times.
- let leap_second_input = if parsed.leap_second_allowed() && parsed.second() == Some(60) {
- parsed.set_second(59).expect("59 is a valid second");
- parsed
- .set_subsecond(999_999_999)
- .expect("999_999_999 is a valid subsecond");
- true
- } else {
- false
+ let leap_second_input =
+ if parsed.get_flag(Parsed::LEAP_SECOND_ALLOWED_FLAG) && parsed.second() == Some(60) {
+ parsed.set_second(59).expect("59 is a valid second");
+ parsed
+ .set_subsecond(999_999_999)
+ .expect("999_999_999 is a valid subsecond");
+ true
+ } else {
+ false
+ };
+
+ let dt = Self {
+ date: Date::try_from(parsed)?,
+ time: Time::try_from(parsed)?,
+ offset: O::try_from_parsed(parsed)?,
};
- let dt = PrimitiveDateTime::try_from(parsed)?.assume_offset(parsed.try_into()?);
+
if leap_second_input && !dt.is_valid_leap_second_stand_in() {
return Err(error::TryFromParsed::ComponentRange(
error::ComponentRange {
diff --git a/vendor/time/src/parsing/shim.rs b/vendor/time/src/parsing/shim.rs
index 00aaf4852..ced7feb03 100644
--- a/vendor/time/src/parsing/shim.rs
+++ b/vendor/time/src/parsing/shim.rs
@@ -31,7 +31,7 @@ macro_rules! impl_parse_bytes {
}
)*)
}
-impl_parse_bytes! { u8 u16 u32 }
+impl_parse_bytes! { u8 u16 u32 u128 }
/// Parse the given types from bytes.
macro_rules! impl_parse_bytes_nonzero {