@@ -46,20 +46,21 @@ mod os {
46
46
}
47
47
48
48
use std:: borrow:: Cow ;
49
- use std:: env;
50
49
use std:: env:: consts:: EXE_SUFFIX ;
51
50
use std:: fs;
52
51
use std:: io:: Write ;
53
52
use std:: path:: { Component , Path , PathBuf , MAIN_SEPARATOR } ;
54
53
use std:: process:: Command ;
55
54
use std:: str:: FromStr ;
55
+ use std:: { env, fmt} ;
56
56
57
57
use anyhow:: { anyhow, Context , Result } ;
58
58
use cfg_if:: cfg_if;
59
59
use same_file:: Handle ;
60
60
use serde:: { Deserialize , Serialize } ;
61
61
62
62
use crate :: currentprocess:: terminalsource;
63
+ use crate :: errors:: RustupError ;
63
64
use crate :: {
64
65
cli:: {
65
66
common:: { self , ignorable_error, report_error, Confirm , PackageUpdate } ,
@@ -1247,29 +1248,49 @@ async fn get_available_rustup_version() -> Result<String> {
1247
1248
let release_file = tempdir. path ( ) . join ( "release-stable.toml" ) ;
1248
1249
utils:: download_file ( & release_file_url, & release_file, None , & |_| ( ) ) . await ?;
1249
1250
let release_toml_str = utils:: read_file ( "rustup release" , & release_file) ?;
1250
- let release_toml: toml:: Value =
1251
- toml:: from_str ( & release_toml_str) . context ( "unable to parse rustup release file" ) ?;
1252
-
1253
- // Check the release file schema.
1254
- let schema = release_toml
1255
- . get ( "schema-version" )
1256
- . ok_or_else ( || anyhow ! ( "no schema key in rustup release file" ) ) ?
1257
- . as_str ( )
1258
- . ok_or_else ( || anyhow ! ( "invalid schema key in rustup release file" ) ) ?;
1259
- if schema != "1" {
1260
- return Err ( anyhow ! ( format!(
1261
- "unknown schema version '{schema}' in rustup release file"
1262
- ) ) ) ;
1251
+ let release_toml = toml:: from_str :: < RustupManifest > ( & release_toml_str)
1252
+ . context ( "unable to parse rustup release file" ) ?;
1253
+
1254
+ Ok ( release_toml. version )
1255
+ }
1256
+
1257
+ #[ derive( Debug , Deserialize , Serialize ) ]
1258
+ #[ serde( rename_all = "kebab-case" ) ]
1259
+ struct RustupManifest {
1260
+ schema_version : SchemaVersion ,
1261
+ version : String ,
1262
+ }
1263
+
1264
+ #[ derive( Clone , Copy , Debug , Default , Deserialize , Eq , PartialEq , Serialize ) ]
1265
+ pub ( crate ) enum SchemaVersion {
1266
+ #[ serde( rename = "1" ) ]
1267
+ #[ default]
1268
+ V1 ,
1269
+ }
1270
+
1271
+ impl SchemaVersion {
1272
+ pub fn as_str ( & self ) -> & ' static str {
1273
+ match self {
1274
+ Self :: V1 => "1" ,
1275
+ }
1263
1276
}
1277
+ }
1264
1278
1265
- // Get the version.
1266
- let available_version = release_toml
1267
- . get ( "version" )
1268
- . ok_or_else ( || anyhow ! ( "no version key in rustup release file" ) ) ?
1269
- . as_str ( )
1270
- . ok_or_else ( || anyhow ! ( "invalid version key in rustup release file" ) ) ?;
1279
+ impl FromStr for SchemaVersion {
1280
+ type Err = RustupError ;
1271
1281
1272
- Ok ( String :: from ( available_version) )
1282
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
1283
+ match s {
1284
+ "1" => Ok ( Self :: V1 ) ,
1285
+ _ => Err ( RustupError :: UnsupportedVersion ( s. to_owned ( ) ) ) ,
1286
+ }
1287
+ }
1288
+ }
1289
+
1290
+ impl fmt:: Display for SchemaVersion {
1291
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1292
+ write ! ( f, "{}" , self . as_str( ) )
1293
+ }
1273
1294
}
1274
1295
1275
1296
pub ( crate ) async fn check_rustup_update ( ) -> Result < ( ) > {
0 commit comments