From c120fd823ba1cbd78167f0f3dca32b68d9f2308a Mon Sep 17 00:00:00 2001 From: Alexey Shmalko Date: Thu, 2 May 2019 00:52:44 +0300 Subject: [PATCH] Rework Version::parse to avoid extra allocations --- src/tools/tidy/src/features.rs | 2 +- src/tools/tidy/src/features/version.rs | 28 +++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index afadedd8b6bb..48ecbe338074 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -147,7 +147,7 @@ pub fn check(path: &Path, bad: &mut bool, quiet: bool) { } } -fn format_features<'a>(features: &'a Features, family: &'a str) -> impl Iterator + 'a { +fn format_features<'a>(features: &'a Features, family: &'a str) -> impl Iterator + 'a { features.iter().map(move |(name, feature)| { format!("{:<32} {:<8} {:<12} {:<8}", name, diff --git a/src/tools/tidy/src/features/version.rs b/src/tools/tidy/src/features/version.rs index 7ea788a85180..8d1ebccbff67 100644 --- a/src/tools/tidy/src/features/version.rs +++ b/src/tools/tidy/src/features/version.rs @@ -1,7 +1,6 @@ use std::str::FromStr; use std::num::ParseIntError; use std::fmt; -use std::convert::TryInto; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Version { @@ -10,16 +9,14 @@ pub struct Version { impl fmt::Display for Version { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let x = self.parts.iter().map(|x| x.to_string()).collect::>().join("."); - f.pad(&x) + f.pad(&format!("{}.{}.{}", self.parts[0], self.parts[1], self.parts[2])) } } #[derive(Debug, PartialEq, Eq)] pub enum ParseVersionError { ParseIntError(ParseIntError), - // core::array::TryFromSlice is not exported from std, so we invent our own variant - WrongNumberOfParts + WrongNumberOfParts, } impl From for ParseVersionError { @@ -32,10 +29,23 @@ impl FromStr for Version { type Err = ParseVersionError; fn from_str(s: &str) -> Result { - let parts: Vec<_> = s.split('.').map(|part| part.parse()).collect::>()?; - Ok(Self { - parts: parts.as_slice().try_into() .or(Err(ParseVersionError::WrongNumberOfParts))?, - }) + let mut iter = s.split('.').map(|part| Ok(part.parse()?)); + + let parts = { + let mut part = || { + iter.next() + .unwrap_or(Err(ParseVersionError::WrongNumberOfParts)) + }; + + [part()?, part()?, part()?] + }; + + if let Some(_) = iter.next() { + // Ensure we don't have more than 3 parts. + return Err(ParseVersionError::WrongNumberOfParts); + } + + Ok(Self { parts }) } }