From 59a33dca2b86d6cbd06989488b800a84a5be92da Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 22 Sep 2025 13:54:18 +0200 Subject: [PATCH 1/5] dist: remove temp::Notification variant from dist::Notification --- src/dist/notifications.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/dist/notifications.rs b/src/dist/notifications.rs index d108623b8d..563b1d803a 100644 --- a/src/dist/notifications.rs +++ b/src/dist/notifications.rs @@ -1,5 +1,4 @@ use crate::dist::manifest::Component; -use crate::dist::temp; use crate::dist::{TargetTriple, ToolchainDesc}; use crate::utils::notify::NotificationLevel; use std::fmt::{self, Display}; @@ -10,8 +9,6 @@ use super::manifest::Manifest; #[derive(Debug)] pub enum Notification<'a> { Utils(crate::utils::Notification<'a>), - Temp(temp::Notification<'a>), - Extracting(&'a Path, &'a Path), ComponentAlreadyInstalled(&'a str), CantReadUpdateHash(&'a Path), @@ -45,17 +42,10 @@ impl<'a> From> for Notification<'a> { } } -impl<'a> From> for Notification<'a> { - fn from(n: temp::Notification<'a>) -> Self { - Notification::Temp(n) - } -} - impl Notification<'_> { pub(crate) fn level(&self) -> NotificationLevel { use self::Notification::*; match self { - Temp(n) => n.level(), Utils(n) => n.level(), ChecksumValid(_) | NoUpdateHash(_) @@ -89,7 +79,6 @@ impl Display for Notification<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> { use self::Notification::*; match self { - Temp(n) => n.fmt(f), Utils(n) => n.fmt(f), Extracting(_, _) => write!(f, "extracting..."), ComponentAlreadyInstalled(c) => write!(f, "component {c} is up to date"), From 3d773393245ea16b15046491630dbdc0f73ae991 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 22 Sep 2025 14:46:32 +0200 Subject: [PATCH 2/5] Inline dist::temp::Notification variants into top-level Notification --- src/config.rs | 2 +- src/dist/temp.rs | 58 +++----------------------------------------- src/notifications.rs | 48 ++++++++++++++++++++++++------------ src/settings.rs | 2 +- 4 files changed, 38 insertions(+), 72 deletions(-) diff --git a/src/config.rs b/src/config.rs index 100eae6eb5..bfd5960bfe 100644 --- a/src/config.rs +++ b/src/config.rs @@ -295,7 +295,7 @@ impl<'a> Cfg<'a> { let tmp_cx = temp::Context::new( rustup_dir.join("tmp"), dist_root_server.as_str(), - Box::new(move |n| (notify_clone)(n.into())), + Box::new(move |n| (notify_clone)(n)), ); let dist_root = dist_root_server + "/dist"; diff --git a/src/dist/temp.rs b/src/dist/temp.rs index 72b3677a42..7803bd932d 100644 --- a/src/dist/temp.rs +++ b/src/dist/temp.rs @@ -1,13 +1,11 @@ -use std::fmt::{self, Display}; -use std::fs; -use std::io; -use std::ops; use std::path::{Path, PathBuf}; +use std::{fmt, fs, ops}; pub(crate) use anyhow::{Context as _, Result}; use thiserror::Error as ThisError; -use crate::utils::{self, notify::NotificationLevel, raw}; +use crate::notifications::Notification; +use crate::utils::{self, raw}; #[derive(Debug, ThisError)] pub(crate) enum CreatingError { @@ -68,56 +66,6 @@ impl Drop for File<'_> { } } -#[derive(Debug)] -pub enum Notification<'a> { - CreatingRoot(&'a Path), - CreatingFile(&'a Path), - CreatingDirectory(&'a Path), - FileDeletion(&'a Path, io::Result<()>), - DirectoryDeletion(&'a Path, io::Result<()>), -} - -impl Notification<'_> { - pub(crate) fn level(&self) -> NotificationLevel { - use self::Notification::*; - match self { - CreatingRoot(_) | CreatingFile(_) | CreatingDirectory(_) => NotificationLevel::Debug, - FileDeletion(_, result) | DirectoryDeletion(_, result) => { - if result.is_ok() { - NotificationLevel::Debug - } else { - NotificationLevel::Warn - } - } - } - } -} - -impl Display for Notification<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> { - use self::Notification::*; - match self { - CreatingRoot(path) => write!(f, "creating temp root: {}", path.display()), - CreatingFile(path) => write!(f, "creating temp file: {}", path.display()), - CreatingDirectory(path) => write!(f, "creating temp directory: {}", path.display()), - FileDeletion(path, result) => { - if result.is_ok() { - write!(f, "deleted temp file: {}", path.display()) - } else { - write!(f, "could not delete temp file: {}", path.display()) - } - } - DirectoryDeletion(path, result) => { - if result.is_ok() { - write!(f, "deleted temp directory: {}", path.display()) - } else { - write!(f, "could not delete temp directory: {}", path.display()) - } - } - } - } -} - pub struct Context { root_directory: PathBuf, pub dist_server: String, diff --git a/src/notifications.rs b/src/notifications.rs index a21468ce33..a97a3995ad 100644 --- a/src/notifications.rs +++ b/src/notifications.rs @@ -1,19 +1,19 @@ use std::fmt::{self, Display}; +use std::io; use std::path::{Path, PathBuf}; use crate::settings::MetadataVersion; -use crate::{ - dist::{ToolchainDesc, temp}, - toolchain::ToolchainName, - utils::notify::NotificationLevel, -}; +use crate::{dist::ToolchainDesc, toolchain::ToolchainName, utils::notify::NotificationLevel}; #[derive(Debug)] -pub(crate) enum Notification<'a> { +pub enum Notification<'a> { Install(crate::dist::Notification<'a>), Utils(crate::utils::Notification<'a>), - Temp(temp::Notification<'a>), - + CreatingRoot(&'a Path), + CreatingFile(&'a Path), + CreatingDirectory(&'a Path), + FileDeletion(&'a Path, io::Result<()>), + DirectoryDeletion(&'a Path, io::Result<()>), SetAutoInstall(&'a str), SetDefaultToolchain(Option<&'a ToolchainName>), SetOverrideToolchain(&'a Path, &'a str), @@ -50,11 +50,6 @@ impl<'a> From> for Notification<'a> { Notification::Utils(n) } } -impl<'a> From> for Notification<'a> { - fn from(n: temp::Notification<'a>) -> Self { - Notification::Temp(n) - } -} impl Notification<'_> { pub(crate) fn level(&self) -> NotificationLevel { @@ -62,7 +57,14 @@ impl Notification<'_> { match self { Install(n) => n.level(), Utils(n) => n.level(), - Temp(n) => n.level(), + CreatingRoot(_) | CreatingFile(_) | CreatingDirectory(_) => NotificationLevel::Debug, + FileDeletion(_, result) | DirectoryDeletion(_, result) => { + if result.is_ok() { + NotificationLevel::Debug + } else { + NotificationLevel::Warn + } + } ToolchainDirectory(_) | LookingForToolchain(_) | InstallingToolchain(_) @@ -92,7 +94,23 @@ impl Display for Notification<'_> { match self { Install(n) => n.fmt(f), Utils(n) => n.fmt(f), - Temp(n) => n.fmt(f), + CreatingRoot(path) => write!(f, "creating temp root: {}", path.display()), + CreatingFile(path) => write!(f, "creating temp file: {}", path.display()), + CreatingDirectory(path) => write!(f, "creating temp directory: {}", path.display()), + FileDeletion(path, result) => { + if result.is_ok() { + write!(f, "deleted temp file: {}", path.display()) + } else { + write!(f, "could not delete temp file: {}", path.display()) + } + } + DirectoryDeletion(path, result) => { + if result.is_ok() { + write!(f, "deleted temp directory: {}", path.display()) + } else { + write!(f, "could not delete temp directory: {}", path.display()) + } + } SetAutoInstall(auto) => write!(f, "auto install set to '{auto}'"), SetDefaultToolchain(None) => write!(f, "default toolchain unset"), SetDefaultToolchain(Some(name)) => write!(f, "default toolchain set to '{name}'"), diff --git a/src/settings.rs b/src/settings.rs index 9b93b14079..44305d727a 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -147,7 +147,7 @@ impl Settings { } #[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] -pub(crate) enum MetadataVersion { +pub enum MetadataVersion { #[serde(rename = "2")] V2, #[serde(rename = "12")] From 306670e590c9f2a5c633b5b7f989d6a27b68c537 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 22 Sep 2025 15:02:53 +0200 Subject: [PATCH 3/5] Inline dist Notification variants into top-level Notification --- src/cli/common.rs | 7 +- src/cli/download_tracker.rs | 16 +-- src/config.rs | 2 +- src/dist/component/tests.rs | 76 +++++-------- src/dist/component/transaction.rs | 2 +- src/dist/download.rs | 2 +- src/dist/manifestation.rs | 2 +- src/dist/manifestation/tests.rs | 11 +- src/dist/mod.rs | 9 +- src/dist/notifications.rs | 176 ------------------------------ src/install.rs | 16 +-- src/notifications.rs | 153 ++++++++++++++++++++++++-- src/toolchain.rs | 2 +- src/toolchain/distributable.rs | 27 ++--- tests/suite/dist_install.rs | 2 +- 15 files changed, 207 insertions(+), 296 deletions(-) delete mode 100644 src/dist/notifications.rs diff --git a/src/cli/common.rs b/src/cli/common.rs index 1e5abced4b..3deb44813e 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -16,7 +16,7 @@ use tracing_subscriber::{EnvFilter, Registry, reload::Handle}; use crate::{ cli::download_tracker::DownloadTracker, config::Cfg, - dist::{TargetTriple, ToolchainDesc, notifications as dist_notifications}, + dist::{TargetTriple, ToolchainDesc}, errors::RustupError, install::UpdateStatus, notifications::Notification, @@ -139,10 +139,7 @@ impl Notifier { return; } - if let Notification::Install(dist_notifications::Notification::Utils( - util_notifications::Notification::SetDefaultBufferSize(_), - )) = &n - { + if let Notification::Utils(util_notifications::Notification::SetDefaultBufferSize(_)) = &n { if *self.ram_notice_shown.borrow() { return; } else { diff --git a/src/cli/download_tracker.rs b/src/cli/download_tracker.rs index c9e1d2e55b..53bff50628 100644 --- a/src/cli/download_tracker.rs +++ b/src/cli/download_tracker.rs @@ -2,7 +2,6 @@ use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle}; use std::collections::HashMap; use std::time::{Duration, Instant}; -use crate::dist::Notification as In; use crate::notifications::Notification; use crate::process::Process; use crate::utils::Notification as Un; @@ -40,36 +39,33 @@ impl DownloadTracker { pub(crate) fn handle_notification(&mut self, n: &Notification<'_>) -> bool { match *n { - Notification::Install(In::Utils(Un::DownloadContentLengthReceived( - content_len, - url, - ))) => { + Notification::Utils(Un::DownloadContentLengthReceived(content_len, url)) => { if let Some(url) = url { self.content_length_received(content_len, url); } true } - Notification::Install(In::Utils(Un::DownloadDataReceived(data, url))) => { + Notification::Utils(Un::DownloadDataReceived(data, url)) => { if let Some(url) = url { self.data_received(data.len(), url); } true } - Notification::Install(In::Utils(Un::DownloadFinished(url))) => { + Notification::Utils(Un::DownloadFinished(url)) => { if let Some(url) = url { self.download_finished(url); } true } - Notification::Install(In::Utils(Un::DownloadFailed(url))) => { + Notification::Utils(Un::DownloadFailed(url)) => { self.download_failed(url); false } - Notification::Install(In::DownloadingComponent(component, _, _, url)) => { + Notification::DownloadingComponent(component, _, _, url) => { self.create_progress_bar(component.to_owned(), url.to_owned()); true } - Notification::Install(In::RetryingDownload(url)) => { + Notification::RetryingDownload(url) => { self.retrying_download(url); true } diff --git a/src/config.rs b/src/config.rs index bfd5960bfe..fbb173d0cb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -330,7 +330,7 @@ impl<'a> Cfg<'a> { /// construct a download configuration pub(crate) fn download_cfg( &'a self, - notify_handler: &'a dyn Fn(crate::dist::Notification<'_>), + notify_handler: &'a dyn Fn(Notification<'_>), ) -> DownloadCfg<'a> { DownloadCfg { dist_root: &self.dist_root_url, diff --git a/src/dist/component/tests.rs b/src/dist/component/tests.rs index 24acd5ddf0..dcc830257f 100644 --- a/src/dist/component/tests.rs +++ b/src/dist/component/tests.rs @@ -3,7 +3,6 @@ use std::io::Write; use std::path::PathBuf; use crate::dist::DEFAULT_DIST_SERVER; -use crate::dist::Notification; use crate::dist::component::Transaction; use crate::dist::prefix::InstallPrefix; use crate::dist::temp; @@ -24,9 +23,8 @@ fn add_file() { Box::new(|_| ()), ); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let mut file = tx.add_file("c", PathBuf::from("foo/bar")).unwrap(); write!(file, "test").unwrap(); @@ -53,9 +51,8 @@ fn add_file_then_rollback() { Box::new(|_| ()), ); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); tx.add_file("c", PathBuf::from("foo/bar")).unwrap(); drop(tx); @@ -76,9 +73,8 @@ fn add_file_that_exists() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); fs::create_dir_all(prefixdir.path().join("foo")).unwrap(); utils::write_file("", &prefixdir.path().join("foo/bar"), "").unwrap(); @@ -108,9 +104,8 @@ fn copy_file() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let srcpath = srcdir.path().join("bar"); utils::write_file("", &srcpath, "").unwrap(); @@ -136,9 +131,8 @@ fn copy_file_then_rollback() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let srcpath = srcdir.path().join("bar"); utils::write_file("", &srcpath, "").unwrap(); @@ -164,9 +158,8 @@ fn copy_file_that_exists() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let srcpath = srcdir.path().join("bar"); utils::write_file("", &srcpath, "").unwrap(); @@ -201,9 +194,8 @@ fn copy_dir() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let srcpath1 = srcdir.path().join("foo"); let srcpath2 = srcdir.path().join("bar/baz"); @@ -236,9 +228,8 @@ fn copy_dir_then_rollback() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let srcpath1 = srcdir.path().join("foo"); let srcpath2 = srcdir.path().join("bar/baz"); @@ -271,9 +262,8 @@ fn copy_dir_that_exists() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); fs::create_dir_all(prefix.path().join("a")).unwrap(); @@ -303,9 +293,8 @@ fn remove_file() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let filepath = prefixdir.path().join("foo"); utils::write_file("", &filepath, "").unwrap(); @@ -329,9 +318,8 @@ fn remove_file_then_rollback() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let filepath = prefixdir.path().join("foo"); utils::write_file("", &filepath, "").unwrap(); @@ -355,9 +343,8 @@ fn remove_file_that_not_exists() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let err = tx.remove_file("c", PathBuf::from("foo")).unwrap_err(); @@ -383,9 +370,8 @@ fn remove_dir() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let filepath = prefixdir.path().join("foo/bar"); fs::create_dir_all(filepath.parent().unwrap()).unwrap(); @@ -410,9 +396,8 @@ fn remove_dir_then_rollback() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let filepath = prefixdir.path().join("foo/bar"); fs::create_dir_all(filepath.parent().unwrap()).unwrap(); @@ -437,9 +422,8 @@ fn remove_dir_that_not_exists() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let err = tx.remove_dir("c", PathBuf::from("foo")).unwrap_err(); @@ -465,9 +449,8 @@ fn write_file() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let content = "hi".to_string(); tx.write_file("c", PathBuf::from("foo/bar"), content.clone()) @@ -493,9 +476,8 @@ fn write_file_then_rollback() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let content = "hi".to_string(); tx.write_file("c", PathBuf::from("foo/bar"), content) @@ -518,9 +500,8 @@ fn write_file_that_exists() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let content = "hi".to_string(); utils_raw::write_file(&prefix.path().join("a"), &content).unwrap(); @@ -550,9 +531,8 @@ fn modify_file_that_not_exists() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); tx.modify_file(PathBuf::from("foo/bar")).unwrap(); tx.commit(); @@ -575,9 +555,8 @@ fn modify_file_that_exists() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let path = prefix.path().join("foo"); utils_raw::write_file(&path, "wow").unwrap(); @@ -600,9 +579,8 @@ fn modify_file_that_not_exists_then_rollback() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); tx.modify_file(PathBuf::from("foo/bar")).unwrap(); drop(tx); @@ -623,9 +601,8 @@ fn modify_file_that_exists_then_rollback() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let path = prefix.path().join("foo"); utils_raw::write_file(&path, "wow").unwrap(); @@ -651,9 +628,8 @@ fn modify_twice_then_rollback() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); let path = prefix.path().join("foo"); utils_raw::write_file(&path, "wow").unwrap(); @@ -679,9 +655,8 @@ fn do_multiple_op_transaction(rollback: bool) { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); // copy_file let relpath1 = PathBuf::from("bin/rustc"); @@ -781,9 +756,8 @@ fn rollback_failure_keeps_going() { let prefix = InstallPrefix::from(prefixdir.path()); - let notify = |_: Notification<'_>| (); let tp = TestProcess::default(); - let mut tx = Transaction::new(prefix.clone(), &tmp_cx, ¬ify, &tp.process); + let mut tx = Transaction::new(prefix.clone(), &tmp_cx, &|_| (), &tp.process); write!(tx.add_file("", PathBuf::from("foo")).unwrap(), "").unwrap(); write!(tx.add_file("", PathBuf::from("bar")).unwrap(), "").unwrap(); diff --git a/src/dist/component/transaction.rs b/src/dist/component/transaction.rs index 41ac83b125..4252de8a02 100644 --- a/src/dist/component/transaction.rs +++ b/src/dist/component/transaction.rs @@ -14,10 +14,10 @@ use std::path::{Path, PathBuf}; use anyhow::{Context, Result, anyhow}; -use crate::dist::notifications::*; use crate::dist::prefix::InstallPrefix; use crate::dist::temp; use crate::errors::*; +use crate::notifications::Notification; use crate::process::Process; use crate::utils; diff --git a/src/dist/download.rs b/src/dist/download.rs index 38a8e0f125..ab004fa85f 100644 --- a/src/dist/download.rs +++ b/src/dist/download.rs @@ -6,11 +6,11 @@ use anyhow::{Context, Result, anyhow}; use sha2::{Digest, Sha256}; use url::Url; -use crate::dist::notifications::*; use crate::dist::temp; use crate::download::download_file; use crate::download::download_file_with_resume; use crate::errors::*; +use crate::notifications::Notification; use crate::process::Process; use crate::utils; diff --git a/src/dist/manifestation.rs b/src/dist/manifestation.rs index c27c1c2059..a84cc40747 100644 --- a/src/dist/manifestation.rs +++ b/src/dist/manifestation.rs @@ -19,11 +19,11 @@ use crate::dist::component::{ use crate::dist::config::Config; use crate::dist::download::{DownloadCfg, File}; use crate::dist::manifest::{Component, CompressionKind, HashedBinary, Manifest, TargetedPackage}; -use crate::dist::notifications::*; use crate::dist::prefix::InstallPrefix; use crate::dist::temp; use crate::dist::{DEFAULT_DIST_SERVER, Profile, TargetTriple}; use crate::errors::RustupError; +use crate::notifications::Notification; use crate::process::Process; use crate::utils; diff --git a/src/dist/manifestation/tests.rs b/src/dist/manifestation/tests.rs index 233ccb2df9..392fa4781a 100644 --- a/src/dist/manifestation/tests.rs +++ b/src/dist/manifestation/tests.rs @@ -16,21 +16,16 @@ use url::Url; use crate::{ dist::{ - DEFAULT_DIST_SERVER, Notification, Profile, TargetTriple, ToolchainDesc, + DEFAULT_DIST_SERVER, Profile, TargetTriple, ToolchainDesc, download::DownloadCfg, manifest::{Component, Manifest}, manifestation::{Changes, Manifestation, UpdateStatus}, prefix::InstallPrefix, temp, - }, - download::download_file, - errors::RustupError, - process::TestProcess, - test::{ + }, download::download_file, errors::RustupError, notifications::Notification, process::TestProcess, test::{ dist::*, mock::{MockComponentBuilder, MockFile, MockInstallerBuilder}, - }, - utils::{self, raw as utils_raw}, + }, utils::{self, raw as utils_raw} }; const SHA256_HASH_LEN: usize = 64; diff --git a/src/dist/mod.rs b/src/dist/mod.rs index 516369d17f..931932019c 100644 --- a/src/dist/mod.rs +++ b/src/dist/mod.rs @@ -14,11 +14,7 @@ use thiserror::Error as ThisError; use tracing::{info, warn}; use crate::{ - config::{Cfg, dist_root_server}, - errors::RustupError, - process::Process, - toolchain::ToolchainName, - utils, + config::{Cfg, dist_root_server}, errors::RustupError, notifications::Notification, process::Process, toolchain::ToolchainName, utils }; pub mod component; @@ -33,9 +29,6 @@ use manifest::{Component, Manifest as ManifestV2}; pub mod manifestation; use manifestation::{Changes, Manifestation, UpdateStatus}; -pub(crate) mod notifications; -pub use notifications::Notification; - pub mod prefix; use prefix::InstallPrefix; diff --git a/src/dist/notifications.rs b/src/dist/notifications.rs deleted file mode 100644 index 563b1d803a..0000000000 --- a/src/dist/notifications.rs +++ /dev/null @@ -1,176 +0,0 @@ -use crate::dist::manifest::Component; -use crate::dist::{TargetTriple, ToolchainDesc}; -use crate::utils::notify::NotificationLevel; -use std::fmt::{self, Display}; -use std::path::Path; - -use super::manifest::Manifest; - -#[derive(Debug)] -pub enum Notification<'a> { - Utils(crate::utils::Notification<'a>), - Extracting(&'a Path, &'a Path), - ComponentAlreadyInstalled(&'a str), - CantReadUpdateHash(&'a Path), - NoUpdateHash(&'a Path), - ChecksumValid(&'a str), - FileAlreadyDownloaded, - CachedFileChecksumFailed, - RollingBack, - ExtensionNotInstalled(&'a str), - NonFatalError(&'a anyhow::Error), - MissingInstalledComponent(&'a str), - /// The URL of the download is passed as the last argument, to allow us to track concurrent downloads. - DownloadingComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>, &'a str), - InstallingComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>), - RemovingComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>), - RemovingOldComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>), - DownloadingManifest(&'a str), - DownloadedManifest(&'a str, Option<&'a str>), - DownloadingLegacyManifest, - SkippingNightlyMissingComponent(&'a ToolchainDesc, &'a Manifest, &'a [Component]), - ForcingUnavailableComponent(&'a str), - ComponentUnavailable(&'a str, Option<&'a TargetTriple>), - StrayHash(&'a Path), - SignatureInvalid(&'a str), - RetryingDownload(&'a str), -} - -impl<'a> From> for Notification<'a> { - fn from(n: crate::utils::Notification<'a>) -> Self { - Notification::Utils(n) - } -} - -impl Notification<'_> { - pub(crate) fn level(&self) -> NotificationLevel { - use self::Notification::*; - match self { - Utils(n) => n.level(), - ChecksumValid(_) - | NoUpdateHash(_) - | FileAlreadyDownloaded - | DownloadingLegacyManifest => NotificationLevel::Debug, - Extracting(_, _) - | DownloadingComponent(_, _, _, _) - | InstallingComponent(_, _, _) - | RemovingComponent(_, _, _) - | RemovingOldComponent(_, _, _) - | ComponentAlreadyInstalled(_) - | RollingBack - | DownloadingManifest(_) - | SkippingNightlyMissingComponent(_, _, _) - | RetryingDownload(_) - | DownloadedManifest(_, _) => NotificationLevel::Info, - CantReadUpdateHash(_) - | ExtensionNotInstalled(_) - | MissingInstalledComponent(_) - | CachedFileChecksumFailed - | ComponentUnavailable(_, _) - | ForcingUnavailableComponent(_) - | StrayHash(_) => NotificationLevel::Warn, - NonFatalError(_) => NotificationLevel::Error, - SignatureInvalid(_) => NotificationLevel::Warn, - } - } -} - -impl Display for Notification<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> { - use self::Notification::*; - match self { - Utils(n) => n.fmt(f), - Extracting(_, _) => write!(f, "extracting..."), - ComponentAlreadyInstalled(c) => write!(f, "component {c} is up to date"), - CantReadUpdateHash(path) => write!( - f, - "can't read update hash file: '{}', can't skip update...", - path.display() - ), - NoUpdateHash(path) => write!(f, "no update hash at: '{}'", path.display()), - ChecksumValid(_) => write!(f, "checksum passed"), - FileAlreadyDownloaded => write!(f, "reusing previously downloaded file"), - CachedFileChecksumFailed => write!(f, "bad checksum for cached download"), - RollingBack => write!(f, "rolling back changes"), - ExtensionNotInstalled(c) => write!(f, "extension '{c}' was not installed"), - NonFatalError(e) => write!(f, "{e}"), - MissingInstalledComponent(c) => { - write!(f, "during uninstall component {c} was not found") - } - DownloadingComponent(c, h, t, _) => { - if Some(h) == t.as_ref() || t.is_none() { - write!(f, "downloading component '{c}'") - } else { - write!(f, "downloading component '{}' for '{}'", c, t.unwrap()) - } - } - InstallingComponent(c, h, t) => { - if Some(h) == t.as_ref() || t.is_none() { - write!(f, "installing component '{c}'") - } else { - write!(f, "installing component '{}' for '{}'", c, t.unwrap()) - } - } - RemovingComponent(c, h, t) => { - if Some(h) == t.as_ref() || t.is_none() { - write!(f, "removing component '{c}'") - } else { - write!(f, "removing component '{}' for '{}'", c, t.unwrap()) - } - } - RemovingOldComponent(c, h, t) => { - if Some(h) == t.as_ref() || t.is_none() { - write!(f, "removing previous version of component '{c}'") - } else { - write!( - f, - "removing previous version of component '{}' for '{}'", - c, - t.unwrap() - ) - } - } - DownloadingManifest(t) => write!(f, "syncing channel updates for '{t}'"), - DownloadedManifest(date, Some(version)) => { - write!(f, "latest update on {date}, rust version {version}") - } - DownloadedManifest(date, None) => { - write!(f, "latest update on {date}, no rust version") - } - DownloadingLegacyManifest => write!(f, "manifest not found. trying legacy manifest"), - ComponentUnavailable(pkg, toolchain) => { - if let Some(tc) = toolchain { - write!(f, "component '{pkg}' is not available on target '{tc}'") - } else { - write!(f, "component '{pkg}' is not available") - } - } - StrayHash(path) => write!( - f, - "removing stray hash found at '{}' in order to continue", - path.display() - ), - SkippingNightlyMissingComponent(toolchain, manifest, components) => write!( - f, - "skipping nightly which is missing installed component{} '{}'", - if components.len() > 1 { "s" } else { "" }, - components - .iter() - .map(|component| { - if component.target.as_ref() != Some(&toolchain.target) { - component.name(manifest) - } else { - component.short_name(manifest) - } - }) - .collect::>() - .join("', '") - ), - ForcingUnavailableComponent(component) => { - write!(f, "Force-skipping unavailable component '{component}'") - } - SignatureInvalid(url) => write!(f, "Signature verification failed for '{url}'"), - RetryingDownload(url) => write!(f, "retrying download for '{url}'"), - } - } -} diff --git a/src/install.rs b/src/install.rs index a7e48a6c4a..22d52fecbf 100644 --- a/src/install.rs +++ b/src/install.rs @@ -6,9 +6,9 @@ use anyhow::Result; use crate::{ config::Cfg, - dist::{self, DistOptions, Notification, prefix::InstallPrefix}, + dist::{self, DistOptions, prefix::InstallPrefix}, errors::RustupError, - notifications::Notification as RootNotification, + notifications::Notification, toolchain::{CustomToolchainName, LocalToolchainName, Toolchain}, utils, }; @@ -51,20 +51,20 @@ impl InstallMethod<'_> { | InstallMethod::Dist(DistOptions { old_date_version: None, .. - }) => nh(RootNotification::InstallingToolchain(&self.dest_basename())), - _ => nh(RootNotification::UpdatingToolchain(&self.dest_basename())), + }) => nh(Notification::InstallingToolchain(&self.dest_basename())), + _ => nh(Notification::UpdatingToolchain(&self.dest_basename())), } - nh(RootNotification::ToolchainDirectory(&self.dest_path())); - let updated = self.run(&self.dest_path(), &|n| nh(n.into())).await?; + nh(Notification::ToolchainDirectory(&self.dest_path())); + let updated = self.run(&self.dest_path(), &|n| nh(n)).await?; let status = match updated { false => { - nh(RootNotification::UpdateHashMatches); + nh(Notification::UpdateHashMatches); UpdateStatus::Unchanged } true => { - nh(RootNotification::InstalledToolchain(&self.dest_basename())); + nh(Notification::InstalledToolchain(&self.dest_basename())); match self { InstallMethod::Dist(DistOptions { old_date_version: Some((_, v)), diff --git a/src/notifications.rs b/src/notifications.rs index a97a3995ad..4362c63485 100644 --- a/src/notifications.rs +++ b/src/notifications.rs @@ -2,12 +2,38 @@ use std::fmt::{self, Display}; use std::io; use std::path::{Path, PathBuf}; +use crate::dist::TargetTriple; +use crate::dist::manifest::{Component, Manifest}; use crate::settings::MetadataVersion; use crate::{dist::ToolchainDesc, toolchain::ToolchainName, utils::notify::NotificationLevel}; #[derive(Debug)] pub enum Notification<'a> { - Install(crate::dist::Notification<'a>), + Extracting(&'a Path, &'a Path), + ComponentAlreadyInstalled(&'a str), + CantReadUpdateHash(&'a Path), + NoUpdateHash(&'a Path), + ChecksumValid(&'a str), + FileAlreadyDownloaded, + CachedFileChecksumFailed, + RollingBack, + ExtensionNotInstalled(&'a str), + NonFatalError(&'a anyhow::Error), + MissingInstalledComponent(&'a str), + /// The URL of the download is passed as the last argument, to allow us to track concurrent downloads. + DownloadingComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>, &'a str), + InstallingComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>), + RemovingComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>), + RemovingOldComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>), + DownloadingManifest(&'a str), + DownloadedManifest(&'a str, Option<&'a str>), + DownloadingLegacyManifest, + SkippingNightlyMissingComponent(&'a ToolchainDesc, &'a Manifest, &'a [Component]), + ForcingUnavailableComponent(&'a str), + ComponentUnavailable(&'a str, Option<&'a TargetTriple>), + StrayHash(&'a Path), + SignatureInvalid(&'a str), + RetryingDownload(&'a str), Utils(crate::utils::Notification<'a>), CreatingRoot(&'a Path), CreatingFile(&'a Path), @@ -31,7 +57,6 @@ pub enum Notification<'a> { UpgradingMetadata(MetadataVersion, MetadataVersion), MetadataUpgradeNotNeeded(MetadataVersion), ReadMetadataVersion(MetadataVersion), - NonFatalError(&'a anyhow::Error), UpgradeRemovesToolchains, /// Both `rust-toolchain` and `rust-toolchain.toml` exist within a directory DuplicateToolchainFile { @@ -40,11 +65,6 @@ pub enum Notification<'a> { }, } -impl<'a> From> for Notification<'a> { - fn from(n: crate::dist::Notification<'a>) -> Self { - Notification::Install(n) - } -} impl<'a> From> for Notification<'a> { fn from(n: crate::utils::Notification<'a>) -> Self { Notification::Utils(n) @@ -55,7 +75,30 @@ impl Notification<'_> { pub(crate) fn level(&self) -> NotificationLevel { use self::Notification::*; match self { - Install(n) => n.level(), + ChecksumValid(_) + | NoUpdateHash(_) + | FileAlreadyDownloaded + | DownloadingLegacyManifest => NotificationLevel::Debug, + Extracting(_, _) + | DownloadingComponent(_, _, _, _) + | InstallingComponent(_, _, _) + | RemovingComponent(_, _, _) + | RemovingOldComponent(_, _, _) + | ComponentAlreadyInstalled(_) + | RollingBack + | DownloadingManifest(_) + | SkippingNightlyMissingComponent(_, _, _) + | RetryingDownload(_) + | DownloadedManifest(_, _) => NotificationLevel::Info, + CantReadUpdateHash(_) + | ExtensionNotInstalled(_) + | MissingInstalledComponent(_) + | CachedFileChecksumFailed + | ComponentUnavailable(_, _) + | ForcingUnavailableComponent(_) + | StrayHash(_) => NotificationLevel::Warn, + NonFatalError(_) => NotificationLevel::Error, + SignatureInvalid(_) => NotificationLevel::Warn, Utils(n) => n.level(), CreatingRoot(_) | CreatingFile(_) | CreatingDirectory(_) => NotificationLevel::Debug, FileDeletion(_, result) | DirectoryDeletion(_, result) => { @@ -82,7 +125,6 @@ impl Notification<'_> { | UninstalledToolchain(_) | UpgradingMetadata(_, _) | MetadataUpgradeNotNeeded(_) => NotificationLevel::Info, - NonFatalError(_) => NotificationLevel::Error, UpgradeRemovesToolchains | DuplicateToolchainFile { .. } => NotificationLevel::Warn, } } @@ -92,7 +134,97 @@ impl Display for Notification<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> { use self::Notification::*; match self { - Install(n) => n.fmt(f), + Extracting(_, _) => write!(f, "extracting..."), + ComponentAlreadyInstalled(c) => write!(f, "component {c} is up to date"), + CantReadUpdateHash(path) => write!( + f, + "can't read update hash file: '{}', can't skip update...", + path.display() + ), + NoUpdateHash(path) => write!(f, "no update hash at: '{}'", path.display()), + ChecksumValid(_) => write!(f, "checksum passed"), + FileAlreadyDownloaded => write!(f, "reusing previously downloaded file"), + CachedFileChecksumFailed => write!(f, "bad checksum for cached download"), + RollingBack => write!(f, "rolling back changes"), + ExtensionNotInstalled(c) => write!(f, "extension '{c}' was not installed"), + NonFatalError(e) => write!(f, "{e}"), + MissingInstalledComponent(c) => { + write!(f, "during uninstall component {c} was not found") + } + DownloadingComponent(c, h, t, _) => { + if Some(h) == t.as_ref() || t.is_none() { + write!(f, "downloading component '{c}'") + } else { + write!(f, "downloading component '{}' for '{}'", c, t.unwrap()) + } + } + InstallingComponent(c, h, t) => { + if Some(h) == t.as_ref() || t.is_none() { + write!(f, "installing component '{c}'") + } else { + write!(f, "installing component '{}' for '{}'", c, t.unwrap()) + } + } + RemovingComponent(c, h, t) => { + if Some(h) == t.as_ref() || t.is_none() { + write!(f, "removing component '{c}'") + } else { + write!(f, "removing component '{}' for '{}'", c, t.unwrap()) + } + } + RemovingOldComponent(c, h, t) => { + if Some(h) == t.as_ref() || t.is_none() { + write!(f, "removing previous version of component '{c}'") + } else { + write!( + f, + "removing previous version of component '{}' for '{}'", + c, + t.unwrap() + ) + } + } + DownloadingManifest(t) => write!(f, "syncing channel updates for '{t}'"), + DownloadedManifest(date, Some(version)) => { + write!(f, "latest update on {date}, rust version {version}") + } + DownloadedManifest(date, None) => { + write!(f, "latest update on {date}, no rust version") + } + DownloadingLegacyManifest => write!(f, "manifest not found. trying legacy manifest"), + ComponentUnavailable(pkg, toolchain) => { + if let Some(tc) = toolchain { + write!(f, "component '{pkg}' is not available on target '{tc}'") + } else { + write!(f, "component '{pkg}' is not available") + } + } + StrayHash(path) => write!( + f, + "removing stray hash found at '{}' in order to continue", + path.display() + ), + SkippingNightlyMissingComponent(toolchain, manifest, components) => write!( + f, + "skipping nightly which is missing installed component{} '{}'", + if components.len() > 1 { "s" } else { "" }, + components + .iter() + .map(|component| { + if component.target.as_ref() != Some(&toolchain.target) { + component.name(manifest) + } else { + component.short_name(manifest) + } + }) + .collect::>() + .join("', '") + ), + ForcingUnavailableComponent(component) => { + write!(f, "Force-skipping unavailable component '{component}'") + } + SignatureInvalid(url) => write!(f, "Signature verification failed for '{url}'"), + RetryingDownload(url) => write!(f, "retrying download for '{url}'"), Utils(n) => n.fmt(f), CreatingRoot(path) => write!(f, "creating temp root: {}", path.display()), CreatingFile(path) => write!(f, "creating temp file: {}", path.display()), @@ -139,7 +271,6 @@ impl Display for Notification<'_> { write!(f, "nothing to upgrade: metadata version is already '{ver}'") } ReadMetadataVersion(ver) => write!(f, "read metadata version: '{ver}'"), - NonFatalError(e) => write!(f, "{e}"), UpgradeRemovesToolchains => write!( f, "this upgrade will remove all existing toolchains. you will need to reinstall them" diff --git a/src/toolchain.rs b/src/toolchain.rs index 30ae066fd7..e905918db1 100644 --- a/src/toolchain.rs +++ b/src/toolchain.rs @@ -555,7 +555,7 @@ impl<'a> Toolchain<'a> { utils::ensure_file_removed(name, &path)? } InstalledPath::Dir { path } => { - install::uninstall(path, &|n| (cfg.notify_handler)(n.into()))? + install::uninstall(path, &|n| (cfg.notify_handler)(n))? } } } diff --git a/src/toolchain/distributable.rs b/src/toolchain/distributable.rs index 94a84e0c62..6d91312e26 100644 --- a/src/toolchain/distributable.rs +++ b/src/toolchain/distributable.rs @@ -109,10 +109,10 @@ impl<'a> DistributableToolchain<'a> { remove_components: vec![], }; - let notify_handler = - &|n: crate::dist::Notification<'_>| (self.toolchain.cfg.notify_handler)(n.into()); - let download_cfg = self.toolchain.cfg.download_cfg(¬ify_handler); - + let download_cfg = self + .toolchain + .cfg + .download_cfg(&*self.toolchain.cfg.notify_handler); manifestation .update( &manifest, @@ -355,7 +355,7 @@ impl<'a> DistributableToolchain<'a> { toolchain, profile, update_hash, - dl_cfg: cfg.download_cfg(&|n| (cfg.notify_handler)(n.into())), + dl_cfg: cfg.download_cfg(&|n| (cfg.notify_handler)(n)), force, allow_downgrade: false, exists: false, @@ -413,7 +413,7 @@ impl<'a> DistributableToolchain<'a> { toolchain: &self.desc, profile, update_hash, - dl_cfg: cfg.download_cfg(&|n| (cfg.notify_handler)(n.into())), + dl_cfg: cfg.download_cfg(&|n| (cfg.notify_handler)(n)), force, allow_downgrade, exists: true, @@ -509,10 +509,10 @@ impl<'a> DistributableToolchain<'a> { remove_components: vec![component], }; - let notify_handler = - &|n: crate::dist::Notification<'_>| (self.toolchain.cfg.notify_handler)(n.into()); - let download_cfg = self.toolchain.cfg.download_cfg(¬ify_handler); - + let download_cfg = self + .toolchain + .cfg + .download_cfg(&*self.toolchain.cfg.notify_handler); manifestation .update( &manifest, @@ -529,9 +529,10 @@ impl<'a> DistributableToolchain<'a> { pub async fn show_dist_version(&self) -> anyhow::Result> { let update_hash = self.toolchain.cfg.get_hash_file(&self.desc, false)?; - let notify_handler = - &|n: crate::dist::Notification<'_>| (self.toolchain.cfg.notify_handler)(n.into()); - let download_cfg = self.toolchain.cfg.download_cfg(¬ify_handler); + let download_cfg = self + .toolchain + .cfg + .download_cfg(&*self.toolchain.cfg.notify_handler); match crate::dist::dl_v2_manifest(download_cfg, Some(&update_hash), &self.desc).await? { Some((manifest, _)) => Ok(Some(manifest.get_rust_version()?.to_string())), diff --git a/tests/suite/dist_install.rs b/tests/suite/dist_install.rs index 5ab54fcdbe..3999b86910 100644 --- a/tests/suite/dist_install.rs +++ b/tests/suite/dist_install.rs @@ -2,12 +2,12 @@ use std::fs::File; use std::io::Write; use rustup::dist::DEFAULT_DIST_SERVER; -use rustup::dist::Notification; use rustup::dist::component::Components; use rustup::dist::component::Transaction; use rustup::dist::component::{DirectoryPackage, Package}; use rustup::dist::prefix::InstallPrefix; use rustup::dist::temp; +use rustup::notifications::Notification; use rustup::process::TestProcess; use rustup::utils; From 4578dea8d3659fb0738e3f88eaf0b347245245ad Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 22 Sep 2025 15:11:02 +0200 Subject: [PATCH 4/5] Inline utils Notification variants into top-level Notification --- src/cli/common.rs | 4 +- src/cli/download_tracker.rs | 9 ++- src/cli/self_update.rs | 3 +- src/cli/self_update/unix.rs | 3 +- src/cli/self_update/windows.rs | 7 +-- src/diskio/mod.rs | 2 +- src/diskio/threaded.rs | 2 +- src/dist/component/package.rs | 3 +- src/dist/download.rs | 11 ++-- src/dist/manifestation.rs | 20 +++---- src/dist/manifestation/tests.rs | 10 +++- src/dist/mod.rs | 7 ++- src/dist/temp.rs | 2 +- src/download/mod.rs | 2 +- src/notifications.rs | 90 ++++++++++++++++++++++++---- src/utils/mod.rs | 4 +- src/utils/notifications.rs | 101 -------------------------------- 17 files changed, 124 insertions(+), 156 deletions(-) delete mode 100644 src/utils/notifications.rs diff --git a/src/cli/common.rs b/src/cli/common.rs index 3deb44813e..7d9908cb0e 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -22,7 +22,7 @@ use crate::{ notifications::Notification, process::{Process, terminalsource}, toolchain::{LocalToolchainName, Toolchain, ToolchainName}, - utils::{self, notifications as util_notifications, notify::NotificationLevel}, + utils::{self, notify::NotificationLevel}, }; pub(crate) const WARN_COMPLETE_PROFILE: &str = "downloading with complete profile isn't recommended unless you are a developer of the rust language"; @@ -139,7 +139,7 @@ impl Notifier { return; } - if let Notification::Utils(util_notifications::Notification::SetDefaultBufferSize(_)) = &n { + if let Notification::SetDefaultBufferSize(_) = &n { if *self.ram_notice_shown.borrow() { return; } else { diff --git a/src/cli/download_tracker.rs b/src/cli/download_tracker.rs index 53bff50628..a2105dd048 100644 --- a/src/cli/download_tracker.rs +++ b/src/cli/download_tracker.rs @@ -4,7 +4,6 @@ use std::time::{Duration, Instant}; use crate::notifications::Notification; use crate::process::Process; -use crate::utils::Notification as Un; /// Tracks download progress and displays information about it to a terminal. /// @@ -39,25 +38,25 @@ impl DownloadTracker { pub(crate) fn handle_notification(&mut self, n: &Notification<'_>) -> bool { match *n { - Notification::Utils(Un::DownloadContentLengthReceived(content_len, url)) => { + Notification::DownloadContentLengthReceived(content_len, url) => { if let Some(url) = url { self.content_length_received(content_len, url); } true } - Notification::Utils(Un::DownloadDataReceived(data, url)) => { + Notification::DownloadDataReceived(data, url) => { if let Some(url) = url { self.data_received(data.len(), url); } true } - Notification::Utils(Un::DownloadFinished(url)) => { + Notification::DownloadFinished(url) => { if let Some(url) = url { self.download_finished(url); } true } - Notification::Utils(Un::DownloadFailed(url)) => { + Notification::DownloadFailed(url) => { self.download_failed(url); false } diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index c318cdca08..be8f87c4e2 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -61,12 +61,13 @@ use crate::{ dist::{self, PartialToolchainDesc, Profile, TargetTriple, ToolchainDesc}, errors::RustupError, install::UpdateStatus, + notifications::Notification, process::{Process, terminalsource}, toolchain::{ DistributableToolchain, MaybeOfficialToolchainName, ResolvableToolchainName, Toolchain, ToolchainName, }, - utils::{self, Notification}, + utils, }; #[cfg(unix)] diff --git a/src/cli/self_update/unix.rs b/src/cli/self_update/unix.rs index 8c095257f6..99aa6f806c 100644 --- a/src/cli/self_update/unix.rs +++ b/src/cli/self_update/unix.rs @@ -6,8 +6,9 @@ use tracing::{error, warn}; use super::install_bins; use super::shell::{self, Posix, UnixShell}; +use crate::notifications::Notification; use crate::process::Process; -use crate::utils::{self, Notification}; +use crate::utils; // If the user is trying to install with sudo, on some systems this will // result in writing root-owned files to the user's home directory, because diff --git a/src/cli/self_update/windows.rs b/src/cli/self_update/windows.rs index 0812fa3917..100e0bae39 100644 --- a/src/cli/self_update/windows.rs +++ b/src/cli/self_update/windows.rs @@ -23,8 +23,9 @@ use super::{InstallOpts, install_bins, report_error}; use crate::cli::{download_tracker::DownloadTracker, markdown::md}; use crate::dist::TargetTriple; use crate::download::download_file; +use crate::notifications::Notification; use crate::process::{Process, terminalsource::ColorableTerminal}; -use crate::utils::{self, Notification}; +use crate::utils; pub(crate) fn ensure_prompt(process: &Process) -> Result<()> { writeln!(process.stdout().lock(),)?; @@ -285,9 +286,7 @@ pub(crate) async fn try_install_msvc( &visual_studio, None, &move |n| { - download_tracker.lock().unwrap().handle_notification( - &crate::notifications::Notification::Install(crate::dist::Notification::Utils(n)), - ); + download_tracker.lock().unwrap().handle_notification(&n); }, process, ) diff --git a/src/diskio/mod.rs b/src/diskio/mod.rs index a03bef1cf7..a960e6f925 100644 --- a/src/diskio/mod.rs +++ b/src/diskio/mod.rs @@ -65,8 +65,8 @@ use std::{fmt::Debug, fs::OpenOptions}; use anyhow::Result; +use crate::notifications::Notification; use crate::process::Process; -use crate::utils::notifications::Notification; use threaded::PoolReference; /// Carries the implementation specific data for complete file transfers into the executor. diff --git a/src/diskio/threaded.rs b/src/diskio/threaded.rs index 1d23bf34a6..576bdc6b4f 100644 --- a/src/diskio/threaded.rs +++ b/src/diskio/threaded.rs @@ -15,7 +15,7 @@ use sharded_slab::pool::{OwnedRef, OwnedRefMut}; use tracing::debug; use super::{CompletedIo, Executor, Item, perform}; -use crate::utils::notifications::Notification; +use crate::notifications::Notification; #[derive(Copy, Clone, Debug, Enum)] pub(crate) enum Bucket { diff --git a/src/dist/component/package.rs b/src/dist/component/package.rs index 004a064c4f..c89dbe1ccc 100644 --- a/src/dist/component/package.rs +++ b/src/dist/component/package.rs @@ -17,8 +17,9 @@ use crate::dist::component::components::*; use crate::dist::component::transaction::*; use crate::dist::temp; use crate::errors::*; +use crate::notifications::Notification; use crate::process::Process; -use crate::utils::{self, Notification}; +use crate::utils; /// The current metadata revision used by rust-installer pub(crate) const INSTALLER_VERSION: &str = "3"; diff --git a/src/dist/download.rs b/src/dist/download.rs index ab004fa85f..d7755a57f5 100644 --- a/src/dist/download.rs +++ b/src/dist/download.rs @@ -80,7 +80,7 @@ impl<'a> DownloadCfg<'a> { &partial_file_path, Some(&mut hasher), true, - &|n| (self.notify_handler)(n.into()), + &|n| (self.notify_handler)(n), self.process, ) .await @@ -140,7 +140,7 @@ impl<'a> DownloadCfg<'a> { &hash_url, &hash_file, None, - &|n| (self.notify_handler)(n.into()), + &|n| (self.notify_handler)(n), self.process, ) .await?; @@ -185,7 +185,7 @@ impl<'a> DownloadCfg<'a> { &url, &file, Some(&mut hasher), - &|n| (self.notify_handler)(n.into()), + &|n| (self.notify_handler)(n), self.process, ) .await?; @@ -209,10 +209,7 @@ impl<'a> DownloadCfg<'a> { fn file_hash(path: &Path, notify_handler: &dyn Fn(Notification<'_>)) -> Result { let mut hasher = Sha256::new(); - let notification_converter = |notification: crate::utils::Notification<'_>| { - notify_handler(notification.into()); - }; - let mut downloaded = utils::FileReaderWithProgress::new_file(path, ¬ification_converter)?; + let mut downloaded = utils::FileReaderWithProgress::new_file(path, notify_handler)?; use std::io::Read; let mut buf = vec![0; 32768]; while let Ok(n) = downloaded.read(&mut buf) { diff --git a/src/dist/manifestation.rs b/src/dist/manifestation.rs index a84cc40747..e5a23cb8cb 100644 --- a/src/dist/manifestation.rs +++ b/src/dist/manifestation.rs @@ -265,18 +265,16 @@ impl Manifestation { component.target.as_ref(), )); - let notification_converter = |notification: crate::utils::Notification<'_>| { - (download_cfg.notify_handler)(notification.into()); - }; - let cx = PackageContext { tmp_cx, - notify_handler: Some(¬ification_converter), + notify_handler: Some(download_cfg.notify_handler), process: download_cfg.process, }; - let reader = - utils::FileReaderWithProgress::new_file(&installer_file, ¬ification_converter)?; + let reader = utils::FileReaderWithProgress::new_file( + &installer_file, + download_cfg.notify_handler, + )?; let package = match format { CompressionKind::GZip => &TarGzPackage::new(reader, &cx)? as &dyn Package, CompressionKind::XZ => &TarXzPackage::new(reader, &cx)?, @@ -487,14 +485,10 @@ impl Manifestation { } // Install all the components in the installer - let notification_converter = |notification: crate::utils::Notification<'_>| { - notify_handler(notification.into()); - }; - let reader = - utils::FileReaderWithProgress::new_file(&installer_file, ¬ification_converter)?; + let reader = utils::FileReaderWithProgress::new_file(&installer_file, notify_handler)?; let cx = PackageContext { tmp_cx, - notify_handler: Some(¬ification_converter), + notify_handler: Some(notify_handler), process, }; diff --git a/src/dist/manifestation/tests.rs b/src/dist/manifestation/tests.rs index 392fa4781a..c8564f6a39 100644 --- a/src/dist/manifestation/tests.rs +++ b/src/dist/manifestation/tests.rs @@ -22,10 +22,16 @@ use crate::{ manifestation::{Changes, Manifestation, UpdateStatus}, prefix::InstallPrefix, temp, - }, download::download_file, errors::RustupError, notifications::Notification, process::TestProcess, test::{ + }, + download::download_file, + errors::RustupError, + notifications::Notification, + process::TestProcess, + test::{ dist::*, mock::{MockComponentBuilder, MockFile, MockInstallerBuilder}, - }, utils::{self, raw as utils_raw} + }, + utils::{self, raw as utils_raw}, }; const SHA256_HASH_LEN: usize = 64; diff --git a/src/dist/mod.rs b/src/dist/mod.rs index 931932019c..faef0a0360 100644 --- a/src/dist/mod.rs +++ b/src/dist/mod.rs @@ -14,7 +14,12 @@ use thiserror::Error as ThisError; use tracing::{info, warn}; use crate::{ - config::{Cfg, dist_root_server}, errors::RustupError, notifications::Notification, process::Process, toolchain::ToolchainName, utils + config::{Cfg, dist_root_server}, + errors::RustupError, + notifications::Notification, + process::Process, + toolchain::ToolchainName, + utils, }; pub mod component; diff --git a/src/dist/temp.rs b/src/dist/temp.rs index 7803bd932d..d18f6d3005 100644 --- a/src/dist/temp.rs +++ b/src/dist/temp.rs @@ -103,7 +103,7 @@ impl Context { // This is technically racey, but the probability of getting the same // random names at exactly the same time is... low. if !raw::path_exists(&temp_dir) { - (self.notify_handler)(Notification::CreatingDirectory(&temp_dir)); + (self.notify_handler)(Notification::CreatingDirectory("temp", &temp_dir)); fs::create_dir(&temp_dir) .with_context(|| CreatingError::Directory(PathBuf::from(&temp_dir)))?; return Ok(Dir { diff --git a/src/download/mod.rs b/src/download/mod.rs index fa89bb7896..755c1229d5 100644 --- a/src/download/mod.rs +++ b/src/download/mod.rs @@ -20,7 +20,7 @@ use tracing::info; use tracing::warn; use url::Url; -use crate::{errors::RustupError, process::Process, utils::Notification}; +use crate::{errors::RustupError, notifications::Notification, process::Process}; #[cfg(test)] mod tests; diff --git a/src/notifications.rs b/src/notifications.rs index 4362c63485..4adb095d8d 100644 --- a/src/notifications.rs +++ b/src/notifications.rs @@ -2,9 +2,12 @@ use std::fmt::{self, Display}; use std::io; use std::path::{Path, PathBuf}; +use url::Url; + use crate::dist::TargetTriple; use crate::dist::manifest::{Component, Manifest}; use crate::settings::MetadataVersion; +use crate::utils::units; use crate::{dist::ToolchainDesc, toolchain::ToolchainName, utils::notify::NotificationLevel}; #[derive(Debug)] @@ -34,10 +37,37 @@ pub enum Notification<'a> { StrayHash(&'a Path), SignatureInvalid(&'a str), RetryingDownload(&'a str), - Utils(crate::utils::Notification<'a>), + CreatingDirectory(&'a str, &'a Path), + LinkingDirectory(&'a Path, &'a Path), + CopyingDirectory(&'a Path, &'a Path), + RemovingDirectory(&'a str, &'a Path), + DownloadingFile(&'a Url, &'a Path), + /// Received the Content-Length of the to-be downloaded data with + /// the respective URL of the download (for tracking concurrent downloads). + DownloadContentLengthReceived(u64, Option<&'a str>), + /// Received some data. + DownloadDataReceived(&'a [u8], Option<&'a str>), + /// Download has finished. + DownloadFinished(Option<&'a str>), + /// Download has failed. + DownloadFailed(&'a str), + NoCanonicalPath(&'a Path), + ResumingPartialDownload, + /// This would make more sense as a crate::notifications::Notification + /// member, but the notification callback is already narrowed to + /// utils::notifications by the time tar unpacking is called. + SetDefaultBufferSize(usize), + Error(String), + UsingCurl, + UsingReqwest, + /// Renaming encountered a file in use error and is retrying. + /// The InUse aspect is a heuristic - the OS specifies + /// Permission denied, but as we work in users home dirs and + /// running programs like virus scanner are known to cause this + /// the heuristic is quite good. + RenameInUse(&'a Path, &'a Path), CreatingRoot(&'a Path), CreatingFile(&'a Path), - CreatingDirectory(&'a Path), FileDeletion(&'a Path, io::Result<()>), DirectoryDeletion(&'a Path, io::Result<()>), SetAutoInstall(&'a str), @@ -65,12 +95,6 @@ pub enum Notification<'a> { }, } -impl<'a> From> for Notification<'a> { - fn from(n: crate::utils::Notification<'a>) -> Self { - Notification::Utils(n) - } -} - impl Notification<'_> { pub(crate) fn level(&self) -> NotificationLevel { use self::Notification::*; @@ -99,8 +123,23 @@ impl Notification<'_> { | StrayHash(_) => NotificationLevel::Warn, NonFatalError(_) => NotificationLevel::Error, SignatureInvalid(_) => NotificationLevel::Warn, - Utils(n) => n.level(), - CreatingRoot(_) | CreatingFile(_) | CreatingDirectory(_) => NotificationLevel::Debug, + SetDefaultBufferSize(_) => NotificationLevel::Trace, + CreatingDirectory(_, _) + | RemovingDirectory(_, _) + | LinkingDirectory(_, _) + | CopyingDirectory(_, _) + | DownloadingFile(_, _) + | DownloadContentLengthReceived(_, _) + | DownloadDataReceived(_, _) + | DownloadFinished(_) + | DownloadFailed(_) + | ResumingPartialDownload + | UsingCurl + | UsingReqwest => NotificationLevel::Debug, + RenameInUse(_, _) => NotificationLevel::Info, + NoCanonicalPath(_) => NotificationLevel::Warn, + Error(_) => NotificationLevel::Error, + CreatingRoot(_) | CreatingFile(_) => NotificationLevel::Debug, FileDeletion(_, result) | DirectoryDeletion(_, result) => { if result.is_ok() { NotificationLevel::Debug @@ -225,10 +264,37 @@ impl Display for Notification<'_> { } SignatureInvalid(url) => write!(f, "Signature verification failed for '{url}'"), RetryingDownload(url) => write!(f, "retrying download for '{url}'"), - Utils(n) => n.fmt(f), + CreatingDirectory(name, path) => { + write!(f, "creating {} directory: '{}'", name, path.display()) + } + Error(e) => write!(f, "error: '{e}'"), + LinkingDirectory(_, dest) => write!(f, "linking directory from: '{}'", dest.display()), + CopyingDirectory(src, _) => write!(f, "copying directory from: '{}'", src.display()), + RemovingDirectory(name, path) => { + write!(f, "removing {} directory: '{}'", name, path.display()) + } + RenameInUse(src, dest) => write!( + f, + "retrying renaming '{}' to '{}'", + src.display(), + dest.display() + ), + SetDefaultBufferSize(size) => write!( + f, + "using up to {} of RAM to unpack components", + units::Size::new(*size) + ), + DownloadingFile(url, _) => write!(f, "downloading file from: '{url}'"), + DownloadContentLengthReceived(len, _) => write!(f, "download size is: '{len}'"), + DownloadDataReceived(data, _) => write!(f, "received some data of size {}", data.len()), + DownloadFinished(_) => write!(f, "download finished"), + DownloadFailed(_) => write!(f, "download failed"), + NoCanonicalPath(path) => write!(f, "could not canonicalize path: '{}'", path.display()), + ResumingPartialDownload => write!(f, "resuming partial download"), + UsingCurl => write!(f, "downloading with curl"), + UsingReqwest => write!(f, "downloading with reqwest"), CreatingRoot(path) => write!(f, "creating temp root: {}", path.display()), CreatingFile(path) => write!(f, "creating temp file: {}", path.display()), - CreatingDirectory(path) => write!(f, "creating temp directory: {}", path.display()), FileDeletion(path, result) => { if result.is_ok() { write!(f, "deleted temp file: {}", path.display()) diff --git a/src/utils/mod.rs b/src/utils/mod.rs index dd69ef00a9..d1c9ae4c0b 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -16,12 +16,12 @@ use url::Url; use crate::errors::*; use crate::process::Process; +use crate::notifications::Notification; #[cfg(not(windows))] pub(crate) use crate::utils::raw::find_cmd; +pub(crate) use crate::utils::raw::is_directory; pub use crate::utils::raw::{is_file, path_exists}; -pub(crate) use crate::utils::{notifications::Notification, raw::is_directory}; -pub(crate) mod notifications; pub(crate) mod notify; pub mod raw; pub(crate) mod units; diff --git a/src/utils/notifications.rs b/src/utils/notifications.rs deleted file mode 100644 index 0f185f9da3..0000000000 --- a/src/utils/notifications.rs +++ /dev/null @@ -1,101 +0,0 @@ -use std::fmt::{self, Display}; -use std::path::Path; - -use url::Url; - -use crate::utils::notify::NotificationLevel; -use crate::utils::units; - -#[derive(Debug)] -pub enum Notification<'a> { - CreatingDirectory(&'a str, &'a Path), - LinkingDirectory(&'a Path, &'a Path), - CopyingDirectory(&'a Path, &'a Path), - RemovingDirectory(&'a str, &'a Path), - DownloadingFile(&'a Url, &'a Path), - /// Received the Content-Length of the to-be downloaded data with - /// the respective URL of the download (for tracking concurrent downloads). - DownloadContentLengthReceived(u64, Option<&'a str>), - /// Received some data. - DownloadDataReceived(&'a [u8], Option<&'a str>), - /// Download has finished. - DownloadFinished(Option<&'a str>), - /// Download has failed. - DownloadFailed(&'a str), - NoCanonicalPath(&'a Path), - ResumingPartialDownload, - /// This would make more sense as a crate::notifications::Notification - /// member, but the notification callback is already narrowed to - /// utils::notifications by the time tar unpacking is called. - SetDefaultBufferSize(usize), - Error(String), - UsingCurl, - UsingReqwest, - /// Renaming encountered a file in use error and is retrying. - /// The InUse aspect is a heuristic - the OS specifies - /// Permission denied, but as we work in users home dirs and - /// running programs like virus scanner are known to cause this - /// the heuristic is quite good. - RenameInUse(&'a Path, &'a Path), -} - -impl Notification<'_> { - pub(crate) fn level(&self) -> NotificationLevel { - use self::Notification::*; - match self { - SetDefaultBufferSize(_) => NotificationLevel::Trace, - CreatingDirectory(_, _) - | RemovingDirectory(_, _) - | LinkingDirectory(_, _) - | CopyingDirectory(_, _) - | DownloadingFile(_, _) - | DownloadContentLengthReceived(_, _) - | DownloadDataReceived(_, _) - | DownloadFinished(_) - | DownloadFailed(_) - | ResumingPartialDownload - | UsingCurl - | UsingReqwest => NotificationLevel::Debug, - RenameInUse(_, _) => NotificationLevel::Info, - NoCanonicalPath(_) => NotificationLevel::Warn, - Error(_) => NotificationLevel::Error, - } - } -} - -impl Display for Notification<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> { - use self::Notification::*; - match self { - CreatingDirectory(name, path) => { - write!(f, "creating {} directory: '{}'", name, path.display()) - } - Error(e) => write!(f, "error: '{e}'"), - LinkingDirectory(_, dest) => write!(f, "linking directory from: '{}'", dest.display()), - CopyingDirectory(src, _) => write!(f, "copying directory from: '{}'", src.display()), - RemovingDirectory(name, path) => { - write!(f, "removing {} directory: '{}'", name, path.display()) - } - RenameInUse(src, dest) => write!( - f, - "retrying renaming '{}' to '{}'", - src.display(), - dest.display() - ), - SetDefaultBufferSize(size) => write!( - f, - "using up to {} of RAM to unpack components", - units::Size::new(*size) - ), - DownloadingFile(url, _) => write!(f, "downloading file from: '{url}'"), - DownloadContentLengthReceived(len, _) => write!(f, "download size is: '{len}'"), - DownloadDataReceived(data, _) => write!(f, "received some data of size {}", data.len()), - DownloadFinished(_) => write!(f, "download finished"), - DownloadFailed(_) => write!(f, "download failed"), - NoCanonicalPath(path) => write!(f, "could not canonicalize path: '{}'", path.display()), - ResumingPartialDownload => write!(f, "resuming partial download"), - UsingCurl => write!(f, "downloading with curl"), - UsingReqwest => write!(f, "downloading with reqwest"), - } - } -} From 84e13a050ce432c100861e5f1d3ff2bba7159b6f Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 23 Sep 2025 17:17:10 +0200 Subject: [PATCH 5/5] notifications: tweak style --- src/notifications.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/notifications.rs b/src/notifications.rs index 4adb095d8d..8669d12663 100644 --- a/src/notifications.rs +++ b/src/notifications.rs @@ -140,13 +140,10 @@ impl Notification<'_> { NoCanonicalPath(_) => NotificationLevel::Warn, Error(_) => NotificationLevel::Error, CreatingRoot(_) | CreatingFile(_) => NotificationLevel::Debug, - FileDeletion(_, result) | DirectoryDeletion(_, result) => { - if result.is_ok() { - NotificationLevel::Debug - } else { - NotificationLevel::Warn - } - } + FileDeletion(_, result) | DirectoryDeletion(_, result) => match result { + Ok(_) => NotificationLevel::Debug, + Err(_) => NotificationLevel::Warn, + }, ToolchainDirectory(_) | LookingForToolchain(_) | InstallingToolchain(_)