summaryrefslogtreecommitdiffstats
path: root/vendor/chrono/src/format/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chrono/src/format/parse.rs')
-rw-r--r--vendor/chrono/src/format/parse.rs71
1 files changed, 68 insertions, 3 deletions
diff --git a/vendor/chrono/src/format/parse.rs b/vendor/chrono/src/format/parse.rs
index 69204d2e9..ed3f91f6d 100644
--- a/vendor/chrono/src/format/parse.rs
+++ b/vendor/chrono/src/format/parse.rs
@@ -248,6 +248,36 @@ where
parse_internal(parsed, s, items).map(|_| ()).map_err(|(_s, e)| e)
}
+/// Tries to parse given string into `parsed` with given formatting items.
+/// Returns `Ok` with a slice of the unparsed remainder.
+///
+/// This particular date and time parser is:
+///
+/// - Greedy. It will consume the longest possible prefix.
+/// For example, `April` is always consumed entirely when the long month name is requested;
+/// it equally accepts `Apr`, but prefers the longer prefix in this case.
+///
+/// - Padding-agnostic (for numeric items).
+/// The [`Pad`](./enum.Pad.html) field is completely ignored,
+/// so one can prepend any number of zeroes before numbers.
+///
+/// - (Still) obeying the intrinsic parsing width. This allows, for example, parsing `HHMMSS`.
+pub fn parse_and_remainder<'a, 'b, I, B>(
+ parsed: &mut Parsed,
+ s: &'b str,
+ items: I,
+) -> ParseResult<&'b str>
+where
+ I: Iterator<Item = B>,
+ B: Borrow<Item<'a>>,
+{
+ match parse_internal(parsed, s, items) {
+ Ok(s) => Ok(s),
+ Err((s, ParseError(ParseErrorKind::TooLong))) => Ok(s),
+ Err((_s, e)) => Err(e),
+ }
+}
+
fn parse_internal<'a, 'b, I, B>(
parsed: &mut Parsed,
mut s: &'b str,
@@ -474,9 +504,10 @@ where
/// 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>>();
+/// "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>>()?;
+/// # Ok::<(), chrono::ParseError>(())
/// ```
impl str::FromStr for DateTime<FixedOffset> {
type Err = ParseError;
@@ -686,6 +717,7 @@ fn test_parse() {
// fixed: dot plus nanoseconds
check!("", [fix!(Nanosecond)]; ); // no field set, but not an error
+ check!(".", [fix!(Nanosecond)]; TOO_SHORT);
check!("4", [fix!(Nanosecond)]; TOO_LONG); // never consumes `4`
check!("4", [fix!(Nanosecond), num!(Second)]; second: 4);
check!(".0", [fix!(Nanosecond)]; nanosecond: 0);
@@ -704,6 +736,7 @@ fn test_parse() {
// fixed: nanoseconds without the dot
check!("", [internal_fix!(Nanosecond3NoDot)]; TOO_SHORT);
+ check!(".", [internal_fix!(Nanosecond3NoDot)]; TOO_SHORT);
check!("0", [internal_fix!(Nanosecond3NoDot)]; TOO_SHORT);
check!("4", [internal_fix!(Nanosecond3NoDot)]; TOO_SHORT);
check!("42", [internal_fix!(Nanosecond3NoDot)]; TOO_SHORT);
@@ -715,6 +748,7 @@ fn test_parse() {
check!(".421", [internal_fix!(Nanosecond3NoDot)]; INVALID);
check!("", [internal_fix!(Nanosecond6NoDot)]; TOO_SHORT);
+ check!(".", [internal_fix!(Nanosecond6NoDot)]; TOO_SHORT);
check!("0", [internal_fix!(Nanosecond6NoDot)]; TOO_SHORT);
check!("42195", [internal_fix!(Nanosecond6NoDot)]; TOO_SHORT);
check!("421950", [internal_fix!(Nanosecond6NoDot)]; nanosecond: 421_950_000);
@@ -725,6 +759,7 @@ fn test_parse() {
check!(".42100", [internal_fix!(Nanosecond6NoDot)]; INVALID);
check!("", [internal_fix!(Nanosecond9NoDot)]; TOO_SHORT);
+ check!(".", [internal_fix!(Nanosecond9NoDot)]; TOO_SHORT);
check!("42195", [internal_fix!(Nanosecond9NoDot)]; TOO_SHORT);
check!("421950803", [internal_fix!(Nanosecond9NoDot)]; nanosecond: 421_950_803);
check!("000000003", [internal_fix!(Nanosecond9NoDot)]; nanosecond: 3);
@@ -854,6 +889,28 @@ fn test_rfc2822() {
("Tue, 20 Jan 2015 17:35:20 -0890", Err(OUT_OF_RANGE)), // bad offset
("6 Jun 1944 04:00:00Z", Err(INVALID)), // bad offset (zulu not allowed)
("Tue, 20 Jan 2015 17:35:20 HAS", Err(NOT_ENOUGH)), // bad named time zone
+ // named timezones that have specific timezone offsets
+ // see https://www.rfc-editor.org/rfc/rfc2822#section-4.3
+ ("Tue, 20 Jan 2015 17:35:20 GMT", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
+ ("Tue, 20 Jan 2015 17:35:20 UT", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
+ ("Tue, 20 Jan 2015 17:35:20 ut", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
+ ("Tue, 20 Jan 2015 17:35:20 EDT", Ok("Tue, 20 Jan 2015 17:35:20 -0400")),
+ ("Tue, 20 Jan 2015 17:35:20 EST", Ok("Tue, 20 Jan 2015 17:35:20 -0500")),
+ ("Tue, 20 Jan 2015 17:35:20 CDT", Ok("Tue, 20 Jan 2015 17:35:20 -0500")),
+ ("Tue, 20 Jan 2015 17:35:20 CST", Ok("Tue, 20 Jan 2015 17:35:20 -0600")),
+ ("Tue, 20 Jan 2015 17:35:20 MDT", Ok("Tue, 20 Jan 2015 17:35:20 -0600")),
+ ("Tue, 20 Jan 2015 17:35:20 MST", Ok("Tue, 20 Jan 2015 17:35:20 -0700")),
+ ("Tue, 20 Jan 2015 17:35:20 PDT", Ok("Tue, 20 Jan 2015 17:35:20 -0700")),
+ ("Tue, 20 Jan 2015 17:35:20 PST", Ok("Tue, 20 Jan 2015 17:35:20 -0800")),
+ ("Tue, 20 Jan 2015 17:35:20 pst", Ok("Tue, 20 Jan 2015 17:35:20 -0800")),
+ // named single-letter military timezones must fallback to +0000
+ ("Tue, 20 Jan 2015 17:35:20 Z", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
+ ("Tue, 20 Jan 2015 17:35:20 A", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
+ ("Tue, 20 Jan 2015 17:35:20 a", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
+ ("Tue, 20 Jan 2015 17:35:20 K", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
+ ("Tue, 20 Jan 2015 17:35:20 k", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
+ // named single-letter timezone "J" is specifically not valid
+ ("Tue, 20 Jan 2015 17:35:20 J", Err(NOT_ENOUGH)),
];
fn rfc2822_to_datetime(date: &str) -> ParseResult<DateTime<FixedOffset>> {
@@ -975,3 +1032,11 @@ fn test_rfc3339() {
}
}
}
+
+#[cfg(test)]
+#[test]
+fn test_issue_1010() {
+ let dt = crate::NaiveDateTime::parse_from_str("\u{c}SUN\u{e}\u{3000}\0m@J\u{3000}\0\u{3000}\0m\u{c}!\u{c}\u{b}\u{c}\u{c}\u{c}\u{c}%A\u{c}\u{b}\0SU\u{c}\u{c}",
+ "\u{c}\u{c}%A\u{c}\u{b}\0SUN\u{c}\u{c}\u{c}SUNN\u{c}\u{c}\u{c}SUN\u{c}\u{c}!\u{c}\u{b}\u{c}\u{c}\u{c}\u{c}%A\u{c}\u{b}%a");
+ assert_eq!(dt, Err(ParseError(ParseErrorKind::Invalid)));
+}