@@ -56,6 +56,7 @@ extern crate doc_comment;
56
56
#[ cfg( test) ]
57
57
doctest ! ( "../README.md" ) ;
58
58
59
+ use std:: collections:: HashMap ;
59
60
use std:: process:: Command ;
60
61
use std:: { env, error, fmt, io, num, str} ;
61
62
use std:: { ffi:: OsString , str:: FromStr } ;
@@ -206,65 +207,43 @@ pub fn version_meta() -> Result<VersionMeta> {
206
207
/// the SemVer version and additional metadata
207
208
/// like the git short hash and build date.
208
209
pub fn version_meta_for ( verbose_version_string : & str ) -> Result < VersionMeta > {
209
- let out: Vec < _ > = verbose_version_string. lines ( ) . collect ( ) ;
210
-
211
- if !( out. len ( ) >= 6 && out. len ( ) <= 8 ) {
212
- return Err ( Error :: UnexpectedVersionFormat ) ;
213
- }
214
-
215
- let short_version_string = out[ 0 ] ;
216
-
217
- #[ allow( clippy:: manual_strip) ]
218
- fn expect_prefix < ' a > ( line : & ' a str , prefix : & str ) -> Result < & ' a str > {
219
- if line. starts_with ( prefix) {
220
- Ok ( & line[ prefix. len ( ) ..] )
221
- } else {
222
- Err ( Error :: UnexpectedVersionFormat )
210
+ let mut map = HashMap :: new ( ) ;
211
+ for ( i, line) in verbose_version_string. lines ( ) . enumerate ( ) {
212
+ if i == 0 {
213
+ map. insert ( "short" , line) ;
214
+ continue ;
223
215
}
224
- }
225
-
226
- let commit_hash = match expect_prefix ( out[ 2 ] , "commit-hash: " ) ? {
227
- "unknown" => None ,
228
- hash => Some ( hash. to_owned ( ) ) ,
229
- } ;
230
-
231
- let commit_date = match expect_prefix ( out[ 3 ] , "commit-date: " ) ? {
232
- "unknown" => None ,
233
- hash => Some ( hash. to_owned ( ) ) ,
234
- } ;
235
216
236
- // Handle that the build date may or may not be present.
237
- let mut idx = 4 ;
238
- let mut build_date = None ;
239
- if out[ idx] . starts_with ( "build-date" ) {
240
- build_date = match expect_prefix ( out[ idx] , "build-date: " ) ? {
241
- "unknown" => None ,
242
- s => Some ( s. to_owned ( ) ) ,
217
+ let mut parts = line. splitn ( 2 , ": " ) ;
218
+ let key = match parts. next ( ) {
219
+ Some ( key) => key,
220
+ None => continue ,
243
221
} ;
244
- idx += 1 ;
222
+
223
+ if let Some ( value) = parts. next ( ) {
224
+ map. insert ( key, value) ;
225
+ }
245
226
}
246
227
247
- let host = expect_prefix ( out[ idx] , "host: " ) ?;
248
- idx += 1 ;
249
- let release = expect_prefix ( out[ idx] , "release: " ) ?;
250
- idx += 1 ;
228
+ let short_version_string = expect_key ( "short" , & map) ?;
229
+ let host = expect_key ( "host" , & map) ?;
230
+ let release = expect_key ( "release" , & map) ?;
251
231
let semver: Version = release. parse ( ) ?;
252
232
253
- let channel = if semver. pre . is_empty ( ) {
254
- Channel :: Stable
255
- } else {
256
- match semver. pre [ 0 ] {
257
- Identifier :: AlphaNumeric ( ref s) if s == "dev" => Channel :: Dev ,
258
- Identifier :: AlphaNumeric ( ref s) if s == "beta" => Channel :: Beta ,
259
- Identifier :: AlphaNumeric ( ref s) if s == "nightly" => Channel :: Nightly ,
260
- ref x => return Err ( Error :: UnknownPreReleaseTag ( x. clone ( ) ) ) ,
261
- }
233
+ let channel = match semver. pre . first ( ) {
234
+ None => Channel :: Stable ,
235
+ Some ( Identifier :: AlphaNumeric ( s) ) if s == "dev" => Channel :: Dev ,
236
+ Some ( Identifier :: AlphaNumeric ( s) ) if s == "beta" => Channel :: Beta ,
237
+ Some ( Identifier :: AlphaNumeric ( s) ) if s == "nightly" => Channel :: Nightly ,
238
+ Some ( x) => return Err ( Error :: UnknownPreReleaseTag ( x. clone ( ) ) ) ,
262
239
} ;
263
240
264
- let llvm_version = if let Some ( & line) = out. get ( idx) {
265
- Some ( expect_prefix ( line, "LLVM version: " ) ?. parse ( ) ?)
266
- } else {
267
- None
241
+ let commit_hash = expect_key_or_unknown ( "commit-hash" , & map) ?;
242
+ let commit_date = expect_key_or_unknown ( "commit-date" , & map) ?;
243
+ let build_date = expect_key_or_unknown ( "build-date" , & map) . ok ( ) . flatten ( ) ;
244
+ let llvm_version = match map. get ( "LLVM version" ) {
245
+ Some ( & v) => Some ( v. parse ( ) ?) ,
246
+ None => None ,
268
247
} ;
269
248
270
249
Ok ( VersionMeta {
@@ -273,12 +252,26 @@ pub fn version_meta_for(verbose_version_string: &str) -> Result<VersionMeta> {
273
252
commit_date,
274
253
build_date,
275
254
channel,
276
- host : host . into ( ) ,
277
- short_version_string : short_version_string . into ( ) ,
255
+ host,
256
+ short_version_string,
278
257
llvm_version,
279
258
} )
280
259
}
281
260
261
+ fn expect_key_or_unknown ( key : & str , map : & HashMap < & str , & str > ) -> Result < Option < String > , Error > {
262
+ match map. get ( key) {
263
+ Some ( & v) if v == "unknown" => Ok ( None ) ,
264
+ Some ( & v) => Ok ( Some ( String :: from ( v) ) ) ,
265
+ None => Err ( Error :: UnexpectedVersionFormat ) ,
266
+ }
267
+ }
268
+
269
+ fn expect_key ( key : & str , map : & HashMap < & str , & str > ) -> Result < String , Error > {
270
+ map. get ( key)
271
+ . map ( |& v| String :: from ( v) )
272
+ . ok_or ( Error :: UnexpectedVersionFormat )
273
+ }
274
+
282
275
/// LLVM Version Parse Error
283
276
#[ derive( Debug ) ]
284
277
pub enum LlvmVersionParseError {
0 commit comments