Replace all uses of `try!` with question mark

The `?` operator was stabilized in 1.13, this gets rid of a few hundred
deprecation warnings.

Fixes #357
This commit is contained in:
Brandon W Maister 2019-11-23 19:06:27 -05:00
parent 46f8267c61
commit 6622bdcae7
11 changed files with 147 additions and 150 deletions

View File

@ -327,7 +327,7 @@ impl DateTime<FixedOffset> {
pub fn parse_from_rfc2822(s: &str) -> ParseResult<DateTime<FixedOffset>> { pub fn parse_from_rfc2822(s: &str) -> ParseResult<DateTime<FixedOffset>> {
const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC2822)]; const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC2822)];
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, ITEMS.iter())); parse(&mut parsed, s, ITEMS.iter())?;
parsed.to_datetime() parsed.to_datetime()
} }
@ -339,7 +339,7 @@ impl DateTime<FixedOffset> {
pub fn parse_from_rfc3339(s: &str) -> ParseResult<DateTime<FixedOffset>> { pub fn parse_from_rfc3339(s: &str) -> ParseResult<DateTime<FixedOffset>> {
const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC3339)]; const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC3339)];
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, ITEMS.iter())); parse(&mut parsed, s, ITEMS.iter())?;
parsed.to_datetime() parsed.to_datetime()
} }
@ -365,7 +365,7 @@ impl DateTime<FixedOffset> {
/// ``` /// ```
pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<DateTime<FixedOffset>> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<DateTime<FixedOffset>> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); parse(&mut parsed, s, StrftimeItems::new(fmt))?;
parsed.to_datetime() parsed.to_datetime()
} }
} }
@ -639,7 +639,7 @@ impl str::FromStr for DateTime<FixedOffset> {
]; ];
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, ITEMS.iter())); parse(&mut parsed, s, ITEMS.iter())?;
parsed.to_datetime() 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<T, D>(me: LocalResult<T>, d: &mut D) -> Result<T, D::Error> fn from<T, D>(me: LocalResult<T>, d: &mut D) -> Result<T, D::Error>
where D: Decoder, where D: Decoder,
T: fmt::Display, T: fmt::Display,
@ -943,7 +943,7 @@ pub mod serde {
#[derive(Debug)] #[derive(Debug)]
pub struct MilliSecondsTimestampVisitor; 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<T, E, V>(me: LocalResult<T>, ts: &V) -> Result<T, E> fn serde_from<T, E, V>(me: LocalResult<T>, ts: &V) -> Result<T, E>
where where
E: de::Error, E: de::Error,
@ -1073,7 +1073,7 @@ pub mod serde {
pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error>
where D: de::Deserializer<'de> where D: de::Deserializer<'de>
{ {
Ok(try!(d.deserialize_i64(NanoSecondsTimestampVisitor))) Ok(d.deserialize_i64(NanoSecondsTimestampVisitor)?)
} }
impl<'de> de::Visitor<'de> for NanoSecondsTimestampVisitor { impl<'de> de::Visitor<'de> for NanoSecondsTimestampVisitor {
@ -1220,7 +1220,7 @@ pub mod serde {
pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error>
where D: de::Deserializer<'de> where D: de::Deserializer<'de>
{ {
Ok(try!(d.deserialize_option(OptionNanoSecondsTimestampVisitor))) Ok(d.deserialize_option(OptionNanoSecondsTimestampVisitor)?)
} }
struct OptionNanoSecondsTimestampVisitor; struct OptionNanoSecondsTimestampVisitor;
@ -1364,7 +1364,7 @@ pub mod serde {
pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error>
where D: de::Deserializer<'de> 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 { impl<'de> de::Visitor<'de> for MilliSecondsTimestampVisitor {
@ -1511,7 +1511,7 @@ pub mod serde {
pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error>
where D: de::Deserializer<'de> 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; struct OptionMilliSecondsTimestampVisitor;
@ -1655,7 +1655,7 @@ pub mod serde {
pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error>
where D: de::Deserializer<'de> where D: de::Deserializer<'de>
{ {
Ok(try!(d.deserialize_i64(SecondsTimestampVisitor))) Ok(d.deserialize_i64(SecondsTimestampVisitor)?)
} }
impl<'de> de::Visitor<'de> for SecondsTimestampVisitor { impl<'de> de::Visitor<'de> for SecondsTimestampVisitor {
@ -1798,7 +1798,7 @@ pub mod serde {
pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error>
where D: de::Deserializer<'de> where D: de::Deserializer<'de>
{ {
Ok(try!(d.deserialize_option(OptionSecondsTimestampVisitor))) Ok(d.deserialize_option(OptionSecondsTimestampVisitor)?)
} }
struct OptionSecondsTimestampVisitor; struct OptionSecondsTimestampVisitor;

View File

@ -433,22 +433,20 @@ pub fn format<'a, I, B>(
if let Some(v) = v { if let Some(v) = v {
try!( if (spec == &Year || spec == &IsoYear) && !(0 <= v && v < 10_000) {
if (spec == &Year || spec == &IsoYear) && !(0 <= v && v < 10_000) { // non-four-digit years require an explicit sign as per ISO 8601
// non-four-digit years require an explicit sign as per ISO 8601 match pad {
match pad { &Pad::None => write!(result, "{:+}", v),
&Pad::None => write!(result, "{:+}", v), &Pad::Zero => write!(result, "{:+01$}", v, width + 1),
&Pad::Zero => write!(result, "{:+01$}", v, width + 1), &Pad::Space => write!(result, "{:+1$}", 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 {
match pad {
&Pad::None => write!(result, "{}", v),
&Pad::Zero => write!(result, "{:01$}", v, width),
&Pad::Space => write!(result, "{:1$}", v, width),
}
}?
} else { } else {
return Err(fmt::Error) // insufficient arguments for given format 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` &RFC2822 => // same to `%a, %e %b %Y %H:%M:%S %z`
if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) { if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) {
let sec = t.second() + t.nanosecond() / 1_000_000_000; let sec = t.second() + t.nanosecond() / 1_000_000_000;
try!(write!( write!(
result, result,
"{}, {:02} {} {:04} {:02}:{:02}:{:02} ", "{}, {:02} {} {:04} {:02}:{:02}:{:02} ",
SHORT_WEEKDAYS[d.weekday().num_days_from_monday() as usize], SHORT_WEEKDAYS[d.weekday().num_days_from_monday() as usize],
d.day(), SHORT_MONTHS[d.month0() as usize], d.year(), d.day(), SHORT_MONTHS[d.month0() as usize], d.year(),
t.hour(), t.minute(), sec t.hour(), t.minute(), sec
)); )?;
Some(write_local_minus_utc(&mut result, off, false, false)) Some(write_local_minus_utc(&mut result, off, false, false))
} else { } else {
None None
@ -590,7 +588,7 @@ pub fn format<'a, I, B>(
if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) { if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) {
// reuse `Debug` impls which already print ISO 8601 format. // reuse `Debug` impls which already print ISO 8601 format.
// this is faster in this way. // 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)) Some(write_local_minus_utc(&mut result, off, false, true))
} else { } else {
None None
@ -598,7 +596,7 @@ pub fn format<'a, I, B>(
}; };
match ret { match ret {
Some(ret) => try!(ret), Some(ret) => ret?,
None => return Err(fmt::Error), // insufficient arguments for given format None => return Err(fmt::Error), // insufficient arguments for given format
} }
}, },

View File

@ -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, ())> { fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a str, ())> {
macro_rules! try_consume { 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: // 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 let Ok((s_, weekday)) = scan::short_weekday(s) {
if !s_.starts_with(',') { return Err(INVALID); } if !s_.starts_with(',') { return Err(INVALID); }
s = &s_[1..]; s = &s_[1..];
try!(parsed.set_weekday(weekday)); parsed.set_weekday(weekday)?;
} }
s = s.trim_left(); s = s.trim_left();
try!(parsed.set_day(try_consume!(scan::number(s, 1, 2)))); parsed.set_day(try_consume!(scan::number(s, 1, 2)))?;
s = try!(scan::space(s)); // mandatory s = scan::space(s)?; // mandatory
try!(parsed.set_month(1 + i64::from(try_consume!(scan::short_month0(s))))); parsed.set_month(1 + i64::from(try_consume!(scan::short_month0(s))))?;
s = try!(scan::space(s)); // mandatory s = scan::space(s)?; // mandatory
// distinguish two- and three-digit years from four-digit years // distinguish two- and three-digit years from four-digit years
let prevlen = s.len(); 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 (3, _) => { year += 1900; } // 112 -> 2012, 009 -> 1909
(_, _) => {} // 1987 -> 1987, 0654 -> 0654 (_, _) => {} // 1987 -> 1987, 0654 -> 0654
} }
try!(parsed.set_year(year)); parsed.set_year(year)?;
s = try!(scan::space(s)); // mandatory s = scan::space(s)?; // mandatory
try!(parsed.set_hour(try_consume!(scan::number(s, 2, 2)))); parsed.set_hour(try_consume!(scan::number(s, 2, 2)))?;
s = try!(scan::char(s.trim_left(), b':')).trim_left(); // *S ":" *S s = scan::char(s.trim_left(), b':')?.trim_left(); // *S ":" *S
try!(parsed.set_minute(try_consume!(scan::number(s, 2, 2)))); parsed.set_minute(try_consume!(scan::number(s, 2, 2)))?;
if let Ok(s_) = scan::char(s.trim_left(), b':') { // [ ":" *S 2DIGIT ] 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)) { if let Some(offset) = try_consume!(scan::timezone_offset_2822(s)) {
// only set the offset when it is definitely known (i.e. not `-0000`) // 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, ())) 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, ())> { fn parse_rfc3339<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a str, ())> {
macro_rules! try_consume { 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: // 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. // 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. // since this is not a typical Chrono behavior, we check it earlier.
try!(parsed.set_year(try_consume!(scan::number(s, 4, 4)))); parsed.set_year(try_consume!(scan::number(s, 4, 4)))?;
s = try!(scan::char(s, b'-')); s = scan::char(s, b'-')?;
try!(parsed.set_month(try_consume!(scan::number(s, 2, 2)))); parsed.set_month(try_consume!(scan::number(s, 2, 2)))?;
s = try!(scan::char(s, b'-')); s = scan::char(s, b'-')?;
try!(parsed.set_day(try_consume!(scan::number(s, 2, 2)))); parsed.set_day(try_consume!(scan::number(s, 2, 2)))?;
s = match s.as_bytes().first() { s = match s.as_bytes().first() {
Some(&b't') | Some(&b'T') => &s[1..], 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), None => return Err(TOO_SHORT),
}; };
try!(parsed.set_hour(try_consume!(scan::number(s, 2, 2)))); parsed.set_hour(try_consume!(scan::number(s, 2, 2)))?;
s = try!(scan::char(s, b':')); s = scan::char(s, b':')?;
try!(parsed.set_minute(try_consume!(scan::number(s, 2, 2)))); parsed.set_minute(try_consume!(scan::number(s, 2, 2)))?;
s = try!(scan::char(s, b':')); s = scan::char(s, b':')?;
try!(parsed.set_second(try_consume!(scan::number(s, 2, 2)))); parsed.set_second(try_consume!(scan::number(s, 2, 2)))?;
if s.starts_with('.') { if s.starts_with('.') {
let nanosecond = try_consume!(scan::nanosecond(&s[1..])); 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':'))); 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); } 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, ())) 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<()> pub fn parse<'a, I, B>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResult<()>
where I: Iterator<Item=B>, B: Borrow<Item<'a>> { where I: Iterator<Item=B>, B: Borrow<Item<'a>> {
macro_rules! try_consume { 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 { 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 { let v = if signed {
if s.starts_with('-') { if s.starts_with('-') {
let v = try_consume!(scan::number(&s[1..], 1, usize::MAX)); 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('+') { } else if s.starts_with('+') {
try_consume!(scan::number(&s[1..], 1, usize::MAX)) try_consume!(scan::number(&s[1..], 1, usize::MAX))
} else { } else {
@ -279,7 +279,7 @@ pub fn parse<'a, I, B>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResul
} else { } else {
try_consume!(scan::number(s, 1, width)) try_consume!(scan::number(s, 1, width))
}; };
try!(set(parsed, v)); set(parsed, v)?;
} }
&Item::Fixed(ref spec) => { &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 { match spec {
&ShortMonthName => { &ShortMonthName => {
let month0 = try_consume!(scan::short_month0(s)); let month0 = try_consume!(scan::short_month0(s));
try!(parsed.set_month(i64::from(month0) + 1)); parsed.set_month(i64::from(month0) + 1)?;
} }
&LongMonthName => { &LongMonthName => {
let month0 = try_consume!(scan::short_or_long_month0(s)); 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 => { &ShortWeekdayName => {
let weekday = try_consume!(scan::short_weekday(s)); let weekday = try_consume!(scan::short_weekday(s));
try!(parsed.set_weekday(weekday)); parsed.set_weekday(weekday)?;
} }
&LongWeekdayName => { &LongWeekdayName => {
let weekday = try_consume!(scan::short_or_long_weekday(s)); let weekday = try_consume!(scan::short_or_long_weekday(s));
try!(parsed.set_weekday(weekday)); parsed.set_weekday(weekday)?;
} }
&LowerAmPm | &UpperAmPm => { &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, (b'p',b'm') => true,
_ => return Err(INVALID) _ => return Err(INVALID)
}; };
try!(parsed.set_ampm(ampm)); parsed.set_ampm(ampm)?;
s = &s[2..]; s = &s[2..];
} }
&Nanosecond | &Nanosecond3 | &Nanosecond6 | &Nanosecond9 => { &Nanosecond | &Nanosecond3 | &Nanosecond6 | &Nanosecond9 => {
if s.starts_with('.') { if s.starts_with('.') {
let nano = try_consume!(scan::nanosecond(&s[1..])); let nano = try_consume!(scan::nanosecond(&s[1..]));
try!(parsed.set_nanosecond(nano)); parsed.set_nanosecond(nano)?;
} }
} }
&Internal(InternalFixed { val: InternalInternal::Nanosecond3NoDot }) => { &Internal(InternalFixed { val: InternalInternal::Nanosecond3NoDot }) => {
if s.len() < 3 { return Err(TOO_SHORT); } if s.len() < 3 { return Err(TOO_SHORT); }
let nano = try_consume!(scan::nanosecond_fixed(s, 3)); let nano = try_consume!(scan::nanosecond_fixed(s, 3));
try!(parsed.set_nanosecond(nano)); parsed.set_nanosecond(nano)?;
} }
&Internal(InternalFixed { val: InternalInternal::Nanosecond6NoDot }) => { &Internal(InternalFixed { val: InternalInternal::Nanosecond6NoDot }) => {
if s.len() < 6 { return Err(TOO_SHORT); } if s.len() < 6 { return Err(TOO_SHORT); }
let nano = try_consume!(scan::nanosecond_fixed(s, 6)); let nano = try_consume!(scan::nanosecond_fixed(s, 6));
try!(parsed.set_nanosecond(nano)); parsed.set_nanosecond(nano)?;
} }
&Internal(InternalFixed { val: InternalInternal::Nanosecond9NoDot }) => { &Internal(InternalFixed { val: InternalInternal::Nanosecond9NoDot }) => {
if s.len() < 9 { return Err(TOO_SHORT); } if s.len() < 9 { return Err(TOO_SHORT); }
let nano = try_consume!(scan::nanosecond_fixed(s, 9)); let nano = try_consume!(scan::nanosecond_fixed(s, 9));
try!(parsed.set_nanosecond(nano)); parsed.set_nanosecond(nano)?;
} }
&TimezoneName => return Err(BAD_FORMAT), &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 => { &TimezoneOffsetColon | &TimezoneOffset => {
let offset = try_consume!(scan::timezone_offset(s.trim_left(), let offset = try_consume!(scan::timezone_offset(s.trim_left(),
scan::colon_or_space)); scan::colon_or_space));
try!(parsed.set_offset(i64::from(offset))); parsed.set_offset(i64::from(offset))?;
} }
&TimezoneOffsetColonZ | &TimezoneOffsetZ => { &TimezoneOffsetColonZ | &TimezoneOffsetZ => {
let offset = try_consume!(scan::timezone_offset_zulu(s.trim_left(), let offset = try_consume!(scan::timezone_offset_zulu(s.trim_left(),
scan::colon_or_space)); scan::colon_or_space));
try!(parsed.set_offset(i64::from(offset))); parsed.set_offset(i64::from(offset))?;
} }
&Internal(InternalFixed { val: InternalInternal::TimezoneOffsetPermissive }) => { &Internal(InternalFixed { val: InternalInternal::TimezoneOffsetPermissive }) => {
let offset = try_consume!(scan::timezone_offset_permissive( let offset = try_consume!(scan::timezone_offset_permissive(
s.trim_left(), scan::colon_or_space)); 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)), &RFC2822 => try_consume!(parse_rfc2822(parsed, s)),
@ -389,7 +389,7 @@ fn test_parse() {
// workaround for Rust issue #22255 // workaround for Rust issue #22255
fn parse_all(s: &str, items: &[Item]) -> ParseResult<Parsed> { fn parse_all(s: &str, items: &[Item]) -> ParseResult<Parsed> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, items.iter())); parse(&mut parsed, s, items.iter())?;
Ok(parsed) Ok(parsed)
} }
@ -700,7 +700,7 @@ fn test_rfc2822() {
fn rfc2822_to_datetime(date: &str) -> ParseResult<DateTime<FixedOffset>> { fn rfc2822_to_datetime(date: &str) -> ParseResult<DateTime<FixedOffset>> {
let mut parsed = Parsed::new(); 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() parsed.to_datetime()
} }
@ -781,7 +781,7 @@ fn test_rfc3339() {
fn rfc3339_to_datetime(date: &str) -> ParseResult<DateTime<FixedOffset>> { fn rfc3339_to_datetime(date: &str) -> ParseResult<DateTime<FixedOffset>> {
let mut parsed = Parsed::new(); 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() parsed.to_datetime()
} }

View File

@ -144,65 +144,65 @@ impl Parsed {
/// Tries to set the [`year`](#structfield.year) field from given value. /// Tries to set the [`year`](#structfield.year) field from given value.
#[inline] #[inline]
pub fn set_year(&mut self, value: i64) -> ParseResult<()> { 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. /// Tries to set the [`year_div_100`](#structfield.year_div_100) field from given value.
#[inline] #[inline]
pub fn set_year_div_100(&mut self, value: i64) -> ParseResult<()> { pub fn set_year_div_100(&mut self, value: i64) -> ParseResult<()> {
if value < 0 { return Err(OUT_OF_RANGE); } 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. /// Tries to set the [`year_mod_100`](#structfield.year_mod_100) field from given value.
#[inline] #[inline]
pub fn set_year_mod_100(&mut self, value: i64) -> ParseResult<()> { pub fn set_year_mod_100(&mut self, value: i64) -> ParseResult<()> {
if value < 0 { return Err(OUT_OF_RANGE); } 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. /// Tries to set the [`isoyear`](#structfield.isoyear) field from given value.
#[inline] #[inline]
pub fn set_isoyear(&mut self, value: i64) -> ParseResult<()> { 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. /// Tries to set the [`isoyear_div_100`](#structfield.isoyear_div_100) field from given value.
#[inline] #[inline]
pub fn set_isoyear_div_100(&mut self, value: i64) -> ParseResult<()> { pub fn set_isoyear_div_100(&mut self, value: i64) -> ParseResult<()> {
if value < 0 { return Err(OUT_OF_RANGE); } 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. /// Tries to set the [`isoyear_mod_100`](#structfield.isoyear_mod_100) field from given value.
#[inline] #[inline]
pub fn set_isoyear_mod_100(&mut self, value: i64) -> ParseResult<()> { pub fn set_isoyear_mod_100(&mut self, value: i64) -> ParseResult<()> {
if value < 0 { return Err(OUT_OF_RANGE); } 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. /// Tries to set the [`month`](#structfield.month) field from given value.
#[inline] #[inline]
pub fn set_month(&mut self, value: i64) -> ParseResult<()> { 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. /// Tries to set the [`week_from_sun`](#structfield.week_from_sun) field from given value.
#[inline] #[inline]
pub fn set_week_from_sun(&mut self, value: i64) -> ParseResult<()> { 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. /// Tries to set the [`week_from_mon`](#structfield.week_from_mon) field from given value.
#[inline] #[inline]
pub fn set_week_from_mon(&mut self, value: i64) -> ParseResult<()> { 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. /// Tries to set the [`isoweek`](#structfield.isoweek) field from given value.
#[inline] #[inline]
pub fn set_isoweek(&mut self, value: i64) -> ParseResult<()> { 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. /// 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. /// Tries to set the [`ordinal`](#structfield.ordinal) field from given value.
#[inline] #[inline]
pub fn set_ordinal(&mut self, value: i64) -> ParseResult<()> { 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. /// Tries to set the [`day`](#structfield.day) field from given value.
#[inline] #[inline]
pub fn set_day(&mut self, value: i64) -> ParseResult<()> { 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. /// 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. /// [`hour_mod_12`](#structfield.hour_mod_12) fields from given value.
#[inline] #[inline]
pub fn set_hour(&mut self, value: i64) -> ParseResult<()> { pub fn set_hour(&mut self, value: i64) -> ParseResult<()> {
let v = try!(value.to_u32().ok_or(OUT_OF_RANGE)); let v = value.to_u32().ok_or(OUT_OF_RANGE)?;
try!(set_if_consistent(&mut self.hour_div_12, v / 12)); set_if_consistent(&mut self.hour_div_12, v / 12)?;
try!(set_if_consistent(&mut self.hour_mod_12, v % 12)); set_if_consistent(&mut self.hour_mod_12, v % 12)?;
Ok(()) Ok(())
} }
/// Tries to set the [`minute`](#structfield.minute) field from given value. /// Tries to set the [`minute`](#structfield.minute) field from given value.
#[inline] #[inline]
pub fn set_minute(&mut self, value: i64) -> ParseResult<()> { 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. /// Tries to set the [`second`](#structfield.second) field from given value.
#[inline] #[inline]
pub fn set_second(&mut self, value: i64) -> ParseResult<()> { 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. /// Tries to set the [`nanosecond`](#structfield.nanosecond) field from given value.
#[inline] #[inline]
pub fn set_nanosecond(&mut self, value: i64) -> ParseResult<()> { 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. /// 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. /// Tries to set the [`offset`](#structfield.offset) field from given value.
#[inline] #[inline]
pub fn set_offset(&mut self, value: i64) -> ParseResult<()> { 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. /// Returns a parsed naive date out of given fields.
@ -316,7 +316,7 @@ impl Parsed {
(None, Some(q), Some(r @ 0...99)) => { (None, Some(q), Some(r @ 0...99)) => {
if q < 0 { return Err(OUT_OF_RANGE); } if q < 0 { return Err(OUT_OF_RANGE); }
let y = q.checked_mul(100).and_then(|v| v.checked_add(r)); 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. // we only have modulo. try to interpret a modulo as a conventional two-digit year.
@ -330,9 +330,9 @@ impl Parsed {
} }
let given_year = 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 = 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. // verify the normal year-month-day date.
let verify_ymd = |date: NaiveDate| { let verify_ymd = |date: NaiveDate| {
@ -388,20 +388,20 @@ impl Parsed {
let (verified, parsed_date) = match (given_year, given_isoyear, self) { let (verified, parsed_date) = match (given_year, given_isoyear, self) {
(Some(year), _, &Parsed { month: Some(month), day: Some(day), .. }) => { (Some(year), _, &Parsed { month: Some(month), day: Some(day), .. }) => {
// year, month, 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) (verify_isoweekdate(date) && verify_ordinal(date), date)
}, },
(Some(year), _, &Parsed { ordinal: Some(ordinal), .. }) => { (Some(year), _, &Parsed { ordinal: Some(ordinal), .. }) => {
// year, day of the year // 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) (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
}, },
(Some(year), _, &Parsed { week_from_sun: Some(week_from_sun), (Some(year), _, &Parsed { week_from_sun: Some(week_from_sun),
weekday: Some(weekday), .. }) => { weekday: Some(weekday), .. }) => {
// year, week (starting at 1st Sunday), day of the week // 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() { let firstweek = match newyear.weekday() {
Weekday::Sun => 0, Weekday::Sun => 0,
Weekday::Mon => 6, Weekday::Mon => 6,
@ -416,8 +416,8 @@ impl Parsed {
if week_from_sun > 53 { return Err(OUT_OF_RANGE); } // can it overflow? if week_from_sun > 53 { return Err(OUT_OF_RANGE); } // can it overflow?
let ndays = firstweek + (week_from_sun as i32 - 1) * 7 + let ndays = firstweek + (week_from_sun as i32 - 1) * 7 +
weekday.num_days_from_sunday() as i32; weekday.num_days_from_sunday() as i32;
let date = try!(newyear.checked_add_signed(OldDuration::days(i64::from(ndays))) let date = newyear.checked_add_signed(OldDuration::days(i64::from(ndays)))
.ok_or(OUT_OF_RANGE)); .ok_or(OUT_OF_RANGE)?;
if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error
(verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date) (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), (Some(year), _, &Parsed { week_from_mon: Some(week_from_mon),
weekday: Some(weekday), .. }) => { weekday: Some(weekday), .. }) => {
// year, week (starting at 1st Monday), day of the week // 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() { let firstweek = match newyear.weekday() {
Weekday::Sun => 1, Weekday::Sun => 1,
Weekday::Mon => 0, Weekday::Mon => 0,
@ -441,8 +441,8 @@ impl Parsed {
if week_from_mon > 53 { return Err(OUT_OF_RANGE); } // can it overflow? if week_from_mon > 53 { return Err(OUT_OF_RANGE); } // can it overflow?
let ndays = firstweek + (week_from_mon as i32 - 1) * 7 + let ndays = firstweek + (week_from_mon as i32 - 1) * 7 +
weekday.num_days_from_monday() as i32; weekday.num_days_from_monday() as i32;
let date = try!(newyear.checked_add_signed(OldDuration::days(i64::from(ndays))) let date = newyear.checked_add_signed(OldDuration::days(i64::from(ndays)))
.ok_or(OUT_OF_RANGE)); .ok_or(OUT_OF_RANGE)?;
if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error
(verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date) (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), .. }) => { (_, Some(isoyear), &Parsed { isoweek: Some(isoweek), weekday: Some(weekday), .. }) => {
// ISO year, week, day of the week // ISO year, week, day of the week
let date = NaiveDate::from_isoywd_opt(isoyear, isoweek, weekday); 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) (verify_ymd(date) && verify_ordinal(date), date)
}, },
@ -547,9 +547,9 @@ impl Parsed {
} }
// reconstruct date and time fields from timestamp // 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 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. // fill year, ordinal, hour, minute and second fields from timestamp.
// if existing fields are consistent, this will allow the full date/time reconstruction. // 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. // ...and we have the correct candidates for other fields.
} else { } else {
try!(parsed.set_second(i64::from(datetime.second()))); parsed.set_second(i64::from(datetime.second()))?;
} }
try!(parsed.set_year (i64::from(datetime.year()))); parsed.set_year (i64::from(datetime.year()))?;
try!(parsed.set_ordinal(i64::from(datetime.ordinal()))); // more efficient than ymd parsed.set_ordinal(i64::from(datetime.ordinal()))?; // more efficient than ymd
try!(parsed.set_hour (i64::from(datetime.hour()))); parsed.set_hour (i64::from(datetime.hour()))?;
try!(parsed.set_minute (i64::from(datetime.minute()))); parsed.set_minute (i64::from(datetime.minute()))?;
// validate other fields (e.g. week) and return // validate other fields (e.g. week) and return
let date = try!(parsed.to_naive_date()); let date = parsed.to_naive_date()?;
let time = try!(parsed.to_naive_time()); let time = parsed.to_naive_time()?;
Ok(date.and_time(time)) Ok(date.and_time(time))
} else { } else {
// reproduce the previous error(s) // reproduce the previous error(s)
try!(date); date?;
try!(time); time?;
unreachable!() unreachable!()
} }
} }
@ -597,9 +597,9 @@ impl Parsed {
/// plus a time zone offset. /// plus a time zone offset.
/// Either way those fields have to be consistent to each other. /// Either way those fields have to be consistent to each other.
pub fn to_datetime(&self) -> ParseResult<DateTime<FixedOffset>> { pub fn to_datetime(&self) -> ParseResult<DateTime<FixedOffset>> {
let offset = try!(self.offset.ok_or(NOT_ENOUGH)); let offset = self.offset.ok_or(NOT_ENOUGH)?;
let datetime = try!(self.to_naive_datetime_with_offset(offset)); let datetime = self.to_naive_datetime_with_offset(offset)?;
let offset = try!(FixedOffset::east_opt(offset).ok_or(OUT_OF_RANGE)); let offset = FixedOffset::east_opt(offset).ok_or(OUT_OF_RANGE)?;
match offset.from_local_datetime(&datetime) { match offset.from_local_datetime(&datetime) {
LocalResult::None => Err(IMPOSSIBLE), LocalResult::None => Err(IMPOSSIBLE),
LocalResult::Single(t) => Ok(t), LocalResult::Single(t) => Ok(t),
@ -624,7 +624,7 @@ impl Parsed {
// an empty `nanosecond` is always equal to zero, so missing nanosecond is fine. // an empty `nanosecond` is always equal to zero, so missing nanosecond is fine.
let nanosecond = self.nanosecond.unwrap_or(0); let nanosecond = self.nanosecond.unwrap_or(0);
let dt = NaiveDateTime::from_timestamp_opt(timestamp, nanosecond); 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(); 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. // `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. // 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) { match tz.from_local_datetime(&datetime) {
LocalResult::None => Err(IMPOSSIBLE), LocalResult::None => Err(IMPOSSIBLE),
LocalResult::Single(t) => if check_offset(&t) {Ok(t)} else {Err(IMPOSSIBLE)}, LocalResult::Single(t) => if check_offset(&t) {Ok(t)} else {Err(IMPOSSIBLE)},

View File

@ -66,13 +66,13 @@ pub fn number(s: &str, min: usize, max: usize) -> ParseResult<(&str, i64)> {
pub fn nanosecond(s: &str) -> ParseResult<(&str, i64)> { pub fn nanosecond(s: &str) -> ParseResult<(&str, i64)> {
// record the number of digits consumed for later scaling. // record the number of digits consumed for later scaling.
let origlen = s.len(); let origlen = s.len();
let (s, v) = try!(number(s, 1, 9)); let (s, v) = number(s, 1, 9)?;
let consumed = origlen - s.len(); let consumed = origlen - s.len();
// scale the number accordingly. // scale the number accordingly.
static SCALE: [i64; 10] = [0, 100_000_000, 10_000_000, 1_000_000, 100_000, 10_000, static SCALE: [i64; 10] = [0, 100_000_000, 10_000_000, 1_000_000, 100_000, 10_000,
1_000, 100, 10, 1]; 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. // if there are more than 9 digits, skip next digits.
let s = s.trim_left_matches(|c: char| '0' <= c && c <= '9'); 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). /// Returns the number of whole nanoseconds (0--999,999,999).
pub fn nanosecond_fixed(s: &str, digits: usize) -> ParseResult<(&str, i64)> { pub fn nanosecond_fixed(s: &str, digits: usize) -> ParseResult<(&str, i64)> {
// record the number of digits consumed for later scaling. // 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. // scale the number accordingly.
static SCALE: [i64; 10] = [0, 100_000_000, 10_000_000, 1_000_000, 100_000, 10_000, static SCALE: [i64; 10] = [0, 100_000_000, 10_000_000, 1_000_000, 100_000, 10_000,
1_000, 100, 10, 1]; 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)) 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] = static LONG_MONTH_SUFFIXES: [&'static str; 12] =
["uary", "ruary", "ch", "il", "", "e", "y", "ust", "tember", "ober", "ember", "ember"]; ["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 // tries to consume the suffix if possible
let suffix = LONG_MONTH_SUFFIXES[month0 as usize]; 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] = static LONG_WEEKDAY_SUFFIXES: [&'static str; 7] =
["day", "sday", "nesday", "rsday", "day", "urday", "day"]; ["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 // tries to consume the suffix if possible
let suffix = LONG_WEEKDAY_SUFFIXES[weekday.num_days_from_monday() as usize]; let suffix = LONG_WEEKDAY_SUFFIXES[weekday.num_days_from_monday() as usize];
@ -225,14 +225,14 @@ fn timezone_offset_internal<F>(mut s: &str, mut consume_colon: F, allow_missing_
s = &s[1..]; s = &s[1..];
// hours (00--99) // 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')), (h1 @ b'0'...b'9', h2 @ b'0'...b'9') => i32::from((h1 - b'0') * 10 + (h2 - b'0')),
_ => return Err(INVALID), _ => return Err(INVALID),
}; };
s = &s[2..]; s = &s[2..];
// colons (and possibly other separators) // colons (and possibly other separators)
s = try!(consume_colon(s)); s = consume_colon(s)?;
// minutes (00--59) // minutes (00--59)
// if the next two items are digits then we have to add minutes // 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<i32>)> {
Ok((s, None)) // recommended by RFC 2822: consume but treat it as -0000 Ok((s, None)) // recommended by RFC 2822: consume but treat it as -0000
} }
} else { } 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 if offset == 0 && s.starts_with('-') { // -0000 is not same to +0000
Ok((s_, None)) Ok((s_, None))
} else { } else {

View File

@ -386,7 +386,6 @@
#![cfg_attr(feature = "bench", feature(test))] // lib stability features as per RFC #507 #![cfg_attr(feature = "bench", feature(test))] // lib stability features as per RFC #507
#![deny(missing_docs)] #![deny(missing_docs)]
#![deny(missing_debug_implementations)] #![deny(missing_debug_implementations)]
#![allow(deprecated)]
#![cfg_attr(not(any(feature = "std", test)), no_std)] #![cfg_attr(not(any(feature = "std", test)), no_std)]

View File

@ -455,7 +455,7 @@ impl NaiveDate {
/// ~~~~ /// ~~~~
pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDate> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDate> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); parse(&mut parsed, s, StrftimeItems::new(fmt))?;
parsed.to_naive_date() parsed.to_naive_date()
} }
@ -1518,7 +1518,7 @@ impl str::FromStr for NaiveDate {
]; ];
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, ITEMS.iter())); parse(&mut parsed, s, ITEMS.iter())?;
parsed.to_naive_date() parsed.to_naive_date()
} }
} }

View File

@ -210,7 +210,7 @@ impl NaiveDateTime {
/// ~~~~ /// ~~~~
pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDateTime> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDateTime> {
let mut parsed = Parsed::new(); 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 parsed.to_naive_datetime_with_offset(0) // no offset adjustment
} }
@ -1489,7 +1489,7 @@ impl str::FromStr for NaiveDateTime {
]; ];
let mut parsed = Parsed::new(); 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) parsed.to_naive_datetime_with_offset(0)
} }
} }
@ -1834,7 +1834,7 @@ pub mod serde {
pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
where D: de::Deserializer<'de> where D: de::Deserializer<'de>
{ {
Ok(try!(d.deserialize_i64(NaiveDateTimeFromNanoSecondsVisitor))) Ok(d.deserialize_i64(NaiveDateTimeFromNanoSecondsVisitor)?)
} }
struct NaiveDateTimeFromNanoSecondsVisitor; struct NaiveDateTimeFromNanoSecondsVisitor;
@ -1979,7 +1979,7 @@ pub mod serde {
pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
where D: de::Deserializer<'de> where D: de::Deserializer<'de>
{ {
Ok(try!(d.deserialize_i64(NaiveDateTimeFromMilliSecondsVisitor))) Ok(d.deserialize_i64(NaiveDateTimeFromMilliSecondsVisitor)?)
} }
struct NaiveDateTimeFromMilliSecondsVisitor; struct NaiveDateTimeFromMilliSecondsVisitor;
@ -2124,7 +2124,7 @@ pub mod serde {
pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
where D: de::Deserializer<'de> where D: de::Deserializer<'de>
{ {
Ok(try!(d.deserialize_i64(NaiveDateTimeFromSecondsVisitor))) Ok(d.deserialize_i64(NaiveDateTimeFromSecondsVisitor)?)
} }
struct NaiveDateTimeFromSecondsVisitor; struct NaiveDateTimeFromSecondsVisitor;

View File

@ -496,7 +496,7 @@ impl NaiveTime {
/// ~~~~ /// ~~~~
pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveTime> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveTime> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); parse(&mut parsed, s, StrftimeItems::new(fmt))?;
parsed.to_naive_time() parsed.to_naive_time()
} }
@ -1236,7 +1236,7 @@ impl fmt::Debug for NaiveTime {
(sec, self.frac) (sec, self.frac)
}; };
try!(write!(f, "{:02}:{:02}:{:02}", hour, min, sec)); write!(f, "{:02}:{:02}:{:02}", hour, min, sec)?;
if nano == 0 { if nano == 0 {
Ok(()) Ok(())
} else if nano % 1_000_000 == 0 { } else if nano % 1_000_000 == 0 {
@ -1314,7 +1314,7 @@ impl str::FromStr for NaiveTime {
]; ];
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, ITEMS.iter())); parse(&mut parsed, s, ITEMS.iter())?;
parsed.to_naive_time() parsed.to_naive_time()
} }
} }

View File

@ -415,7 +415,7 @@ pub trait TimeZone: Sized + Clone {
/// with parsed `FixedOffset`. /// with parsed `FixedOffset`.
fn datetime_from_str(&self, s: &str, fmt: &str) -> ParseResult<DateTime<Self>> { fn datetime_from_str(&self, s: &str, fmt: &str) -> ParseResult<DateTime<Self>> {
let mut parsed = Parsed::new(); 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) parsed.to_datetime_with_timezone(self)
} }

View File

@ -364,20 +364,20 @@ impl fmt::Display for Duration {
let hasdate = days != 0; let hasdate = days != 0;
let hastime = (secs != 0 || abs.nanos != 0) || !hasdate; let hastime = (secs != 0 || abs.nanos != 0) || !hasdate;
try!(write!(f, "{}P", sign)); write!(f, "{}P", sign)?;
if hasdate { if hasdate {
try!(write!(f, "{}D", days)); write!(f, "{}D", days)?;
} }
if hastime { if hastime {
if abs.nanos == 0 { if abs.nanos == 0 {
try!(write!(f, "T{}S", secs)); write!(f, "T{}S", secs)?;
} else if abs.nanos % NANOS_PER_MILLI == 0 { } 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 { } 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 { } else {
try!(write!(f, "T{}.{:09}S", secs, abs.nanos)); write!(f, "T{}.{:09}S", secs, abs.nanos)?;
} }
} }
Ok(()) Ok(())