use super::common::{self, PanicOnError};
use std::fs;
use std::io::{self, Write};
use std::path::Path;
pub fn run(args: Vec<String>) {
if args.len() < 4 {
eprintln!("Usage: tempesta move <path-from> <path-to>");
std::process::exit(1);
}
let relative_path_from = &args[2];
common::validate_path(relative_path_from);
let relative_path_to = &args[3];
common::validate_path(relative_path_to);
let toml_from_file_path = common::get_bookmark_file_path(relative_path_from);
if !toml_from_file_path.exists() {
eprintln!("Path {:?} do not exists", &toml_from_file_path.to_str());
std::process::exit(1);
}
let toml_to_file_path = if relative_path_to.ends_with('/') {
let directory_path = Path::new(relative_path_to);
let file_name = toml_from_file_path.file_stem().unwrap();
let full_path = &directory_path.join(file_name).display().to_string();
common::get_bookmark_file_path(full_path)
} else {
common::get_bookmark_file_path(relative_path_to)
};
if toml_to_file_path.exists() && !prompt_for_overwrite(&toml_to_file_path) {
println!("Move operation aborted.");
std::process::exit(0);
}
if let Some(parent) = toml_to_file_path.parent() {
if !parent.exists() {
fs::create_dir_all(parent)
.panic_on_error("Failed to create destination directory")
}
}
fs::rename(&toml_from_file_path, &toml_to_file_path)
.panic_on_error("Failed to move bookmark file");
if let Some(parent) = toml_from_file_path.parent() {
cleanup_empty_parents(parent)
.panic_on_error("Warning: Failed to clean up empty directories")
}
let comment = format!(
"Move bookmark from {} to {}",
&relative_path_from, &relative_path_to
);
common::git_commit(&comment);
println!(
"Bookmark moved successfully from {} to {}",
&relative_path_from, &relative_path_to
);
}
fn prompt_for_overwrite(destination: &Path) -> bool {
print!(
"A bookmark already exists at {}. Overwrite? [Y/n]: ",
destination.display()
);
io::stdout().flush().expect("Failed to flush stdout");
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read user input");
let trimmed = input.trim().to_lowercase();
match trimmed.as_str() {
"" | "y" | "yes" => true, "n" | "no" => false,
_ => {
println!("Invalid input, assuming 'no'.");
false
}
}
}
fn cleanup_empty_parents(starting_dir: &Path) -> std::io::Result<()> {
let mut current = starting_dir.to_path_buf();
loop {
if !current.exists() {
break;
}
let is_empty = fs::read_dir(¤t)?.next().is_none();
if is_empty {
fs::remove_dir(¤t)?;
if !current.pop() {
break; }
} else {
break; }
}
Ok(())
}