Skip to content

Commit 36fcd37

Browse files
committed
Let argument parser handle Profile conversion
1 parent 55d4f35 commit 36fcd37

File tree

5 files changed

+60
-72
lines changed

5 files changed

+60
-72
lines changed

src/cli/rustup_mode.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::fmt;
33
use std::io::Write;
44
use std::path::{Path, PathBuf};
55
use std::process::ExitStatus;
6-
use std::str::FromStr;
76

87
use anyhow::{anyhow, Error, Result};
98
use clap::{
@@ -333,8 +332,8 @@ struct UpdateOpts {
333332
)]
334333
toolchain: Vec<PartialToolchainDesc>,
335334

336-
#[arg(long, value_parser = PossibleValuesParser::new(Profile::names()))]
337-
profile: Option<String>,
335+
#[arg(long, value_enum)]
336+
profile: Option<Profile>,
338337

339338
/// Add specific components on installation
340339
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
@@ -518,11 +517,8 @@ enum SetSubcmd {
518517

519518
/// The default components installed with a toolchain
520519
Profile {
521-
#[arg(
522-
default_value = Profile::default_name(),
523-
value_parser = PossibleValuesParser::new(Profile::names()),
524-
)]
525-
profile_name: String,
520+
#[arg(value_enum, default_value_t)]
521+
profile_name: Profile,
526522
},
527523

