diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cc0c24..80cd045 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,13 +8,29 @@ Chrono obeys the principle of [Semantic Versioning](http://semver.org/). There were/are numerous minor versions before 1.0 due to the language changes. Versions with only mechanical changes will be omitted from the following list. -## next +## 0.4.10 + +### Improvements + +* `DateTime::parse_from_str` is more than 2x faster in some cases. (@michalsrb + #358) +* Significant improvements to no-std and alloc support (This should also make + many format/serialization operations induce zero unnecessary allocations) + (@CryZe #341) ### Features * Functions that were accepting `Iterator` of `Item`s (for example `format_with_items`) now accept `Iterator` of `Borrow`, so one can - use values or references. + use values or references. (@michalsrb #358) +* Add built-in support for structs with nested `Option` etc fields + (@manifest #302) + +### Internal/doc improvements + +* Use markdown footnotes on the `strftime` docs page (@qudlibetor #359) +* Migrate from `try!` -> `?` (question mark) because it is now emitting + deprecation warnings and has been stable since rustc 1.13.0 ## 0.4.9 diff --git a/Cargo.toml b/Cargo.toml index a572dc9..9c59752 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chrono" -version = "0.4.9" +version = "0.4.10" authors = [ "Kang Seonghoon ", "Brandon W Maister ", diff --git a/src/datetime.rs b/src/datetime.rs index 92cf178..fcfdcd4 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -327,7 +327,7 @@ impl DateTime { pub fn parse_from_rfc2822(s: &str) -> ParseResult> { const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC2822)]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter())); + parse(&mut parsed, s, ITEMS.iter())?; parsed.to_datetime() } @@ -339,7 +339,7 @@ impl DateTime { pub fn parse_from_rfc3339(s: &str) -> ParseResult> { const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC3339)]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter())); + parse(&mut parsed, s, ITEMS.iter())?; parsed.to_datetime() } @@ -365,7 +365,7 @@ impl DateTime { /// ``` pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult> { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); + parse(&mut parsed, s, StrftimeItems::new(fmt))?; parsed.to_datetime() } } @@ -639,7 +639,7 @@ impl str::FromStr for DateTime { ]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter())); + parse(&mut parsed, s, ITEMS.iter())?; parsed.to_datetime() } } @@ -808,7 +808,7 @@ pub mod rustc_serialize { } } - // try!-like function to convert a LocalResult into a serde-ish Result + // lik? function to convert a LocalResult into a serde-ish Result fn from(me: LocalResult, d: &mut D) -> Result where D: Decoder, T: fmt::Display, @@ -943,7 +943,7 @@ pub mod serde { #[derive(Debug)] pub struct MilliSecondsTimestampVisitor; - // try!-like function to convert a LocalResult into a serde-ish Result + // lik? function to convert a LocalResult into a serde-ish Result fn serde_from(me: LocalResult, ts: &V) -> Result where E: de::Error, @@ -1073,7 +1073,7 @@ pub mod serde { pub fn deserialize<'de, D>(d: D) -> Result, D::Error> where D: de::Deserializer<'de> { - Ok(try!(d.deserialize_i64(NanoSecondsTimestampVisitor))) + Ok(d.deserialize_i64(NanoSecondsTimestampVisitor)?) } impl<'de> de::Visitor<'de> for NanoSecondsTimestampVisitor { @@ -1220,7 +1220,7 @@ pub mod serde { pub fn deserialize<'de, D>(d: D) -> Result>, D::Error> where D: de::Deserializer<'de> { - Ok(try!(d.deserialize_option(OptionNanoSecondsTimestampVisitor))) + Ok(d.deserialize_option(OptionNanoSecondsTimestampVisitor)?) } struct OptionNanoSecondsTimestampVisitor; @@ -1364,7 +1364,7 @@ pub mod serde { pub fn deserialize<'de, D>(d: D) -> Result, D::Error> where D: de::Deserializer<'de> { - Ok(try!(d.deserialize_i64(MilliSecondsTimestampVisitor).map(|dt| dt.with_timezone(&Utc)))) + Ok(d.deserialize_i64(MilliSecondsTimestampVisitor).map(|dt| dt.with_timezone(&Utc))?) } impl<'de> de::Visitor<'de> for MilliSecondsTimestampVisitor { @@ -1511,7 +1511,7 @@ pub mod serde { pub fn deserialize<'de, D>(d: D) -> Result>, D::Error> where D: de::Deserializer<'de> { - Ok(try!(d.deserialize_option(OptionMilliSecondsTimestampVisitor).map(|opt| opt.map(|dt| dt.with_timezone(&Utc))))) + Ok(d.deserialize_option(OptionMilliSecondsTimestampVisitor).map(|opt| opt.map(|dt| dt.with_timezone(&Utc)))?) } struct OptionMilliSecondsTimestampVisitor; @@ -1655,7 +1655,7 @@ pub mod serde { pub fn deserialize<'de, D>(d: D) -> Result, D::Error> where D: de::Deserializer<'de> { - Ok(try!(d.deserialize_i64(SecondsTimestampVisitor))) + Ok(d.deserialize_i64(SecondsTimestampVisitor)?) } impl<'de> de::Visitor<'de> for SecondsTimestampVisitor { @@ -1798,7 +1798,7 @@ pub mod serde { pub fn deserialize<'de, D>(d: D) -> Result>, D::Error> where D: de::Deserializer<'de> { - Ok(try!(d.deserialize_option(OptionSecondsTimestampVisitor))) + Ok(d.deserialize_option(OptionSecondsTimestampVisitor)?) } struct OptionSecondsTimestampVisitor; diff --git a/src/format/mod.rs b/src/format/mod.rs index dfd8627..83405d3 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -433,22 +433,20 @@ pub fn format<'a, I, B>( if let Some(v) = v { - try!( - if (spec == &Year || spec == &IsoYear) && !(0 <= v && v < 10_000) { - // non-four-digit years require an explicit sign as per ISO 8601 - match pad { - &Pad::None => write!(result, "{:+}", v), - &Pad::Zero => write!(result, "{:+01$}", v, width + 1), - &Pad::Space => write!(result, "{:+1$}", v, width + 1), - } - } else { - match pad { - &Pad::None => write!(result, "{}", v), - &Pad::Zero => write!(result, "{:01$}", v, width), - &Pad::Space => write!(result, "{:1$}", v, width), - } + if (spec == &Year || spec == &IsoYear) && !(0 <= v && v < 10_000) { + // non-four-digit years require an explicit sign as per ISO 8601 + match pad { + &Pad::None => write!(result, "{:+}", v), + &Pad::Zero => write!(result, "{:+01$}", v, width + 1), + &Pad::Space => write!(result, "{:+1$}", v, width + 1), } - ) + } else { + match pad { + &Pad::None => write!(result, "{}", v), + &Pad::Zero => write!(result, "{:01$}", v, width), + &Pad::Space => write!(result, "{:1$}", v, width), + } + }? } else { return Err(fmt::Error) // insufficient arguments for given format } @@ -575,13 +573,13 @@ pub fn format<'a, I, B>( &RFC2822 => // same to `%a, %e %b %Y %H:%M:%S %z` if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) { let sec = t.second() + t.nanosecond() / 1_000_000_000; - try!(write!( + write!( result, "{}, {:02} {} {:04} {:02}:{:02}:{:02} ", SHORT_WEEKDAYS[d.weekday().num_days_from_monday() as usize], d.day(), SHORT_MONTHS[d.month0() as usize], d.year(), t.hour(), t.minute(), sec - )); + )?; Some(write_local_minus_utc(&mut result, off, false, false)) } else { None @@ -590,7 +588,7 @@ pub fn format<'a, I, B>( if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) { // reuse `Debug` impls which already print ISO 8601 format. // this is faster in this way. - try!(write!(result, "{:?}T{:?}", d, t)); + write!(result, "{:?}T{:?}", d, t)?; Some(write_local_minus_utc(&mut result, off, false, true)) } else { None @@ -598,7 +596,7 @@ pub fn format<'a, I, B>( }; match ret { - Some(ret) => try!(ret), + Some(ret) => ret?, None => return Err(fmt::Error), // insufficient arguments for given format } }, diff --git a/src/format/parse.rs b/src/format/parse.rs index 0a7d6a7..ec34682 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -33,7 +33,7 @@ fn set_weekday_with_number_from_monday(p: &mut Parsed, v: i64) -> ParseResult<() fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a str, ())> { macro_rules! try_consume { - ($e:expr) => ({ let (s_, v) = try!($e); s = s_; v }) + ($e:expr) => ({ let (s_, v) = $e?; s = s_; v }) } // an adapted RFC 2822 syntax from Section 3.3 and 4.3: @@ -90,14 +90,14 @@ fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st if let Ok((s_, weekday)) = scan::short_weekday(s) { if !s_.starts_with(',') { return Err(INVALID); } s = &s_[1..]; - try!(parsed.set_weekday(weekday)); + parsed.set_weekday(weekday)?; } s = s.trim_left(); - try!(parsed.set_day(try_consume!(scan::number(s, 1, 2)))); - s = try!(scan::space(s)); // mandatory - try!(parsed.set_month(1 + i64::from(try_consume!(scan::short_month0(s))))); - s = try!(scan::space(s)); // mandatory + parsed.set_day(try_consume!(scan::number(s, 1, 2)))?; + s = scan::space(s)?; // mandatory + parsed.set_month(1 + i64::from(try_consume!(scan::short_month0(s))))?; + s = scan::space(s)?; // mandatory // distinguish two- and three-digit years from four-digit years let prevlen = s.len(); @@ -109,20 +109,20 @@ fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st (3, _) => { year += 1900; } // 112 -> 2012, 009 -> 1909 (_, _) => {} // 1987 -> 1987, 0654 -> 0654 } - try!(parsed.set_year(year)); + parsed.set_year(year)?; - s = try!(scan::space(s)); // mandatory - try!(parsed.set_hour(try_consume!(scan::number(s, 2, 2)))); - s = try!(scan::char(s.trim_left(), b':')).trim_left(); // *S ":" *S - try!(parsed.set_minute(try_consume!(scan::number(s, 2, 2)))); + s = scan::space(s)?; // mandatory + parsed.set_hour(try_consume!(scan::number(s, 2, 2)))?; + s = scan::char(s.trim_left(), b':')?.trim_left(); // *S ":" *S + parsed.set_minute(try_consume!(scan::number(s, 2, 2)))?; if let Ok(s_) = scan::char(s.trim_left(), b':') { // [ ":" *S 2DIGIT ] - try!(parsed.set_second(try_consume!(scan::number(s_, 2, 2)))); + parsed.set_second(try_consume!(scan::number(s_, 2, 2)))?; } - s = try!(scan::space(s)); // mandatory + s = scan::space(s)?; // mandatory if let Some(offset) = try_consume!(scan::timezone_offset_2822(s)) { // only set the offset when it is definitely known (i.e. not `-0000`) - try!(parsed.set_offset(i64::from(offset))); + parsed.set_offset(i64::from(offset))?; } Ok((s, ())) @@ -130,7 +130,7 @@ fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st fn parse_rfc3339<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a str, ())> { macro_rules! try_consume { - ($e:expr) => ({ let (s_, v) = try!($e); s = s_; v }) + ($e:expr) => ({ let (s_, v) = $e?; s = s_; v }) } // an adapted RFC 3339 syntax from Section 5.6: @@ -160,11 +160,11 @@ fn parse_rfc3339<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st // note that this restriction is unique to RFC 3339 and not ISO 8601. // since this is not a typical Chrono behavior, we check it earlier. - try!(parsed.set_year(try_consume!(scan::number(s, 4, 4)))); - s = try!(scan::char(s, b'-')); - try!(parsed.set_month(try_consume!(scan::number(s, 2, 2)))); - s = try!(scan::char(s, b'-')); - try!(parsed.set_day(try_consume!(scan::number(s, 2, 2)))); + parsed.set_year(try_consume!(scan::number(s, 4, 4)))?; + s = scan::char(s, b'-')?; + parsed.set_month(try_consume!(scan::number(s, 2, 2)))?; + s = scan::char(s, b'-')?; + parsed.set_day(try_consume!(scan::number(s, 2, 2)))?; s = match s.as_bytes().first() { Some(&b't') | Some(&b'T') => &s[1..], @@ -172,19 +172,19 @@ fn parse_rfc3339<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st None => return Err(TOO_SHORT), }; - try!(parsed.set_hour(try_consume!(scan::number(s, 2, 2)))); - s = try!(scan::char(s, b':')); - try!(parsed.set_minute(try_consume!(scan::number(s, 2, 2)))); - s = try!(scan::char(s, b':')); - try!(parsed.set_second(try_consume!(scan::number(s, 2, 2)))); + parsed.set_hour(try_consume!(scan::number(s, 2, 2)))?; + s = scan::char(s, b':')?; + parsed.set_minute(try_consume!(scan::number(s, 2, 2)))?; + s = scan::char(s, b':')?; + parsed.set_second(try_consume!(scan::number(s, 2, 2)))?; if s.starts_with('.') { let nanosecond = try_consume!(scan::nanosecond(&s[1..])); - try!(parsed.set_nanosecond(nanosecond)); + parsed.set_nanosecond(nanosecond)?; } let offset = try_consume!(scan::timezone_offset_zulu(s, |s| scan::char(s, b':'))); if offset <= -86_400 || offset >= 86_400 { return Err(OUT_OF_RANGE); } - try!(parsed.set_offset(i64::from(offset))); + parsed.set_offset(i64::from(offset))?; Ok((s, ())) } @@ -208,7 +208,7 @@ fn parse_rfc3339<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st pub fn parse<'a, I, B>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResult<()> where I: Iterator, B: Borrow> { macro_rules! try_consume { - ($e:expr) => ({ let (s_, v) = try!($e); s = s_; v }) + ($e:expr) => ({ let (s_, v) = $e?; s = s_; v }) } for item in items { @@ -269,7 +269,7 @@ pub fn parse<'a, I, B>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResul let v = if signed { if s.starts_with('-') { let v = try_consume!(scan::number(&s[1..], 1, usize::MAX)); - try!(0i64.checked_sub(v).ok_or(OUT_OF_RANGE)) + 0i64.checked_sub(v).ok_or(OUT_OF_RANGE)? } else if s.starts_with('+') { try_consume!(scan::number(&s[1..], 1, usize::MAX)) } else { @@ -279,7 +279,7 @@ pub fn parse<'a, I, B>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResul } else { try_consume!(scan::number(s, 1, width)) }; - try!(set(parsed, v)); + set(parsed, v)?; } &Item::Fixed(ref spec) => { @@ -288,22 +288,22 @@ pub fn parse<'a, I, B>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResul match spec { &ShortMonthName => { let month0 = try_consume!(scan::short_month0(s)); - try!(parsed.set_month(i64::from(month0) + 1)); + parsed.set_month(i64::from(month0) + 1)?; } &LongMonthName => { let month0 = try_consume!(scan::short_or_long_month0(s)); - try!(parsed.set_month(i64::from(month0) + 1)); + parsed.set_month(i64::from(month0) + 1)?; } &ShortWeekdayName => { let weekday = try_consume!(scan::short_weekday(s)); - try!(parsed.set_weekday(weekday)); + parsed.set_weekday(weekday)?; } &LongWeekdayName => { let weekday = try_consume!(scan::short_or_long_weekday(s)); - try!(parsed.set_weekday(weekday)); + parsed.set_weekday(weekday)?; } &LowerAmPm | &UpperAmPm => { @@ -313,33 +313,33 @@ pub fn parse<'a, I, B>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResul (b'p',b'm') => true, _ => return Err(INVALID) }; - try!(parsed.set_ampm(ampm)); + parsed.set_ampm(ampm)?; s = &s[2..]; } &Nanosecond | &Nanosecond3 | &Nanosecond6 | &Nanosecond9 => { if s.starts_with('.') { let nano = try_consume!(scan::nanosecond(&s[1..])); - try!(parsed.set_nanosecond(nano)); + parsed.set_nanosecond(nano)?; } } &Internal(InternalFixed { val: InternalInternal::Nanosecond3NoDot }) => { if s.len() < 3 { return Err(TOO_SHORT); } let nano = try_consume!(scan::nanosecond_fixed(s, 3)); - try!(parsed.set_nanosecond(nano)); + parsed.set_nanosecond(nano)?; } &Internal(InternalFixed { val: InternalInternal::Nanosecond6NoDot }) => { if s.len() < 6 { return Err(TOO_SHORT); } let nano = try_consume!(scan::nanosecond_fixed(s, 6)); - try!(parsed.set_nanosecond(nano)); + parsed.set_nanosecond(nano)?; } &Internal(InternalFixed { val: InternalInternal::Nanosecond9NoDot }) => { if s.len() < 9 { return Err(TOO_SHORT); } let nano = try_consume!(scan::nanosecond_fixed(s, 9)); - try!(parsed.set_nanosecond(nano)); + parsed.set_nanosecond(nano)?; } &TimezoneName => return Err(BAD_FORMAT), @@ -347,18 +347,18 @@ pub fn parse<'a, I, B>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResul &TimezoneOffsetColon | &TimezoneOffset => { let offset = try_consume!(scan::timezone_offset(s.trim_left(), scan::colon_or_space)); - try!(parsed.set_offset(i64::from(offset))); + parsed.set_offset(i64::from(offset))?; } &TimezoneOffsetColonZ | &TimezoneOffsetZ => { let offset = try_consume!(scan::timezone_offset_zulu(s.trim_left(), scan::colon_or_space)); - try!(parsed.set_offset(i64::from(offset))); + parsed.set_offset(i64::from(offset))?; } &Internal(InternalFixed { val: InternalInternal::TimezoneOffsetPermissive }) => { let offset = try_consume!(scan::timezone_offset_permissive( s.trim_left(), scan::colon_or_space)); - try!(parsed.set_offset(i64::from(offset))); + parsed.set_offset(i64::from(offset))?; } &RFC2822 => try_consume!(parse_rfc2822(parsed, s)), @@ -389,7 +389,7 @@ fn test_parse() { // workaround for Rust issue #22255 fn parse_all(s: &str, items: &[Item]) -> ParseResult { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, items.iter())); + parse(&mut parsed, s, items.iter())?; Ok(parsed) } @@ -700,7 +700,7 @@ fn test_rfc2822() { fn rfc2822_to_datetime(date: &str) -> ParseResult> { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, date, [Item::Fixed(Fixed::RFC2822)].iter())); + parse(&mut parsed, date, [Item::Fixed(Fixed::RFC2822)].iter())?; parsed.to_datetime() } @@ -781,7 +781,7 @@ fn test_rfc3339() { fn rfc3339_to_datetime(date: &str) -> ParseResult> { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, date, [Item::Fixed(Fixed::RFC3339)].iter())); + parse(&mut parsed, date, [Item::Fixed(Fixed::RFC3339)].iter())?; parsed.to_datetime() } diff --git a/src/format/parsed.rs b/src/format/parsed.rs index a09dd19..c1b02ff 100644 --- a/src/format/parsed.rs +++ b/src/format/parsed.rs @@ -144,65 +144,65 @@ impl Parsed { /// Tries to set the [`year`](#structfield.year) field from given value. #[inline] pub fn set_year(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.year, try!(value.to_i32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.year, value.to_i32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`year_div_100`](#structfield.year_div_100) field from given value. #[inline] pub fn set_year_div_100(&mut self, value: i64) -> ParseResult<()> { if value < 0 { return Err(OUT_OF_RANGE); } - set_if_consistent(&mut self.year_div_100, try!(value.to_i32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.year_div_100, value.to_i32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`year_mod_100`](#structfield.year_mod_100) field from given value. #[inline] pub fn set_year_mod_100(&mut self, value: i64) -> ParseResult<()> { if value < 0 { return Err(OUT_OF_RANGE); } - set_if_consistent(&mut self.year_mod_100, try!(value.to_i32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.year_mod_100, value.to_i32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`isoyear`](#structfield.isoyear) field from given value. #[inline] pub fn set_isoyear(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.isoyear, try!(value.to_i32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.isoyear, value.to_i32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`isoyear_div_100`](#structfield.isoyear_div_100) field from given value. #[inline] pub fn set_isoyear_div_100(&mut self, value: i64) -> ParseResult<()> { if value < 0 { return Err(OUT_OF_RANGE); } - set_if_consistent(&mut self.isoyear_div_100, try!(value.to_i32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.isoyear_div_100, value.to_i32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`isoyear_mod_100`](#structfield.isoyear_mod_100) field from given value. #[inline] pub fn set_isoyear_mod_100(&mut self, value: i64) -> ParseResult<()> { if value < 0 { return Err(OUT_OF_RANGE); } - set_if_consistent(&mut self.isoyear_mod_100, try!(value.to_i32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.isoyear_mod_100, value.to_i32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`month`](#structfield.month) field from given value. #[inline] pub fn set_month(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.month, try!(value.to_u32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.month, value.to_u32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`week_from_sun`](#structfield.week_from_sun) field from given value. #[inline] pub fn set_week_from_sun(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.week_from_sun, try!(value.to_u32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.week_from_sun, value.to_u32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`week_from_mon`](#structfield.week_from_mon) field from given value. #[inline] pub fn set_week_from_mon(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.week_from_mon, try!(value.to_u32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.week_from_mon, value.to_u32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`isoweek`](#structfield.isoweek) field from given value. #[inline] pub fn set_isoweek(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.isoweek, try!(value.to_u32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.isoweek, value.to_u32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`weekday`](#structfield.weekday) field from given value. @@ -214,13 +214,13 @@ impl Parsed { /// Tries to set the [`ordinal`](#structfield.ordinal) field from given value. #[inline] pub fn set_ordinal(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.ordinal, try!(value.to_u32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.ordinal, value.to_u32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`day`](#structfield.day) field from given value. #[inline] pub fn set_day(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.day, try!(value.to_u32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.day, value.to_u32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`hour_div_12`](#structfield.hour_div_12) field from given value. @@ -242,28 +242,28 @@ impl Parsed { /// [`hour_mod_12`](#structfield.hour_mod_12) fields from given value. #[inline] pub fn set_hour(&mut self, value: i64) -> ParseResult<()> { - let v = try!(value.to_u32().ok_or(OUT_OF_RANGE)); - try!(set_if_consistent(&mut self.hour_div_12, v / 12)); - try!(set_if_consistent(&mut self.hour_mod_12, v % 12)); + let v = value.to_u32().ok_or(OUT_OF_RANGE)?; + set_if_consistent(&mut self.hour_div_12, v / 12)?; + set_if_consistent(&mut self.hour_mod_12, v % 12)?; Ok(()) } /// Tries to set the [`minute`](#structfield.minute) field from given value. #[inline] pub fn set_minute(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.minute, try!(value.to_u32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.minute, value.to_u32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`second`](#structfield.second) field from given value. #[inline] pub fn set_second(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.second, try!(value.to_u32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.second, value.to_u32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`nanosecond`](#structfield.nanosecond) field from given value. #[inline] pub fn set_nanosecond(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.nanosecond, try!(value.to_u32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.nanosecond, value.to_u32().ok_or(OUT_OF_RANGE)?) } /// Tries to set the [`timestamp`](#structfield.timestamp) field from given value. @@ -275,7 +275,7 @@ impl Parsed { /// Tries to set the [`offset`](#structfield.offset) field from given value. #[inline] pub fn set_offset(&mut self, value: i64) -> ParseResult<()> { - set_if_consistent(&mut self.offset, try!(value.to_i32().ok_or(OUT_OF_RANGE))) + set_if_consistent(&mut self.offset, value.to_i32().ok_or(OUT_OF_RANGE)?) } /// Returns a parsed naive date out of given fields. @@ -316,7 +316,7 @@ impl Parsed { (None, Some(q), Some(r @ 0...99)) => { if q < 0 { return Err(OUT_OF_RANGE); } let y = q.checked_mul(100).and_then(|v| v.checked_add(r)); - Ok(Some(try!(y.ok_or(OUT_OF_RANGE)))) + Ok(Some(y.ok_or(OUT_OF_RANGE)?)) }, // we only have modulo. try to interpret a modulo as a conventional two-digit year. @@ -330,9 +330,9 @@ impl Parsed { } let given_year = - try!(resolve_year(self.year, self.year_div_100, self.year_mod_100)); + resolve_year(self.year, self.year_div_100, self.year_mod_100)?; let given_isoyear = - try!(resolve_year(self.isoyear, self.isoyear_div_100, self.isoyear_mod_100)); + resolve_year(self.isoyear, self.isoyear_div_100, self.isoyear_mod_100)?; // verify the normal year-month-day date. let verify_ymd = |date: NaiveDate| { @@ -388,20 +388,20 @@ impl Parsed { let (verified, parsed_date) = match (given_year, given_isoyear, self) { (Some(year), _, &Parsed { month: Some(month), day: Some(day), .. }) => { // year, month, day - let date = try!(NaiveDate::from_ymd_opt(year, month, day).ok_or(OUT_OF_RANGE)); + let date = NaiveDate::from_ymd_opt(year, month, day).ok_or(OUT_OF_RANGE)?; (verify_isoweekdate(date) && verify_ordinal(date), date) }, (Some(year), _, &Parsed { ordinal: Some(ordinal), .. }) => { // year, day of the year - let date = try!(NaiveDate::from_yo_opt(year, ordinal).ok_or(OUT_OF_RANGE)); + let date = NaiveDate::from_yo_opt(year, ordinal).ok_or(OUT_OF_RANGE)?; (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date) }, (Some(year), _, &Parsed { week_from_sun: Some(week_from_sun), weekday: Some(weekday), .. }) => { // year, week (starting at 1st Sunday), day of the week - let newyear = try!(NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)); + let newyear = NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)?; let firstweek = match newyear.weekday() { Weekday::Sun => 0, Weekday::Mon => 6, @@ -416,8 +416,8 @@ impl Parsed { if week_from_sun > 53 { return Err(OUT_OF_RANGE); } // can it overflow? let ndays = firstweek + (week_from_sun as i32 - 1) * 7 + weekday.num_days_from_sunday() as i32; - let date = try!(newyear.checked_add_signed(OldDuration::days(i64::from(ndays))) - .ok_or(OUT_OF_RANGE)); + let date = newyear.checked_add_signed(OldDuration::days(i64::from(ndays))) + .ok_or(OUT_OF_RANGE)?; if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date) @@ -426,7 +426,7 @@ impl Parsed { (Some(year), _, &Parsed { week_from_mon: Some(week_from_mon), weekday: Some(weekday), .. }) => { // year, week (starting at 1st Monday), day of the week - let newyear = try!(NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)); + let newyear = NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)?; let firstweek = match newyear.weekday() { Weekday::Sun => 1, Weekday::Mon => 0, @@ -441,8 +441,8 @@ impl Parsed { if week_from_mon > 53 { return Err(OUT_OF_RANGE); } // can it overflow? let ndays = firstweek + (week_from_mon as i32 - 1) * 7 + weekday.num_days_from_monday() as i32; - let date = try!(newyear.checked_add_signed(OldDuration::days(i64::from(ndays))) - .ok_or(OUT_OF_RANGE)); + let date = newyear.checked_add_signed(OldDuration::days(i64::from(ndays))) + .ok_or(OUT_OF_RANGE)?; if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date) @@ -451,7 +451,7 @@ impl Parsed { (_, Some(isoyear), &Parsed { isoweek: Some(isoweek), weekday: Some(weekday), .. }) => { // ISO year, week, day of the week let date = NaiveDate::from_isoywd_opt(isoyear, isoweek, weekday); - let date = try!(date.ok_or(OUT_OF_RANGE)); + let date = date.ok_or(OUT_OF_RANGE)?; (verify_ymd(date) && verify_ordinal(date), date) }, @@ -547,9 +547,9 @@ impl Parsed { } // reconstruct date and time fields from timestamp - let ts = try!(timestamp.checked_add(i64::from(offset)).ok_or(OUT_OF_RANGE)); + let ts = timestamp.checked_add(i64::from(offset)).ok_or(OUT_OF_RANGE)?; let datetime = NaiveDateTime::from_timestamp_opt(ts, 0); - let mut datetime = try!(datetime.ok_or(OUT_OF_RANGE)); + let mut datetime = datetime.ok_or(OUT_OF_RANGE)?; // fill year, ordinal, hour, minute and second fields from timestamp. // if existing fields are consistent, this will allow the full date/time reconstruction. @@ -566,21 +566,21 @@ impl Parsed { } // ...and we have the correct candidates for other fields. } else { - try!(parsed.set_second(i64::from(datetime.second()))); + parsed.set_second(i64::from(datetime.second()))?; } - try!(parsed.set_year (i64::from(datetime.year()))); - try!(parsed.set_ordinal(i64::from(datetime.ordinal()))); // more efficient than ymd - try!(parsed.set_hour (i64::from(datetime.hour()))); - try!(parsed.set_minute (i64::from(datetime.minute()))); + parsed.set_year (i64::from(datetime.year()))?; + parsed.set_ordinal(i64::from(datetime.ordinal()))?; // more efficient than ymd + parsed.set_hour (i64::from(datetime.hour()))?; + parsed.set_minute (i64::from(datetime.minute()))?; // validate other fields (e.g. week) and return - let date = try!(parsed.to_naive_date()); - let time = try!(parsed.to_naive_time()); + let date = parsed.to_naive_date()?; + let time = parsed.to_naive_time()?; Ok(date.and_time(time)) } else { // reproduce the previous error(s) - try!(date); - try!(time); + date?; + time?; unreachable!() } } @@ -597,9 +597,9 @@ impl Parsed { /// plus a time zone offset. /// Either way those fields have to be consistent to each other. pub fn to_datetime(&self) -> ParseResult> { - let offset = try!(self.offset.ok_or(NOT_ENOUGH)); - let datetime = try!(self.to_naive_datetime_with_offset(offset)); - let offset = try!(FixedOffset::east_opt(offset).ok_or(OUT_OF_RANGE)); + let offset = self.offset.ok_or(NOT_ENOUGH)?; + let datetime = self.to_naive_datetime_with_offset(offset)?; + let offset = FixedOffset::east_opt(offset).ok_or(OUT_OF_RANGE)?; match offset.from_local_datetime(&datetime) { LocalResult::None => Err(IMPOSSIBLE), LocalResult::Single(t) => Ok(t), @@ -624,7 +624,7 @@ impl Parsed { // an empty `nanosecond` is always equal to zero, so missing nanosecond is fine. let nanosecond = self.nanosecond.unwrap_or(0); let dt = NaiveDateTime::from_timestamp_opt(timestamp, nanosecond); - let dt = try!(dt.ok_or(OUT_OF_RANGE)); + let dt = dt.ok_or(OUT_OF_RANGE)?; guessed_offset = tz.offset_from_utc_datetime(&dt).fix().local_minus_utc(); } @@ -639,7 +639,7 @@ impl Parsed { // `guessed_offset` should be correct when `self.timestamp` is given. // it will be 0 otherwise, but this is fine as the algorithm ignores offset for that case. - let datetime = try!(self.to_naive_datetime_with_offset(guessed_offset)); + let datetime = self.to_naive_datetime_with_offset(guessed_offset)?; match tz.from_local_datetime(&datetime) { LocalResult::None => Err(IMPOSSIBLE), LocalResult::Single(t) => if check_offset(&t) {Ok(t)} else {Err(IMPOSSIBLE)}, diff --git a/src/format/scan.rs b/src/format/scan.rs index e776fee..7235d67 100644 --- a/src/format/scan.rs +++ b/src/format/scan.rs @@ -66,13 +66,13 @@ pub fn number(s: &str, min: usize, max: usize) -> ParseResult<(&str, i64)> { pub fn nanosecond(s: &str) -> ParseResult<(&str, i64)> { // record the number of digits consumed for later scaling. let origlen = s.len(); - let (s, v) = try!(number(s, 1, 9)); + let (s, v) = number(s, 1, 9)?; let consumed = origlen - s.len(); // scale the number accordingly. static SCALE: [i64; 10] = [0, 100_000_000, 10_000_000, 1_000_000, 100_000, 10_000, 1_000, 100, 10, 1]; - let v = try!(v.checked_mul(SCALE[consumed]).ok_or(OUT_OF_RANGE)); + let v = v.checked_mul(SCALE[consumed]).ok_or(OUT_OF_RANGE)?; // if there are more than 9 digits, skip next digits. let s = s.trim_left_matches(|c: char| '0' <= c && c <= '9'); @@ -84,12 +84,12 @@ pub fn nanosecond(s: &str) -> ParseResult<(&str, i64)> { /// Returns the number of whole nanoseconds (0--999,999,999). pub fn nanosecond_fixed(s: &str, digits: usize) -> ParseResult<(&str, i64)> { // record the number of digits consumed for later scaling. - let (s, v) = try!(number(s, digits, digits)); + let (s, v) = number(s, digits, digits)?; // scale the number accordingly. static SCALE: [i64; 10] = [0, 100_000_000, 10_000_000, 1_000_000, 100_000, 10_000, 1_000, 100, 10, 1]; - let v = try!(v.checked_mul(SCALE[digits]).ok_or(OUT_OF_RANGE)); + let v = v.checked_mul(SCALE[digits]).ok_or(OUT_OF_RANGE)?; Ok((s, v)) } @@ -140,7 +140,7 @@ pub fn short_or_long_month0(s: &str) -> ParseResult<(&str, u8)> { static LONG_MONTH_SUFFIXES: [&'static str; 12] = ["uary", "ruary", "ch", "il", "", "e", "y", "ust", "tember", "ober", "ember", "ember"]; - let (mut s, month0) = try!(short_month0(s)); + let (mut s, month0) = short_month0(s)?; // tries to consume the suffix if possible let suffix = LONG_MONTH_SUFFIXES[month0 as usize]; @@ -158,7 +158,7 @@ pub fn short_or_long_weekday(s: &str) -> ParseResult<(&str, Weekday)> { static LONG_WEEKDAY_SUFFIXES: [&'static str; 7] = ["day", "sday", "nesday", "rsday", "day", "urday", "day"]; - let (mut s, weekday) = try!(short_weekday(s)); + let (mut s, weekday) = short_weekday(s)?; // tries to consume the suffix if possible let suffix = LONG_WEEKDAY_SUFFIXES[weekday.num_days_from_monday() as usize]; @@ -225,14 +225,14 @@ fn timezone_offset_internal(mut s: &str, mut consume_colon: F, allow_missing_ s = &s[1..]; // hours (00--99) - let hours = match try!(digits(s)) { + let hours = match digits(s)? { (h1 @ b'0'...b'9', h2 @ b'0'...b'9') => i32::from((h1 - b'0') * 10 + (h2 - b'0')), _ => return Err(INVALID), }; s = &s[2..]; // colons (and possibly other separators) - s = try!(consume_colon(s)); + s = consume_colon(s)?; // minutes (00--59) // if the next two items are digits then we have to add minutes @@ -307,7 +307,7 @@ pub fn timezone_offset_2822(s: &str) -> ParseResult<(&str, Option)> { Ok((s, None)) // recommended by RFC 2822: consume but treat it as -0000 } } else { - let (s_, offset) = try!(timezone_offset(s, |s| Ok(s))); + let (s_, offset) = timezone_offset(s, |s| Ok(s))?; if offset == 0 && s.starts_with('-') { // -0000 is not same to +0000 Ok((s_, None)) } else { diff --git a/src/lib.rs b/src/lib.rs index bcd43b8..bf3c151 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -386,7 +386,6 @@ #![cfg_attr(feature = "bench", feature(test))] // lib stability features as per RFC #507 #![deny(missing_docs)] #![deny(missing_debug_implementations)] -#![allow(deprecated)] #![cfg_attr(not(any(feature = "std", test)), no_std)] diff --git a/src/naive/date.rs b/src/naive/date.rs index f0e63e2..8470c5a 100644 --- a/src/naive/date.rs +++ b/src/naive/date.rs @@ -455,7 +455,7 @@ impl NaiveDate { /// ~~~~ pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); + parse(&mut parsed, s, StrftimeItems::new(fmt))?; parsed.to_naive_date() } @@ -1518,7 +1518,7 @@ impl str::FromStr for NaiveDate { ]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter())); + parse(&mut parsed, s, ITEMS.iter())?; parsed.to_naive_date() } } diff --git a/src/naive/datetime.rs b/src/naive/datetime.rs index 50ba8b0..b9f5477 100644 --- a/src/naive/datetime.rs +++ b/src/naive/datetime.rs @@ -210,7 +210,7 @@ impl NaiveDateTime { /// ~~~~ pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); + parse(&mut parsed, s, StrftimeItems::new(fmt))?; parsed.to_naive_datetime_with_offset(0) // no offset adjustment } @@ -1489,7 +1489,7 @@ impl str::FromStr for NaiveDateTime { ]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter())); + parse(&mut parsed, s, ITEMS.iter())?; parsed.to_naive_datetime_with_offset(0) } } @@ -1834,7 +1834,7 @@ pub mod serde { pub fn deserialize<'de, D>(d: D) -> Result where D: de::Deserializer<'de> { - Ok(try!(d.deserialize_i64(NaiveDateTimeFromNanoSecondsVisitor))) + Ok(d.deserialize_i64(NaiveDateTimeFromNanoSecondsVisitor)?) } struct NaiveDateTimeFromNanoSecondsVisitor; @@ -1979,7 +1979,7 @@ pub mod serde { pub fn deserialize<'de, D>(d: D) -> Result where D: de::Deserializer<'de> { - Ok(try!(d.deserialize_i64(NaiveDateTimeFromMilliSecondsVisitor))) + Ok(d.deserialize_i64(NaiveDateTimeFromMilliSecondsVisitor)?) } struct NaiveDateTimeFromMilliSecondsVisitor; @@ -2124,7 +2124,7 @@ pub mod serde { pub fn deserialize<'de, D>(d: D) -> Result where D: de::Deserializer<'de> { - Ok(try!(d.deserialize_i64(NaiveDateTimeFromSecondsVisitor))) + Ok(d.deserialize_i64(NaiveDateTimeFromSecondsVisitor)?) } struct NaiveDateTimeFromSecondsVisitor; diff --git a/src/naive/time.rs b/src/naive/time.rs index 4ce520c..7b59a5d 100644 --- a/src/naive/time.rs +++ b/src/naive/time.rs @@ -496,7 +496,7 @@ impl NaiveTime { /// ~~~~ pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); + parse(&mut parsed, s, StrftimeItems::new(fmt))?; parsed.to_naive_time() } @@ -1236,7 +1236,7 @@ impl fmt::Debug for NaiveTime { (sec, self.frac) }; - try!(write!(f, "{:02}:{:02}:{:02}", hour, min, sec)); + write!(f, "{:02}:{:02}:{:02}", hour, min, sec)?; if nano == 0 { Ok(()) } else if nano % 1_000_000 == 0 { @@ -1314,7 +1314,7 @@ impl str::FromStr for NaiveTime { ]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter())); + parse(&mut parsed, s, ITEMS.iter())?; parsed.to_naive_time() } } diff --git a/src/offset/mod.rs b/src/offset/mod.rs index a255292..0fe3ebd 100644 --- a/src/offset/mod.rs +++ b/src/offset/mod.rs @@ -415,7 +415,7 @@ pub trait TimeZone: Sized + Clone { /// with parsed `FixedOffset`. fn datetime_from_str(&self, s: &str, fmt: &str) -> ParseResult> { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); + parse(&mut parsed, s, StrftimeItems::new(fmt))?; parsed.to_datetime_with_timezone(self) } diff --git a/src/oldtime.rs b/src/oldtime.rs index d523b54..bed8136 100644 --- a/src/oldtime.rs +++ b/src/oldtime.rs @@ -364,20 +364,20 @@ impl fmt::Display for Duration { let hasdate = days != 0; let hastime = (secs != 0 || abs.nanos != 0) || !hasdate; - try!(write!(f, "{}P", sign)); + write!(f, "{}P", sign)?; if hasdate { - try!(write!(f, "{}D", days)); + write!(f, "{}D", days)?; } if hastime { if abs.nanos == 0 { - try!(write!(f, "T{}S", secs)); + write!(f, "T{}S", secs)?; } else if abs.nanos % NANOS_PER_MILLI == 0 { - try!(write!(f, "T{}.{:03}S", secs, abs.nanos / NANOS_PER_MILLI)); + write!(f, "T{}.{:03}S", secs, abs.nanos / NANOS_PER_MILLI)?; } else if abs.nanos % NANOS_PER_MICRO == 0 { - try!(write!(f, "T{}.{:06}S", secs, abs.nanos / NANOS_PER_MICRO)); + write!(f, "T{}.{:06}S", secs, abs.nanos / NANOS_PER_MICRO)?; } else { - try!(write!(f, "T{}.{:09}S", secs, abs.nanos)); + write!(f, "T{}.{:09}S", secs, abs.nanos)?; } } Ok(())