Skip to content

Commit

Permalink
Use parse_rfc3339 directly in DateTime::parse_from_rfc3339
Browse files Browse the repository at this point in the history
We want this to use the strict parser directly, so we can switch the `RFC3339`
item to a relaxed parser.
  • Loading branch information
pitdicker committed Aug 29, 2023
1 parent ccd7f85 commit 3f8a500
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 13 deletions.
12 changes: 8 additions & 4 deletions src/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ use std::time::{SystemTime, UNIX_EPOCH};

#[cfg(feature = "unstable-locales")]
use crate::format::Locale;
use crate::format::{parse, parse_and_remainder, ParseError, ParseResult, Parsed, StrftimeItems};
use crate::format::{
parse, parse_and_remainder, parse_rfc3339, Fixed, Item, ParseError, ParseResult, Parsed,
StrftimeItems, TOO_LONG,
};
#[cfg(any(feature = "alloc", feature = "std"))]
use crate::format::{write_rfc3339, DelayedFormat};
use crate::format::{Fixed, Item};
use crate::naive::{Days, IsoWeek, NaiveDate, NaiveDateTime, NaiveTime};
#[cfg(feature = "clock")]
use crate::offset::Local;
Expand Down Expand Up @@ -699,9 +701,11 @@ impl DateTime<FixedOffset> {
/// also simultaneously valid RFC 3339 values, but not all RFC 3339 values are valid ISO 8601
/// values (or the other way around).
pub fn parse_from_rfc3339(s: &str) -> ParseResult<DateTime<FixedOffset>> {
const ITEMS: &[Item<'static>] = &[Item::Fixed(Fixed::RFC3339)];
let mut parsed = Parsed::new();
parse(&mut parsed, s, ITEMS.iter())?;
let (s, _) = parse_rfc3339(&mut parsed, s)?;
if !s.is_empty() {
return Err(TOO_LONG);
}
parsed.to_datetime()
}

Expand Down
3 changes: 2 additions & 1 deletion src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub use formatting::{format_item_localized, format_localized};
pub use locales::Locale;
#[cfg(all(not(feature = "unstable-locales"), any(feature = "alloc", feature = "std")))]
pub(crate) use locales::Locale;
pub(crate) use parse::parse_rfc3339;
pub use parse::{parse, parse_and_remainder};
pub use parsed::Parsed;
pub use strftime::StrftimeItems;
Expand Down Expand Up @@ -450,7 +451,7 @@ const IMPOSSIBLE: ParseError = ParseError(ParseErrorKind::Impossible);
const NOT_ENOUGH: ParseError = ParseError(ParseErrorKind::NotEnough);
const INVALID: ParseError = ParseError(ParseErrorKind::Invalid);
const TOO_SHORT: ParseError = ParseError(ParseErrorKind::TooShort);
const TOO_LONG: ParseError = ParseError(ParseErrorKind::TooLong);
pub(crate) const TOO_LONG: ParseError = ParseError(ParseErrorKind::TooLong);
const BAD_FORMAT: ParseError = ParseError(ParseErrorKind::BadFormat);

// this implementation is here only because we need some private code from `scan`
Expand Down
10 changes: 2 additions & 8 deletions src/format/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st
Ok((s, ()))
}

fn parse_rfc3339<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a str, ())> {
pub(crate) fn parse_rfc3339<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a str, ())> {
macro_rules! try_consume {
($e:expr) => {{
let (s_, v) = $e?;
Expand Down Expand Up @@ -1817,15 +1817,9 @@ mod tests {
("2015-01-20T00:00:1-08:00", Err(INVALID)), // missing complete S
];

fn rfc3339_to_datetime(date: &str) -> ParseResult<DateTime<FixedOffset>> {
let mut parsed = Parsed::new();
parse(&mut parsed, date, [Item::Fixed(Fixed::RFC3339)].iter())?;
parsed.to_datetime()
}

// Test against test data above
for &(date, checkdate) in testdates.iter() {
let dt = rfc3339_to_datetime(date); // parse a date
let dt = DateTime::<FixedOffset>::parse_from_rfc3339(date);
if dt != checkdate {
// check for expected result
panic!(
Expand Down

0 comments on commit 3f8a500

Please sign in to comment.