diff --git a/src/format/mod.rs b/src/format/mod.rs index efd6f76..f120014 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -4,9 +4,10 @@ //! Formatting utilities for date and time. use std::fmt; +use std::str::FromStr; use std::error::Error; -use {Datelike, Timelike}; +use {Datelike, Timelike, Weekday, ParseWeekdayError}; use div::{div_floor, mod_floor}; use offset::Offset; use offset::fixed::FixedOffset; @@ -557,3 +558,41 @@ impl<'a, I: Iterator> + Clone> fmt::Display for DelayedFormat { } } +// 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::(), Ok(Weekday::Sun)); +/// assert!("any day".parse::().is_err()); +/// ~~~~ +/// +/// The parsing is case-insensitive. +/// +/// ~~~~ +/// # use chrono::Weekday; +/// assert_eq!("mON".parse::(), 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::().is_err()); +/// ~~~~ +impl FromStr for Weekday { + type Err = ParseWeekdayError; + + fn from_str(s: &str) -> Result { + if let Ok(("", w)) = scan::short_or_long_weekday(s) { + Ok(w) + } else { + Err(ParseWeekdayError { _dummy: () }) + } + } +} + diff --git a/src/lib.rs b/src/lib.rs index 685cbf1..a6af13b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -573,25 +573,22 @@ impl num::traits::FromPrimitive for Weekday { } } -use std::str::FromStr; +use std::fmt; -impl FromStr for Weekday { - type Err = String; +/// An error resulting from reading `Weekday` value with `FromStr`. +#[derive(Clone, PartialEq)] +pub struct ParseWeekdayError { + _dummy: (), +} - fn from_str(s: &str) -> Result { - match s.to_string().to_lowercase().as_ref() { - "mon" | "monday" => Ok(Weekday::Mon), - "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)), - } +impl fmt::Debug for ParseWeekdayError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "ParseWeekdayError {{ .. }}") } } +// the actual `FromStr` implementation is in the `format` module to leverage the existing code + #[cfg(feature = "serde")] mod weekday_serde { use super::Weekday; @@ -665,7 +662,6 @@ mod weekday_serde { ("\"wednesday\"", Wed), ("\"thu\"", Thu), ("\"thursday\"", Thu), - ("\"thur\"", Thu), ("\"fri\"", Fri), ("\"friday\"", Fri), ("\"sat\"", Sat), @@ -684,6 +680,8 @@ mod weekday_serde { "\"monDAYs\"", "\"mond\"", "mon", + "\"thur\"", + "\"thurs\"", ]; for str in errors {