Inline some parse related functions

Speedups:
 datetime::tests::bench_datetime_from_str             365                         337                       -28   -7.67%   x 1.08
 datetime::tests::bench_datetime_parse_from_rfc2822   195                         181                       -14   -7.18%   x 1.08
 datetime::tests::bench_datetime_parse_from_rfc3339   166                         142                       -24  -14.46%   x 1.17
This commit is contained in:
Michal Srb 2019-11-22 14:42:55 +01:00
parent 6da5359d39
commit a716b48e9d
2 changed files with 23 additions and 0 deletions

View File

@ -112,6 +112,7 @@ pub struct Parsed {
/// Checks if `old` is either empty or has the same value to `new` (i.e. "consistent"), /// Checks if `old` is either empty or has the same value to `new` (i.e. "consistent"),
/// and if it is empty, set `old` to `new` as well. /// and if it is empty, set `old` to `new` as well.
#[inline]
fn set_if_consistent<T: PartialEq>(old: &mut Option<T>, new: T) -> ParseResult<()> { fn set_if_consistent<T: PartialEq>(old: &mut Option<T>, new: T) -> ParseResult<()> {
if let Some(ref old) = *old { if let Some(ref old) = *old {
if *old == new {Ok(())} else {Err(IMPOSSIBLE)} if *old == new {Ok(())} else {Err(IMPOSSIBLE)}
@ -141,82 +142,97 @@ 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]
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, try!(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]
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, try!(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]
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, try!(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]
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, try!(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]
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, try!(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]
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, try!(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]
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, try!(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]
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, try!(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]
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, try!(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]
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, try!(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.
#[inline]
pub fn set_weekday(&mut self, value: Weekday) -> ParseResult<()> { pub fn set_weekday(&mut self, value: Weekday) -> ParseResult<()> {
set_if_consistent(&mut self.weekday, value) set_if_consistent(&mut self.weekday, value)
} }
/// Tries to set the [`ordinal`](#structfield.ordinal) field from given value. /// Tries to set the [`ordinal`](#structfield.ordinal) field from given value.
#[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, try!(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]
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, try!(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.
/// (`false` for AM, `true` for PM) /// (`false` for AM, `true` for PM)
#[inline]
pub fn set_ampm(&mut self, value: bool) -> ParseResult<()> { pub fn set_ampm(&mut self, value: bool) -> ParseResult<()> {
set_if_consistent(&mut self.hour_div_12, if value {1} else {0}) set_if_consistent(&mut self.hour_div_12, if value {1} else {0})
} }
/// Tries to set the [`hour_mod_12`](#structfield.hour_mod_12) field from /// Tries to set the [`hour_mod_12`](#structfield.hour_mod_12) field from
/// given hour number in 12-hour clocks. /// given hour number in 12-hour clocks.
#[inline]
pub fn set_hour12(&mut self, value: i64) -> ParseResult<()> { pub fn set_hour12(&mut self, value: i64) -> ParseResult<()> {
if value < 1 || value > 12 { return Err(OUT_OF_RANGE); } if value < 1 || value > 12 { return Err(OUT_OF_RANGE); }
set_if_consistent(&mut self.hour_mod_12, value as u32 % 12) set_if_consistent(&mut self.hour_mod_12, value as u32 % 12)
@ -224,6 +240,7 @@ impl Parsed {
/// Tries to set both [`hour_div_12`](#structfield.hour_div_12) and /// Tries to set both [`hour_div_12`](#structfield.hour_div_12) and
/// [`hour_mod_12`](#structfield.hour_mod_12) fields from given value. /// [`hour_mod_12`](#structfield.hour_mod_12) fields from given value.
#[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 = 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_div_12, v / 12));
@ -232,26 +249,31 @@ impl Parsed {
} }
/// Tries to set the [`minute`](#structfield.minute) field from given value. /// Tries to set the [`minute`](#structfield.minute) field from given value.
#[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, try!(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]
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, try!(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]
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, try!(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.
#[inline]
pub fn set_timestamp(&mut self, value: i64) -> ParseResult<()> { pub fn set_timestamp(&mut self, value: i64) -> ParseResult<()> {
set_if_consistent(&mut self.timestamp, value) set_if_consistent(&mut self.timestamp, value)
} }
/// Tries to set the [`offset`](#structfield.offset) field from given value. /// Tries to set the [`offset`](#structfield.offset) field from given value.
#[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, try!(value.to_i32().ok_or(OUT_OF_RANGE)))
} }

View File

@ -30,6 +30,7 @@ fn equals(s: &str, pattern: &str) -> bool {
/// The absence of digits at all is an unconditional error. /// The absence of digits at all is an unconditional error.
/// More than `max` digits are consumed up to the first `max` digits. /// More than `max` digits are consumed up to the first `max` digits.
/// Any number that does not fit in `i64` is an error. /// Any number that does not fit in `i64` is an error.
#[inline]
pub fn number(s: &str, min: usize, max: usize) -> ParseResult<(&str, i64)> { pub fn number(s: &str, min: usize, max: usize) -> ParseResult<(&str, i64)> {
assert!(min <= max); assert!(min <= max);