Skip to content

Commit 57ba98f

Browse files
committed
Use serde to encode/decode rustup manifests
1 parent 7aed7d0 commit 57ba98f

File tree

2 files changed

+43
-22
lines changed

2 files changed

+43
-22
lines changed

src/cli/self_update.rs

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,21 @@ mod os {
4646
}
4747

4848
use std::borrow::Cow;
49-
use std::env;
5049
use std::env::consts::EXE_SUFFIX;
5150
use std::fs;
5251
use std::io::Write;
5352
use std::path::{Component, Path, PathBuf, MAIN_SEPARATOR};
5453
use std::process::Command;
5554
use std::str::FromStr;
55+
use std::{env, fmt};
5656

5757
use anyhow::{anyhow, Context, Result};
5858
use cfg_if::cfg_if;
5959
use same_file::Handle;
6060
use serde::{Deserialize, Serialize};
6161

6262
use crate::currentprocess::terminalsource;
63+
use crate::errors::RustupError;
6364
use crate::{
6465
cli::{
6566
common::{self, ignorable_error, report_error, Confirm, PackageUpdate},
@@ -1247,29 +1248,49 @@ async fn get_available_rustup_version() -> Result<String> {
12471248
let release_file = tempdir.path().join("release-stable.toml");
12481249
utils::download_file(&release_file_url, &release_file, None, &|_| ()).await?;
12491250
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+
}
12631276
}
1277+
}
12641278

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;
12711281

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+
}
12731294
}
12741295

12751296
pub(crate) async fn check_rustup_update() -> Result<()> {

tests/suite/cli_self_upd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ fn update_bad_schema() {
437437
update_setup(&|config, self_dist| {
438438
config.expect_ok(&["rustup-init", "-y", "--no-modify-path"]);
439439
output_release_file(self_dist, "17", "1.1.1");
440-
config.expect_err(&["rustup", "self", "update"], "unknown schema version");
440+
config.expect_err(&["rustup", "self", "update"], "unknown variant");
441441
});
442442
}
443443

0 commit comments

Comments
 (0)