From 1e811d61ed24028a20f84a4338c93754d5d62089 Mon Sep 17 00:00:00 2001 From: Vladimir Rubin Date: Mon, 30 Dec 2024 17:05:56 +0200 Subject: [PATCH] feat: recursiveness --- src/main.rs | 84 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 17 deletions(-) diff --git a/src/main.rs b/src/main.rs index e3fd133..ae6dd03 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use std::{ env, fs, io::{self, Write}, - path::PathBuf, + path::{Path, PathBuf}, process, sync::OnceLock, thread, @@ -86,12 +86,33 @@ fn main() { break; } + let recursive: bool; + + loop { + print!("Recursive (yes/no): "); + io::stdout().flush().unwrap(); + let mut selected = String::new(); + io::stdin() + .read_line(&mut selected) + .expect("Failed to read line"); + + if selected.trim().starts_with('y') { + recursive = true; + break; + } else if selected.trim().starts_with('n') { + recursive = false; + break; + } + + println!("Invalid answer"); + } + println!("Selected: {}", actual_selection.join(", ")); let mut thread_pool: Vec> = Vec::new(); for selection in actual_selection { - let thread = thread::spawn(move || match sort_files(selection, false) { + let thread = thread::spawn(move || match sort_files(selection, recursive) { Ok(_) => {} Err(err) => eprintln!("{}", err), }); @@ -104,16 +125,13 @@ fn main() { } } -// TODO: implement recuriveness -fn sort_files(selection: String, _recursive: bool) -> Result<(), Box> { +fn sort_files(selection: String, recursive: bool) -> Result<(), Box> { let search_path = CONFIG .get() .and_then(|config| config.sources.get(&selection)) .cloned() .unwrap(); - let dir = fs::read_dir(search_path)?; - let file_types = [ ( "Picture", @@ -137,26 +155,58 @@ fn sort_files(selection: String, _recursive: bool) -> Result<(), Box, Option)], + recursive: bool, + ) -> Result<(), Box> { + for entry in fs::read_dir(path)?.flatten() { + let metadata = entry.metadata()?; - for (label, valid_extensions, target_dir_option) in &file_types { - if let Some(target_dir) = target_dir_option { - if valid_extensions.contains(&extension) { - println!("{}: {}", label, path.display()); - move_file_to_directory(&path, target_dir); + if metadata.is_file() { + if let Some(extension) = entry.path().extension().and_then(|e| e.to_str()) { + let file_path = entry.path(); + + for (_label, valid_extensions, target_dir_option) in file_types { + if let Some(target_dir) = target_dir_option { + if valid_extensions.contains(&extension) { + move_file_to_directory(&file_path, target_dir); + } + } } } + } else if metadata.is_dir() && recursive { + // Recurse into the directory + process_directory(&entry.path(), file_types, recursive)?; } } + + Ok(()) } - Ok(()) + process_directory(&search_path, &file_types, recursive) } -fn move_file_to_directory(path: &std::path::Path, dir: &std::path::Path) { - let _ = fs::rename(path, dir.join(path.file_name().unwrap())); +fn move_file_to_directory(path: &Path, dir: &Path) { + if !path.exists() { + eprintln!("Source file does not exist"); + return; + } + + if !dir.exists() { + match fs::create_dir(dir) { + Ok(_) => {}, + Err(err) => eprintln!("Error creating destination directory: {}", err) + } + return; + } + + let destination = dir.join(path.file_name().unwrap_or_default()); + + match fs::rename(path, &destination) { + Ok(()) => {}, + Err(err) => eprintln!("Error moving file: {}", err), + } } fn get_config_path() -> PathBuf {