This commit is contained in:
Talison Fabio 2025-03-22 22:46:02 -03:00
parent 3626e7196f
commit cede4b2624
4 changed files with 18 additions and 5 deletions

View File

@ -323,6 +323,8 @@ fn smart_unpack(
(temp_dir_path.to_owned(), output_file_path.to_owned())
};
// Before moving, need to check if a file with the same name already exists
// If it does, need to ask the user what to do
new_path = match utils::resolve_path(&new_path, question_policy)? {
Some(path) => path,
None => return Ok(ControlFlow::Break(())),

View File

@ -19,6 +19,7 @@ pub fn is_path_stdin(path: &Path) -> bool {
path.as_os_str() == "-"
}
/// Check if &Path exists, if it does then ask the user if they want to overwrite or rename it
pub fn resolve_path(path: &Path, question_policy: QuestionPolicy) -> crate::Result<Option<PathBuf>> {
if path.exists() {
match user_wants_to_overwrite(path, question_policy)? {
@ -46,6 +47,7 @@ pub fn remove_file_or_dir(path: &Path) -> crate::Result<()> {
Ok(())
}
/// Create a new path renaming the "filename" from &Path until find a free name
pub fn rename_for_available_filename(path: &Path) -> PathBuf {
let mut renamed_path = rename_or_increment_filename(path);
while renamed_path.exists() {
@ -54,6 +56,8 @@ pub fn rename_for_available_filename(path: &Path) -> PathBuf {
renamed_path
}
/// Create a new path renaming the "filename" from &Path to `filename_1`
/// or `filename_2`, `filename_3` until find a free name
pub fn rename_or_increment_filename(path: &Path) -> PathBuf {
let parent = path.parent().unwrap_or_else(|| Path::new(""));
let filename = path.file_stem().and_then(|s| s.to_str()).unwrap_or("");

View File

@ -19,7 +19,7 @@ pub use self::{
},
fs::{
cd_into_same_dir_as, create_dir_if_non_existent, is_path_stdin, remove_file_or_dir,
rename_for_available_filename, resolve_path, try_infer_extension,
rename_for_available_filename, resolve_path_conflict, try_infer_extension,
},
question::{
ask_to_create_file, user_wants_to_continue, user_wants_to_overwrite, FileConflitOperation, QuestionAction,

View File

@ -38,10 +38,15 @@ pub enum QuestionAction {
}
#[derive(Default)]
/// Determines which action to do when there is a file conflict
pub enum FileConflitOperation {
#[default]
/// Cancel the operation
Cancel,
/// Overwrite the existing file with the new one
Overwrite,
/// Rename the file
/// It'll be put "_1" at the end of the filename or "_2","_3","_4".. if already exists
Rename,
}
@ -56,7 +61,7 @@ pub fn user_wants_to_overwrite(path: &Path, question_policy: QuestionPolicy) ->
}
}
/// Check if QuestionPolicy flags were set, otherwise, ask user if they want to overwrite.
/// Ask the user if they want to overwrite or rename the &Path
pub fn ask_file_conflict_operation(path: &Path) -> Result<FileConflitOperation> {
use FileConflitOperation as Op;
@ -127,8 +132,7 @@ pub fn user_wants_to_continue(
}
/// Choise dialog for end user with [option1/option2/...] question.
///
/// If the placeholder is found in the prompt text, it will be replaced to form the final message.
/// 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 with the placeholder text in it.
/// e.g.: "Do you want to overwrite 'FILE'?"
@ -137,6 +141,8 @@ pub struct ChoicePrompt<'a, T: Default> {
pub choises: Vec<Choice<'a, T>>,
}
/// A single choice showed as a option to user in a [ChoicePrompt]
/// It holds a label and a color to display to user and a real value to be returned
pub struct Choice<'a, T: Default> {
label: &'a str,
value: T,
@ -155,7 +161,8 @@ impl<'a, T: Default> ChoicePrompt<'a, T> {
}
}
/// Creates user message and receives a boolean input to be used on the program
/// Creates user message and receives a input to be compared with choises "label"
/// and returning the real value of the choise selected
pub fn ask(mut self) -> crate::Result<T> {
let message = self.prompt;