Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/utils/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ mod tests {
assert_eq!(" 95.20 GiB", format_bytes(95200000000));
assert_eq!("302.00 GiB", format_bytes(302000000000));
assert_eq!("302.99 GiB", format_bytes(302990000000));
// Weird aproximation cases:
// Weird approximation cases:
assert_eq!("999.90 GiB", format_bytes(999900000000));
assert_eq!(" 1.00 TiB", format_bytes(999990000000));
}
Expand Down
16 changes: 8 additions & 8 deletions src/utils/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::{
use fs_err::{self as fs, PathExt};
use same_file::Handle;

use super::{question::FileConflitOperation, user_wants_to_overwrite};
use super::{question::FileConflictOperation, user_wants_to_overwrite};
use crate::{
FinalError, QuestionPolicy, Result,
error::Error,
Expand All @@ -37,13 +37,13 @@ pub fn resolve_path_conflict(
) -> Result<Option<PathBuf>> {
if path.fs_err_try_exists()? {
match user_wants_to_overwrite(path, question_policy, question_action)? {
FileConflitOperation::Cancel => Ok(None),
FileConflitOperation::Overwrite => {
FileConflictOperation::Cancel => Ok(None),
FileConflictOperation::Overwrite => {
remove_file_or_dir(path)?;
Ok(Some(path.to_path_buf()))
}
FileConflitOperation::Rename => Ok(Some(find_available_filename_by_renaming(path)?)),
FileConflitOperation::Merge => Ok(Some(path.to_path_buf())),
FileConflictOperation::Rename => Ok(Some(find_available_filename_by_renaming(path)?)),
FileConflictOperation::Merge => Ok(Some(path.to_path_buf())),
}
} else {
Ok(Some(path.to_path_buf()))
Expand All @@ -59,9 +59,9 @@ pub fn resolve_extraction_conflict(path: &Path, question_policy: QuestionPolicy)

// These choices fit a single file. They are rename or overwrite or skip.
match user_wants_to_overwrite(path, question_policy, QuestionAction::Compression)? {
FileConflitOperation::Cancel => Ok(None),
FileConflitOperation::Rename => Ok(Some(find_available_filename_by_renaming(path)?)),
FileConflitOperation::Overwrite | FileConflitOperation::Merge => Ok(Some(path.to_path_buf())),
FileConflictOperation::Cancel => Ok(None),
FileConflictOperation::Rename => Ok(Some(find_available_filename_by_renaming(path)?)),
FileConflictOperation::Overwrite | FileConflictOperation::Merge => Ok(Some(path.to_path_buf())),
}
}

Expand Down
58 changes: 29 additions & 29 deletions src/utils/question.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub enum QuestionAction {

#[derive(Default)]
/// Determines which action to do when there is a file conflict
pub enum FileConflitOperation {
pub enum FileConflictOperation {
#[default]
/// Cancel the operation
Cancel,
Expand All @@ -61,8 +61,8 @@ pub fn user_wants_to_overwrite(
path: &Path,
question_policy: QuestionPolicy,
question_action: QuestionAction,
) -> Result<FileConflitOperation> {
use FileConflitOperation as Op;
) -> Result<FileConflictOperation> {
use FileConflictOperation as Op;

match question_policy {
QuestionPolicy::AlwaysYes => match question_action {
Expand All @@ -78,8 +78,8 @@ pub fn user_wants_to_overwrite(
pub fn prompt_user_for_file_conflict_resolution(
path: &Path,
question_action: QuestionAction,
) -> Result<FileConflitOperation> {
use FileConflitOperation as Op;
) -> Result<FileConflictOperation> {
use FileConflictOperation as Op;

match question_action {
QuestionAction::Compression => ChoicePrompt::new(
Expand Down Expand Up @@ -137,15 +137,15 @@ pub fn create_file_or_prompt_on_conflict(

// Question policy override prompting
let action = match question_policy {
QuestionPolicy::AlwaysYes => FileConflitOperation::Overwrite,
QuestionPolicy::AlwaysNo => FileConflitOperation::Cancel,
QuestionPolicy::AlwaysYes => FileConflictOperation::Overwrite,
QuestionPolicy::AlwaysNo => FileConflictOperation::Cancel,
QuestionPolicy::Ask => prompt_user_for_file_conflict_resolution(&path, question_action)?,
};

let path_to_create_file = match action {
FileConflitOperation::Cancel => return Ok(None),
FileConflitOperation::Merge => path,
FileConflitOperation::Overwrite => {
FileConflictOperation::Cancel => return Ok(None),
FileConflictOperation::Merge => path,
FileConflictOperation::Overwrite => {
// Refuse an existing directory so overwrite never deletes it
if path.is_dir() {
return Err(FinalError::with_title(format!("Cannot compress to {}", PathFmt(&path)))
Expand All @@ -156,7 +156,7 @@ pub fn create_file_or_prompt_on_conflict(
utils::remove_file_or_dir(&path)?;
path
}
FileConflitOperation::Rename => utils::find_available_filename_by_renaming(&path)?,
FileConflictOperation::Rename => utils::find_available_filename_by_renaming(&path)?,
};

let file = fs::File::create(&path_to_create_file)?;
Expand Down Expand Up @@ -185,14 +185,14 @@ pub fn user_wants_to_continue(
}
}

/// Choise dialog for end user with [option1/option2/...] question.
/// Choice dialog for end user with [option1/option2/...] question.
/// Each option is a [Choice] entity, holding a value "T" returned when that option is selected
pub struct ChoicePrompt<'a, T: Default> {
/// The message to be displayed before the options
/// e.g.: "Do you want to overwrite 'FILE'?"
pub prompt: String,

pub choises: Vec<Choice<'a, T>>,
pub choices: Vec<Choice<'a, T>>,
}

/// A single choice showed as a option to user in a [ChoicePrompt]
Expand All @@ -205,18 +205,18 @@ pub struct Choice<'a, T: Default> {

impl<'a, T: Default> ChoicePrompt<'a, T> {
/// Creates a new Confirmation.
pub fn new(prompt: impl Into<String>, choises: impl IntoIterator<Item = (&'a str, T, &'a str)>) -> Self {
pub fn new(prompt: impl Into<String>, choices: impl IntoIterator<Item = (&'a str, T, &'a str)>) -> Self {
Self {
prompt: prompt.into(),
choises: choises
choices: choices
.into_iter()
.map(|(label, value, color)| Choice { label, value, color })
.collect(),
}
}

/// Creates user message and receives a input to be compared with choises "label"
/// and returning the real value of the choise selected
/// Creates user message and receives a input to be compared with choices "label"
/// and returning the real value of the choice selected
pub fn ask(mut self) -> Result<T> {
let message = self.prompt;

Expand All @@ -235,18 +235,18 @@ impl<'a, T: Default> ChoicePrompt<'a, T> {
// Ask the same question to end while no valid answers are given
loop {
let choice_prompt = if is_running_in_accessible_mode() {
self.choises
self.choices
.iter()
.map(|choise| format!("{}{}{}", choise.color, choise.label, *colors::RESET))
.map(|choice| format!("{}{}{}", choice.color, choice.label, *colors::RESET))
.collect::<Vec<_>>()
.join("/")
} else {
let choises = self
.choises
let choices = self
.choices
.iter()
.enumerate()
.map(|(index, choise)| {
let mut chars = choise.label.chars();
.map(|(index, choice)| {
let mut chars = choice.label.chars();
let first = chars
.next()
.expect("dev error, should be reported, we checked this won't happen");
Expand All @@ -256,12 +256,12 @@ impl<'a, T: Default> ChoicePrompt<'a, T> {
first.to_string()
};
let rest: String = chars.collect();
format!("{}({}){}{}", choise.color, first_formatted, rest, *colors::RESET)
format!("{}({}){}{}", choice.color, first_formatted, rest, *colors::RESET)
})
.collect::<Vec<_>>()
.join("/");

format!("[{choises}]")
format!("[{choices}]")
};

eprintln!("{message} {choice_prompt}");
Expand All @@ -282,14 +282,14 @@ impl<'a, T: Default> ChoicePrompt<'a, T> {
answer.make_ascii_lowercase();
let answer = answer.trim();

if answer.is_empty() && !self.choises.is_empty() {
return Ok(self.choises.remove(0).value);
if answer.is_empty() && !self.choices.is_empty() {
return Ok(self.choices.remove(0).value);
}

let chosen_index = self.choises.iter().position(|choise| choise.label.starts_with(answer));
let chosen_index = self.choices.iter().position(|choice| choice.label.starts_with(answer));

if let Some(i) = chosen_index {
return Ok(self.choises.remove(i).value);
return Ok(self.choices.remove(i).value);
}
}
}
Expand Down