528524
/// The rustup auto self update mode
@@ -710,7 +706,7 @@ pub async fn main(current_dir: PathBuf) -> Result<utils::ExitCode> {
710706
.set_default_host_triple(host_triple)
711707
.map(|_| utils::ExitCode(0)),
712708
SetSubcmd::Profile { profile_name } => {
713-
cfg.set_profile(&profile_name).map(|_| utils::ExitCode(0))
709+
cfg.set_profile(profile_name).map(|_| utils::ExitCode(0))
714710
}
715711
SetSubcmd::AutoSelfUpdate {
716712
auto_self_update_mode,
@@ -819,8 +815,7 @@ async fn update(cfg: &mut Cfg, opts: UpdateOpts) -> Result<utils::ExitCode> {
819815
&& self_update_mode == SelfUpdateMode::Enable
820816
&& !opts.no_self_update;
821817
let forced = opts.force_non_host;
822-
if let Some(p) = &opts.profile {
823-
let p = Profile::from_str(p)?;
818+
if let Some(p) = opts.profile {
824819
cfg.set_profile_override(p);
825820
}
826821
let cfg = &cfg;

src/cli/self_update.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ use std::{env, fmt};
5656

5757
use anyhow::{anyhow, Context, Result};
5858
use cfg_if::cfg_if;
59+
use clap::ValueEnum;
60+
use itertools::Itertools;
5961
use same_file::Handle;
6062
use serde::{Deserialize, Serialize};
6163

@@ -88,7 +90,7 @@ pub use windows::complete_windows_uninstall;
8890
pub(crate) struct InstallOpts<'a> {
8991
pub default_host_triple: Option<String>,
9092
pub default_toolchain: Option<MaybeOfficialToolchainName>,
91-
pub profile: String,
93+
pub profile: Profile,
9294
pub no_modify_path: bool,
9395
pub no_update_toolchain: bool,
9496
pub components: &'a [&'a str],
@@ -107,7 +109,7 @@ impl<'a> InstallOpts<'a> {
107109
targets,
108110
} = self;
109111

110-
cfg.set_profile(&profile)?;
112+
cfg.set_profile(profile)?;
111113

112114
if let Some(default_host_triple) = &default_host_triple {
113115
// Set host triple now as it will affect resolution of toolchain_str
@@ -202,13 +204,13 @@ impl<'a> InstallOpts<'a> {
202204
.unwrap_or("stable".into()),
203205
)?)?);
204206

205-
self.profile = common::question_str(
207+
self.profile = <Profile as FromStr>::from_str(&common::question_str(
206208
&format!(
207209
"Profile (which tools and data to install)? ({})",
208-
Profile::names().join("/")
210+
Profile::value_variants().iter().join("/"),
209211
),
210-
&self.profile,
211-
)?;
212+
self.profile.as_str(),
213+
)?)?;
212214

213215
self.no_modify_path =
214216
!common::question_bool("Modify PATH variable?", !self.no_modify_path)?;
@@ -1313,7 +1315,7 @@ mod tests {
13131315

13141316
use crate::cli::common;
13151317
use crate::cli::self_update::InstallOpts;
1316-
use crate::dist::dist::PartialToolchainDesc;
1318+
use crate::dist::dist::{PartialToolchainDesc, Profile};
13171319
use crate::test::{test_dir, with_rustup_home, Env};
13181320
use crate::{currentprocess, for_host};
13191321

@@ -1329,8 +1331,8 @@ mod tests {
13291331

13301332
let opts = InstallOpts {
13311333
default_host_triple: None,
1332-
default_toolchain: None, // No toolchain specified
1333-
profile: "default".to_owned(), // default profile
1334+
default_toolchain: None, // No toolchain specified
1335+
profile: Profile::Default, // default profile
13341336
no_modify_path: false,
13351337
components: &[],
13361338
targets: &[],

src/cli/setup_mode.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::path::PathBuf;
22

33
use anyhow::Result;
4-
use clap::{builder::PossibleValuesParser, Parser};
4+
use clap::Parser;
55

66
use crate::{
77
cli::{
@@ -43,12 +43,8 @@ struct RustupInit {
4343
#[arg(long)]
4444
default_toolchain: Option<MaybeOfficialToolchainName>,
4545

46-
#[arg(
47-
long,
48-
value_parser = PossibleValuesParser::new(Profile::names()),
49-
default_value = Profile::default_name(),
50-
)]
51-
profile: String,
46+
#[arg(long, value_enum, default_value_t)]
47+
profile: Profile,
5248

5349
/// Component name to also install
5450
#[arg(short, long, value_delimiter = ',', num_args = 1..)]
@@ -110,7 +106,7 @@ pub async fn main(current_dir: PathBuf) -> Result<utils::ExitCode> {
110106
return Ok(utils::ExitCode(0));
111107
}
112108

113-
if &profile == "complete" {
109+
if profile == Profile::Complete {
114110
warn!("{}", common::WARN_COMPLETE_PROFILE);
115111
}
116112

src/config.rs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -370,19 +370,14 @@ impl Cfg {
370370
Ok(())
371371
}
372372

373-
pub(crate) fn set_profile(&mut self, profile: &str) -> Result<()> {
374-
match Profile::from_str(profile) {
375-
Ok(p) => {
376-
self.profile_override = None;
377-
self.settings_file.with_mut(|s| {
378-
s.profile = Some(p);
379-
Ok(())
380-
})?;
381-
(self.notify_handler)(Notification::SetProfile(profile));
382-
Ok(())
383-
}
384-
Err(err) => Err(err),
385-
}
373+
pub(crate) fn set_profile(&mut self, profile: Profile) -> Result<()> {
374+
self.profile_override = None;
375+
self.settings_file.with_mut(|s| {
376+
s.profile = Some(profile);
377+
Ok(())
378+
})?;
379+
(self.notify_handler)(Notification::SetProfile(profile.as_str()));
380+
Ok(())
386381
}
387382

388383
pub(crate) fn set_auto_self_update(&mut self, mode: &str) -> Result<()> {
@@ -414,13 +409,8 @@ impl Cfg {
414409
if let Some(p) = self.profile_override {
415410
return Ok(p);
416411
}
417-
self.settings_file.with(|s| {
418-
let p = match s.profile {
419-
Some(p) => p,
420-
None => Profile::Default,
421-
};
422-
Ok(p)
423-
})
412+
self.settings_file
413+
.with(|s| Ok(s.profile.unwrap_or_default()))
424414
}
425415

426416
pub(crate) fn get_self_update_mode(&self) -> Result<SelfUpdateMode> {

src/dist/dist.rs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ use std::str::FromStr;
88

99
use anyhow::{anyhow, bail, Context, Result};
1010
use chrono::NaiveDate;
11+
use clap::builder::PossibleValue;
12+
use clap::ValueEnum;
13+
use itertools::Itertools;
1114
use once_cell::sync::Lazy;
1215
use regex::Regex;
1316
use serde::{Deserialize, Serialize};
@@ -611,6 +614,30 @@ pub enum Profile {
611614
Complete,
612615
}
613616

617+
impl Profile {
618+
pub(crate) fn as_str(&self) -> &'static str {
619+
match self {
620+
Self::Minimal => "minimal",
621+
Self::Default => "default",
622+
Self::Complete => "complete",
623+
}
624+
}
625+
}
626+
627+
impl ValueEnum for Profile {
628+
fn value_variants<'a>() -> &'a [Self] {
629+
&[Profile::Minimal, Profile::Default, Profile::Complete]
630+
}
631+
632+
fn to_possible_value(&self) -> Option<PossibleValue> {
633+
Some(PossibleValue::new(self.as_str()))
634+
}
635+
636+
fn from_str(input: &str, _: bool) -> Result<Self, String> {
637+
<Self as FromStr>::from_str(input).map_err(|e| e.to_string())
638+
}
639+
}
640+
614641
impl FromStr for Profile {
615642
type Err = anyhow::Error;
616643

@@ -622,22 +649,12 @@ impl FromStr for Profile {
622649
_ => Err(anyhow!(format!(
623650
"unknown profile name: '{}'; valid profile names are: {}",
624651
name,
625-
valid_profile_names()
652+
Self::value_variants().iter().join(", ")
626653
))),
627654
}
628655
}
629656
}
630657

631-
impl Profile {
632-
pub(crate) fn names() -> &'static [&'static str] {
633-
&["minimal", "default", "complete"]
634-
}
635-
636-
pub(crate) fn default_name() -> &'static str {
637-
"default"
638-
}
639-
}
640-
641658
impl fmt::Display for TargetTriple {
642659
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
643660
self.0.fmt(f)
@@ -680,22 +697,10 @@ impl fmt::Display for ToolchainDesc {
680697

681698
impl fmt::Display for Profile {
682699
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
683-
match *self {
684-
Self::Minimal => write!(f, "minimal"),
685-
Self::Default => write!(f, "default"),
686-
Self::Complete => write!(f, "complete"),
687-
}
700+
write!(f, "{}", self.as_str())
688701
}
689702
}
690703

691-
pub(crate) fn valid_profile_names() -> String {
692-
Profile::names()
693-
.iter()
694-
.map(|s| format!("'{s}'"))
695-
.collect::<Vec<_>>()
696-
.join(", ")
697-
}
698-
699704
// Installs or updates a toolchain from a dist server. If an initial
700705
// install then it will be installed with the default components. If
701706
// an upgrade then all the existing components will be upgraded.

0 commit comments

Comments
 (0)