diff options
Diffstat (limited to 'vendor/chrono/src/format/parse.rs')
-rw-r--r-- | vendor/chrono/src/format/parse.rs | 97 |
1 files changed, 70 insertions, 27 deletions
diff --git a/vendor/chrono/src/format/parse.rs b/vendor/chrono/src/format/parse.rs index 2fce8277b..69204d2e9 100644 --- a/vendor/chrono/src/format/parse.rs +++ b/vendor/chrono/src/format/parse.rs @@ -14,7 +14,7 @@ use super::scan; use super::{Fixed, InternalFixed, InternalInternal, Item, Numeric, Pad, Parsed}; use super::{ParseError, ParseErrorKind, ParseResult}; use super::{BAD_FORMAT, INVALID, NOT_ENOUGH, OUT_OF_RANGE, TOO_LONG, TOO_SHORT}; -use {DateTime, FixedOffset, Weekday}; +use crate::{DateTime, FixedOffset, Weekday}; fn set_weekday_with_num_days_from_sunday(p: &mut Parsed, v: i64) -> ParseResult<()> { p.set_weekday(match v { @@ -53,7 +53,10 @@ fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st // an adapted RFC 2822 syntax from Section 3.3 and 4.3: // - // date-time = [ day-of-week "," ] date 1*S time *S + // c-char = <any char except '(', ')' and '\\'> + // c-escape = "\" <any char> + // comment = "(" *(comment / c-char / c-escape) ")" *S + // date-time = [ day-of-week "," ] date 1*S time *S *comment // day-of-week = *S day-name *S // day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun" // date = day month year @@ -79,9 +82,10 @@ fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st // // - we do not recognize a folding white space (FWS) or comment (CFWS). // for our purposes, instead, we accept any sequence of Unicode - // white space characters (denoted here to `S`). any actual RFC 2822 - // parser is expected to parse FWS and/or CFWS themselves and replace - // it with a single SP (`%x20`); this is legitimate. + // white space characters (denoted here to `S`). For comments, we accept + // any text within parentheses while respecting escaped parentheses. + // Any actual RFC 2822 parser is expected to parse FWS and/or CFWS themselves + // and replace it with a single SP (`%x20`); this is legitimate. // // - two-digit year < 50 should be interpreted by adding 2000. // two-digit year >= 50 or three-digit year should be interpreted @@ -117,10 +121,10 @@ fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st let mut year = try_consume!(scan::number(s, 2, usize::MAX)); let yearlen = prevlen - s.len(); match (yearlen, year) { - (2, 0...49) => { + (2, 0..=49) => { year += 2000; } // 47 -> 2047, 05 -> 2005 - (2, 50...99) => { + (2, 50..=99) => { year += 1900; } // 79 -> 1979 (3, _) => { @@ -145,6 +149,11 @@ fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st parsed.set_offset(i64::from(offset))?; } + // optional comments + while let Ok((s_out, ())) = scan::comment_2822(s) { + s = s_out; + } + Ok((s, ())) } @@ -411,7 +420,10 @@ where try_consume!(scan::timezone_name_skip(s)); } - &TimezoneOffsetColon | &TimezoneOffset => { + &TimezoneOffsetColon + | &TimezoneOffsetDoubleColon + | &TimezoneOffsetTripleColon + | &TimezoneOffset => { let offset = try_consume!(scan::timezone_offset( s.trim_left(), scan::colon_or_space @@ -455,11 +467,22 @@ where } } +/// Accepts a relaxed form of RFC3339. +/// A space or a 'T' are acepted as the separator between the date and time +/// parts. Additional spaces are allowed between each component. +/// +/// All of these examples are equivalent: +/// ``` +/// # use chrono::{DateTime, offset::FixedOffset}; +/// "2012-12-12T12:12:12Z".parse::<DateTime<FixedOffset>>(); +/// "2012-12-12 12:12:12Z".parse::<DateTime<FixedOffset>>(); +/// "2012- 12-12T12: 12:12Z".parse::<DateTime<FixedOffset>>(); +/// ``` impl str::FromStr for DateTime<FixedOffset> { type Err = ParseError; fn from_str(s: &str) -> ParseResult<DateTime<FixedOffset>> { - const DATE_ITEMS: &'static [Item<'static>] = &[ + const DATE_ITEMS: &[Item<'static>] = &[ Item::Numeric(Numeric::Year, Pad::Zero), Item::Space(""), Item::Literal("-"), @@ -468,7 +491,7 @@ impl str::FromStr for DateTime<FixedOffset> { Item::Literal("-"), Item::Numeric(Numeric::Day, Pad::Zero), ]; - const TIME_ITEMS: &'static [Item<'static>] = &[ + const TIME_ITEMS: &[Item<'static>] = &[ Item::Numeric(Numeric::Hour, Pad::Zero), Item::Space(""), Item::Literal(":"), @@ -488,11 +511,11 @@ impl str::FromStr for DateTime<FixedOffset> { if remainder.starts_with('T') || remainder.starts_with(' ') { parse(&mut parsed, &remainder[1..], TIME_ITEMS.iter())?; } else { - Err(INVALID)?; + return Err(INVALID); } } - Err((_s, e)) => Err(e)?, - Ok(_) => Err(NOT_ENOUGH)?, + Err((_s, e)) => return Err(e), + Ok(_) => return Err(NOT_ENOUGH), }; parsed.to_datetime() } @@ -557,7 +580,7 @@ fn test_parse() { check!(" \t987", [num!(Year)]; year: 987); check!("5", [num!(Year)]; year: 5); check!("5\0", [num!(Year)]; TOO_LONG); - check!("\05", [num!(Year)]; INVALID); + check!("\x005", [num!(Year)]; INVALID); check!("", [num!(Year)]; TOO_SHORT); check!("12345", [num!(Year), lit!("5")]; year: 1234); check!("12345", [nums!(Year), lit!("5")]; year: 1234); @@ -798,14 +821,25 @@ fn test_parse() { fn test_rfc2822() { use super::NOT_ENOUGH; use super::*; - use offset::FixedOffset; - use DateTime; + use crate::offset::FixedOffset; + use crate::DateTime; // Test data - (input, Ok(expected result after parse and format) or Err(error code)) let testdates = [ ("Tue, 20 Jan 2015 17:35:20 -0800", Ok("Tue, 20 Jan 2015 17:35:20 -0800")), // normal case ("Fri, 2 Jan 2015 17:35:20 -0800", Ok("Fri, 02 Jan 2015 17:35:20 -0800")), // folding whitespace ("Fri, 02 Jan 2015 17:35:20 -0800", Ok("Fri, 02 Jan 2015 17:35:20 -0800")), // leading zero + ("Tue, 20 Jan 2015 17:35:20 -0800 (UTC)", Ok("Tue, 20 Jan 2015 17:35:20 -0800")), // trailing comment + ( + r"Tue, 20 Jan 2015 17:35:20 -0800 ( (UTC ) (\( (a)\(( \t ) ) \\( \) ))", + Ok("Tue, 20 Jan 2015 17:35:20 -0800"), + ), // complex trailing comment + (r"Tue, 20 Jan 2015 17:35:20 -0800 (UTC\)", Err(TOO_LONG)), // incorrect comment, not enough closing parentheses + ( + "Tue, 20 Jan 2015 17:35:20 -0800 (UTC)\t \r\n(Anothercomment)", + Ok("Tue, 20 Jan 2015 17:35:20 -0800"), + ), // multiple comments + ("Tue, 20 Jan 2015 17:35:20 -0800 (UTC) ", Err(TOO_LONG)), // trailing whitespace after comment ("20 Jan 2015 17:35:20 -0800", Ok("Tue, 20 Jan 2015 17:35:20 -0800")), // no day of week ("20 JAN 2015 17:35:20 -0800", Ok("Tue, 20 Jan 2015 17:35:20 -0800")), // upper case month ("Tue, 20 Jan 2015 17:35 -0800", Ok("Tue, 20 Jan 2015 17:35:00 -0800")), // no second @@ -853,12 +887,12 @@ fn test_rfc2822() { #[cfg(test)] #[test] fn parse_rfc850() { - use {TimeZone, Utc}; + use crate::{TimeZone, Utc}; - static RFC850_FMT: &'static str = "%A, %d-%b-%y %T GMT"; + static RFC850_FMT: &str = "%A, %d-%b-%y %T GMT"; let dt_str = "Sunday, 06-Nov-94 08:49:37 GMT"; - let dt = Utc.ymd(1994, 11, 6).and_hms(8, 49, 37); + let dt = Utc.with_ymd_and_hms(1994, 11, 6, 8, 49, 37).unwrap(); // Check that the format is what we expect assert_eq!(dt.format(RFC850_FMT).to_string(), dt_str); @@ -869,12 +903,21 @@ fn parse_rfc850() { // Check that the rest of the weekdays parse correctly (this test originally failed because // Sunday parsed incorrectly). let testdates = [ - (Utc.ymd(1994, 11, 7).and_hms(8, 49, 37), "Monday, 07-Nov-94 08:49:37 GMT"), - (Utc.ymd(1994, 11, 8).and_hms(8, 49, 37), "Tuesday, 08-Nov-94 08:49:37 GMT"), - (Utc.ymd(1994, 11, 9).and_hms(8, 49, 37), "Wednesday, 09-Nov-94 08:49:37 GMT"), - (Utc.ymd(1994, 11, 10).and_hms(8, 49, 37), "Thursday, 10-Nov-94 08:49:37 GMT"), - (Utc.ymd(1994, 11, 11).and_hms(8, 49, 37), "Friday, 11-Nov-94 08:49:37 GMT"), - (Utc.ymd(1994, 11, 12).and_hms(8, 49, 37), "Saturday, 12-Nov-94 08:49:37 GMT"), + (Utc.with_ymd_and_hms(1994, 11, 7, 8, 49, 37).unwrap(), "Monday, 07-Nov-94 08:49:37 GMT"), + (Utc.with_ymd_and_hms(1994, 11, 8, 8, 49, 37).unwrap(), "Tuesday, 08-Nov-94 08:49:37 GMT"), + ( + Utc.with_ymd_and_hms(1994, 11, 9, 8, 49, 37).unwrap(), + "Wednesday, 09-Nov-94 08:49:37 GMT", + ), + ( + Utc.with_ymd_and_hms(1994, 11, 10, 8, 49, 37).unwrap(), + "Thursday, 10-Nov-94 08:49:37 GMT", + ), + (Utc.with_ymd_and_hms(1994, 11, 11, 8, 49, 37).unwrap(), "Friday, 11-Nov-94 08:49:37 GMT"), + ( + Utc.with_ymd_and_hms(1994, 11, 12, 8, 49, 37).unwrap(), + "Saturday, 12-Nov-94 08:49:37 GMT", + ), ]; for val in &testdates { @@ -886,8 +929,8 @@ fn parse_rfc850() { #[test] fn test_rfc3339() { use super::*; - use offset::FixedOffset; - use DateTime; + use crate::offset::FixedOffset; + use crate::DateTime; // Test data - (input, Ok(expected result after parse and format) or Err(error code)) let testdates = [ |