Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#98] changed all formatting functions so they accept a type that implements Display #100

Merged
merged 7 commits into from
Sep 19, 2022
4 changes: 2 additions & 2 deletions src/config/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ impl Config {
let expanded_store_directory = shellexpand::full(&self.store_directory);

let store_directory = match expanded_store_directory {
Err(e) => err::abort_with(&e.to_string()),
Err(e) => err::abort_with(e),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is perfect 👨🏻‍🍳 🤌

Ok(cow_path) => PathBuf::from(cow_path.into_owned()),
};

let has_store_directory = store_directory.as_path().is_dir();

if !has_store_directory {
err::abort_with(&format!(
err::abort_with(format!(
"Specified directory for storing tools doesn't exist: {}",
store_directory.display()
));
Expand Down
4 changes: 2 additions & 2 deletions src/config/toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ pub fn with_parsed_file<F: FnOnce(Config)>(config_path: PathBuf, on_success: F)
on_success(config);
}
Err(e) => {
err::abort_with(&format!(
err::abort_with(format!(
"Error parsing configuration at path {}: {}",
config_path.display(),
e.to_string()
e
));
}
}
Expand Down
10 changes: 7 additions & 3 deletions src/infra/err.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::fmt::Display;
use std::process;

/// Print an error message and exit with code 1
pub fn abort_with(err_msg: &str) -> ! {
/// This function can take in any type that implements the [`Display`] trait
pub fn abort_with<Message: Display>(err_msg: Message) -> ! {
eprintln!(
r#"Aborting 'tool-sync' with error:

Expand All @@ -13,7 +15,8 @@ pub fn abort_with(err_msg: &str) -> ! {
}

/// Print an error message, suggesting opening an issue and exit with code 1
pub fn abort_suggest_issue(err_msg: &str) -> ! {
/// This function can take in any type that implements the [`Display`] trait
pub fn abort_suggest_issue<Message: Display>(err_msg: Message) -> ! {
eprintln!(
r#"Aborting 'tool-sync' with error:

Expand All @@ -31,7 +34,8 @@ this issue:
}

/// Print just the message and exit
pub fn abort(err_msg: &str) -> ! {
/// This function can take in any type that implements the [`Display`] trait
pub fn abort<Message: Display>(err_msg: Message) -> ! {
eprintln!("{}", err_msg);
process::exit(1);
}
2 changes: 1 addition & 1 deletion src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ Supported tools:
{tools}"#
);

err::abort(&exit_message);
err::abort(exit_message);
}
}
2 changes: 1 addition & 1 deletion src/sync/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl<'a> Installer<'a> {
let tmp_dir = TempDir::new("tool-sync");
match tmp_dir {
Err(e) => {
err::abort_suggest_issue(&format!("Error creating temporary directory: {}", e));
err::abort_suggest_issue(format!("Error creating temporary directory: {}", e));
}
Ok(tmp_dir) => Installer {
store_directory,
Expand Down
12 changes: 8 additions & 4 deletions src/sync/prefetch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use console::{style, Emoji};
use indicatif::{HumanBytes, ProgressBar, ProgressStyle};

use std::collections::BTreeMap;
use std::fmt::Display;

use super::configure::configure_tool;
use crate::config::schema::ConfigAsset;
Expand Down Expand Up @@ -36,12 +38,14 @@ impl PrefetchProgress {
}
}

fn expected_err_msg(&self, tool_name: &str, msg: &str) {
/// This method can take in any type that implements the [`Display`] trait
fn expected_err_msg<Message: Display>(&self, tool_name: &str, msg: &Message) {
let tool = format!("{}", style(tool_name).cyan().bold());
self.pb.println(format!("{} {} {}", ERROR, tool, msg))
}

fn unexpected_err_msg(&self, tool_name: &str, msg: &str) {
/// This method can take in any type that implements the [`Display`] trait
fn unexpected_err_msg<Message: Display>(&self, tool_name: &str, msg: &Message) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like how only type-signatures changed but not the implementation of functions and the call sites became simpler as well! 🚀

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is a perfect application of polymorphism, it does complicate the code a bit for people that aren't used to generic programming, but this cleans up the code a lot in my opinion.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I like the simplification in this particular case 🙂

In the end, the generic function is written only once and you need to understand it once. But it's used many times and it can save a bit of boilerplate each time.

let tool = format!("{}", style(tool_name).cyan().bold());
let err_msg = format!(
r#"{emoji} {tool} {msg}
Expand Down Expand Up @@ -106,7 +110,7 @@ fn prefetch_tool(

match configure_tool(tool_name, config_asset) {
Tool::Error(e) => {
prefetch_progress.expected_err_msg(tool_name, &e.to_string());
prefetch_progress.expected_err_msg(tool_name, &e);
prefetch_progress.update_message(already_completed);
None
}
Expand All @@ -125,7 +129,7 @@ fn prefetch_tool(
}
Ok(release) => match tool_info.select_asset(&release.assets) {
Err(err) => {
prefetch_progress.unexpected_err_msg(tool_name, &err.to_string());
prefetch_progress.unexpected_err_msg(tool_name, &err);
prefetch_progress.update_message(already_completed);
None
}
Expand Down
11 changes: 10 additions & 1 deletion src/sync/progress.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Display;

use console::{style, Emoji};
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};

Expand Down Expand Up @@ -84,7 +86,14 @@ impl SyncProgress {
pb.finish();
}

pub fn failure(&self, pb: ProgressBar, tool_name: &str, tag: &str, err_msg: String) {
/// This method can take in any type that implements the [`Display`] trait
pub fn failure<Message: Display>(
&self,
pb: ProgressBar,
tool_name: &str,
tag: &str,
err_msg: Message,
) {
pb.set_prefix(self.fmt_prefix(FAILURE, tool_name, tag));

let failure_msg = format!("{}", style(err_msg).red());
Expand Down