11use std:: str:: FromStr ;
22use std:: num:: ParseIntError ;
33use std:: fmt;
4- use std:: convert:: TryInto ;
54
65#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
76pub struct Version {
@@ -10,16 +9,14 @@ pub struct Version {
109
1110impl fmt:: Display for Version {
1211 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
13- let x = self . parts . iter ( ) . map ( |x| x. to_string ( ) ) . collect :: < Vec < _ > > ( ) . join ( "." ) ;
14- f. pad ( & x)
12+ f. pad ( & format ! ( "{}.{}.{}" , self . parts[ 0 ] , self . parts[ 1 ] , self . parts[ 2 ] ) )
1513 }
1614}
1715
1816#[ derive( Debug , PartialEq , Eq ) ]
1917pub enum ParseVersionError {
2018 ParseIntError ( ParseIntError ) ,
21- // core::array::TryFromSlice is not exported from std, so we invent our own variant
22- WrongNumberOfParts
19+ WrongNumberOfParts ,
2320}
2421
2522impl From < ParseIntError > for ParseVersionError {
@@ -32,10 +29,23 @@ impl FromStr for Version {
3229 type Err = ParseVersionError ;
3330
3431 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
35- let parts: Vec < _ > = s. split ( '.' ) . map ( |part| part. parse ( ) ) . collect :: < Result < _ , _ > > ( ) ?;
36- Ok ( Self {
37- parts : parts. as_slice ( ) . try_into ( ) . or ( Err ( ParseVersionError :: WrongNumberOfParts ) ) ?,
38- } )
32+ let mut iter = s. split ( '.' ) . map ( |part| Ok ( part. parse ( ) ?) ) ;
33+
34+ let parts = {
35+ let mut part = || {
36+ iter. next ( )
37+ . unwrap_or ( Err ( ParseVersionError :: WrongNumberOfParts ) )
38+ } ;
39+
40+ [ part ( ) ?, part ( ) ?, part ( ) ?]
41+ } ;
42+
43+ if let Some ( _) = iter. next ( ) {
44+ // Ensure we don't have more than 3 parts.
45+ return Err ( ParseVersionError :: WrongNumberOfParts ) ;
46+ }
47+
48+ Ok ( Self { parts } )
3949 }
4050}
4151
0 commit comments