Limited what `.parse::<Weekday>()` parses to match with scanning.

Amends #113.
This commit is contained in:
Kang Seonghoon 2017-05-02 02:31:02 +09:00
parent 35d1a73ad9
commit c86f5924b0
No known key found for this signature in database
GPG Key ID: 82440FABA6709020
2 changed files with 53 additions and 16 deletions

View File

@ -4,9 +4,10 @@
//! Formatting utilities for date and time. //! Formatting utilities for date and time.
use std::fmt; use std::fmt;
use std::str::FromStr;
use std::error::Error; use std::error::Error;
use {Datelike, Timelike}; use {Datelike, Timelike, Weekday, ParseWeekdayError};
use div::{div_floor, mod_floor}; use div::{div_floor, mod_floor};
use offset::Offset; use offset::Offset;
use offset::fixed::FixedOffset; use offset::fixed::FixedOffset;
@ -557,3 +558,41 @@ impl<'a, I: Iterator<Item=Item<'a>> + Clone> fmt::Display for DelayedFormat<I> {
} }
} }
// this implementation is here only because we need some private code from `scan`
/// Parsing a `str` into a `Weekday` uses the format [`%W`](../../format/strftime/index.html).
///
/// # Example
///
/// ~~~~
/// use chrono::Weekday;
///
/// assert_eq!("Sunday".parse::<Weekday>(), Ok(Weekday::Sun));
/// assert!("any day".parse::<Weekday>().is_err());
/// ~~~~
///
/// The parsing is case-insensitive.
///
/// ~~~~
/// # use chrono::Weekday;
/// assert_eq!("mON".parse::<Weekday>(), Ok(Weekday::Mon));
/// ~~~~
///
/// Only the shortest form (e.g. `sun`) and the longest form (e.g. `sunday`) is accepted.
///
/// ~~~~
/// # use chrono::Weekday;
/// assert!("thurs".parse::<Weekday>().is_err());
/// ~~~~
impl FromStr for Weekday {
type Err = ParseWeekdayError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Ok(("", w)) = scan::short_or_long_weekday(s) {
Ok(w)
} else {
Err(ParseWeekdayError { _dummy: () })
}
}
}

View File

@ -573,25 +573,22 @@ impl num::traits::FromPrimitive for Weekday {
} }
} }
use std::str::FromStr; use std::fmt;
impl FromStr for Weekday { /// An error resulting from reading `Weekday` value with `FromStr`.
type Err = String; #[derive(Clone, PartialEq)]
pub struct ParseWeekdayError {
_dummy: (),
}
fn from_str(s: &str) -> Result<Self, Self::Err> { impl fmt::Debug for ParseWeekdayError {
match s.to_string().to_lowercase().as_ref() { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
"mon" | "monday" => Ok(Weekday::Mon), write!(f, "ParseWeekdayError {{ .. }}")
"tue" | "tuesday" => Ok(Weekday::Tue),
"wed" | "wednesday" => Ok(Weekday::Wed),
"thu" | "thur" | "thursday" => Ok(Weekday::Thu),
"fri" | "friday" => Ok(Weekday::Fri),
"sat" | "saturday" => Ok(Weekday::Sat),
"sun" | "sunday" => Ok(Weekday::Sun),
other => Err(format!("unknown Weekday {}", other)),
}
} }
} }
// the actual `FromStr` implementation is in the `format` module to leverage the existing code
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
mod weekday_serde { mod weekday_serde {
use super::Weekday; use super::Weekday;
@ -665,7 +662,6 @@ mod weekday_serde {
("\"wednesday\"", Wed), ("\"wednesday\"", Wed),
("\"thu\"", Thu), ("\"thu\"", Thu),
("\"thursday\"", Thu), ("\"thursday\"", Thu),
("\"thur\"", Thu),
("\"fri\"", Fri), ("\"fri\"", Fri),
("\"friday\"", Fri), ("\"friday\"", Fri),
("\"sat\"", Sat), ("\"sat\"", Sat),
@ -684,6 +680,8 @@ mod weekday_serde {
"\"monDAYs\"", "\"monDAYs\"",
"\"mond\"", "\"mond\"",
"mon", "mon",
"\"thur\"",
"\"thurs\"",
]; ];
for str in errors { for str in errors {