summaryrefslogtreecommitdiffstats
path: root/vendor/time/src/parsing/parsable.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/time/src/parsing/parsable.rs')
-rw-r--r--vendor/time/src/parsing/parsable.rs44
1 files changed, 25 insertions, 19 deletions
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"),
}
}