1- use std :: cmp :: Ordering ;
1+ use gix :: bstr :: { BStr , BString , ByteSlice } ;
22
3- use gix:: bstr:: { BStr , ByteSlice } ;
4-
5- #[ derive( Eq , PartialEq ) ]
3+ #[ derive( Eq , PartialEq , PartialOrd , Ord ) ]
64enum VersionPart {
7- String ( String ) ,
5+ String ( BString ) ,
86 Number ( usize ) ,
97}
108
11- impl Ord for VersionPart {
12- fn cmp ( & self , other : & Self ) -> std:: cmp:: Ordering {
13- match ( self , other) {
14- ( VersionPart :: String ( a) , VersionPart :: String ( b) ) => a. cmp ( b) ,
15- ( VersionPart :: String ( _) , VersionPart :: Number ( _) ) => Ordering :: Less ,
16- ( VersionPart :: Number ( _) , VersionPart :: String ( _) ) => Ordering :: Greater ,
17- ( VersionPart :: Number ( a) , VersionPart :: Number ( b) ) => a. cmp ( b) ,
18- }
19- }
20- }
21-
22- impl PartialOrd for VersionPart {
23- fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
24- Some ( Ord :: cmp ( self , other) )
25- }
26- }
27-
289/// `Version` is used to store multi-part version numbers. It does so in a rather naive way,
2910/// only distinguishing between parts that can be parsed as an integer and those that cannot.
3011///
@@ -37,9 +18,7 @@ impl PartialOrd for VersionPart {
3718///
3819/// When comparing versions of different lengths, shorter versions sort before longer ones (e.g.,
3920/// `v1.0` < `v1.0.1`). String parts always sort before numeric parts when compared directly.
40- ///
41- /// The sorting does not respect `versionsort.suffix` yet.
42- #[ derive( Eq , PartialEq ) ]
21+ #[ derive( Eq , PartialEq , Ord , PartialOrd ) ]
4322struct Version {
4423 parts : Vec < VersionPart > ,
4524}
@@ -50,12 +29,10 @@ impl Version {
5029 . chunk_by ( |a, b| a. is_ascii_digit ( ) == b. is_ascii_digit ( ) )
5130 . map ( |part| {
5231 if let Ok ( part) = part. to_str ( ) {
53- match part. parse :: < usize > ( ) {
54- Ok ( number) => VersionPart :: Number ( number) ,
55- Err ( _) => VersionPart :: String ( part. to_string ( ) ) ,
56- }
32+ part. parse :: < usize > ( )
33+ . map_or_else ( |_| VersionPart :: String ( part. into ( ) ) , VersionPart :: Number )
5734 } else {
58- VersionPart :: String ( String :: from_utf8_lossy ( part) . to_string ( ) )
35+ VersionPart :: String ( part. into ( ) )
5936 }
6037 } )
6138 . collect ( ) ;
@@ -64,31 +41,6 @@ impl Version {
6441 }
6542}
6643
67- impl Ord for Version {
68- fn cmp ( & self , other : & Self ) -> std:: cmp:: Ordering {
69- let mut a_iter = self . parts . iter ( ) ;
70- let mut b_iter = other. parts . iter ( ) ;
71-
72- loop {
73- match ( a_iter. next ( ) , b_iter. next ( ) ) {
74- ( Some ( a) , Some ( b) ) => match a. cmp ( b) {
75- Ordering :: Equal => continue ,
76- other => return other,
77- } ,
78- ( Some ( _) , None ) => return Ordering :: Greater ,
79- ( None , Some ( _) ) => return Ordering :: Less ,
80- ( None , None ) => return Ordering :: Equal ,
81- }
82- }
83- }
84- }
85-
86- impl PartialOrd for Version {
87- fn partial_cmp ( & self , other : & Self ) -> Option < std:: cmp:: Ordering > {
88- Some ( Ord :: cmp ( self , other) )
89- }
90- }
91-
9244pub fn list ( repo : gix:: Repository , out : & mut dyn std:: io:: Write ) -> anyhow:: Result < ( ) > {
9345 let platform = repo. references ( ) ?;
9446
@@ -135,7 +87,7 @@ pub fn list(repo: gix::Repository, out: &mut dyn std::io::Write) -> anyhow::Resu
13587#[ cfg( test) ]
13688mod tests {
13789 use super :: * ;
138- use gix :: bstr :: BStr ;
90+ use std :: cmp :: Ordering ;
13991
14092 #[ test]
14193 fn sorts_versions_correctly ( ) {
@@ -156,13 +108,8 @@ mod tests {
156108 "v1.0.0" ,
157109 ] ;
158110
159- actual. sort_by ( |a, b| {
160- let version_a = Version :: parse ( BStr :: new ( a. as_bytes ( ) ) ) ;
161- let version_b = Version :: parse ( BStr :: new ( b. as_bytes ( ) ) ) ;
162- version_a. cmp ( & version_b)
163- } ) ;
164-
165- let expected = vec ! [
111+ actual. sort_by ( |& a, & b| Version :: parse ( a. into ( ) ) . cmp ( & Version :: parse ( b. into ( ) ) ) ) ;
112+ let expected = [
166113 "v0.1.0" ,
167114 "v0.1.a" ,
168115 "v0.9.0" ,
@@ -184,8 +131,8 @@ mod tests {
184131
185132 #[ test]
186133 fn sorts_versions_with_different_lengths_correctly ( ) {
187- let v1 = Version :: parse ( BStr :: new ( b "v1.0") ) ;
188- let v2 = Version :: parse ( BStr :: new ( b "v1.0.1") ) ;
134+ let v1 = Version :: parse ( "v1.0" . into ( ) ) ;
135+ let v2 = Version :: parse ( "v1.0.1" . into ( ) ) ;
189136
190137 assert_eq ! ( v1. cmp( & v2) , Ordering :: Less ) ;
191138 assert_eq ! ( v2. cmp( & v1) , Ordering :: Greater ) ;
0 commit comments