From 49b3c950d2edae4642938d75a2af9f37d361ae1a Mon Sep 17 00:00:00 2001 From: Pedro de Oliveira Date: Mon, 8 May 2023 01:51:38 +0100 Subject: [PATCH] * Add documentation to every function * Add main crate documentation * clippy fixes * filenames -> file names, filename -> file name --- README.md | 22 +++++++++++----------- src/main.rs | 54 ++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 7ecc094..14730d5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # rmv: Renaming made easy with regex -`rmv` is a command-line tool that allows you to rename files in a directory using regular expressions. You can use it to match patterns in filenames and replace them with new patterns. +`rmv` is a command-line tool that allows you to rename files in a directory using regular expressions. You can use it to match patterns in file names and replace them with new patterns. ## Installation @@ -12,7 +12,7 @@ cargo install --git https://git.deadbsd.org/falso/rmv.git ## Usage -To use `rmv`, you need to specify the path to the directory where the files to be renamed are located, a regular expression pattern to match against the filenames, and a replacement pattern for the matched filenames. +To use `rmv`, you need to specify the path to the directory where the files to be renamed are located, a regular expression pattern to match against the file names, and a replacement pattern for the matched file names. `rmv --path --pattern --replacement ` @@ -22,20 +22,20 @@ The `--path` argument specifies the path to the directory where the files to be ### `--pattern` -The `--pattern` argument specifies the regular expression pattern to match against the filenames. This argument is required. +The `--pattern` argument specifies the regular expression pattern to match against the file names. This argument is required. -You can use matching groups in the pattern to capture parts of the filename that you want to use in the replacement pattern. For example, the pattern `"S(\d+)E(\d+)"` will match on `"S01E23"` and capture `"01"` in group 1 and `"23"` in group 2. +You can use matching groups in the pattern to capture parts of the file name that you want to use in the replacement pattern. For example, the pattern `"S(\d+)E(\d+)"` will match on `"S01E23"` and capture `"01"` in group 1 and `"23"` in group 2. ### `--replacement` -The `--replacement` argument specifies the replacement pattern for the matched filenames. This argument is required. +The `--replacement` argument specifies the replacement pattern for the matched file names. This argument is required. You can use reference groups in the pattern by using `\1`, `\2`, etc. to refer to the captured groups in the `--pattern` argument. For example, if you have a pattern `"S(\d+)E(\d+)"` that matches `"S01E11"` and you want to replace it with `"Season 01 Episode 11"`, you can use the following replacement pattern: `"Season \1 Episode \2"`. You can also use the following special tags in the replacement pattern: * `{full_name}` - file name with extension -* `{name}` - filename without extension +* `{name}` - file name without extension * `{ext}` - extension ### `--wildcard` (optional) @@ -50,7 +50,7 @@ For example, if you want to only rename files with the `.mkv` extension, you can $ rmv --path /path/to/files --pattern "S(\d+)E(\d+)" --replacement "Season \1 Episode \2.{ext}" --wildcard "*.mkv" ``` -This will match all filenames in the directory that match the pattern `"S(\d+)E(\d+)"` and replace them with the pattern `"Season \1 Episode \2.{ext}"`. Only files with the `".mkv"` extension will be considered. +This will match all file names in the directory that match the pattern `"S(\d+)E(\d+)"` and replace them with the pattern `"Season \1 Episode \2.{ext}"`. Only files with the `".mkv"` extension will be considered. ```shell mv "Not Warez - S01E16 - HDTV-720p.mkv" "Season 01 Episode 16.mkv" @@ -70,21 +70,21 @@ Here are the available options: Path to the directory where the files to be renamed are located -s, --pattern - Regular expression pattern to match against the filenames in the directory. + Regular expression pattern to match against the file names in the directory. The pattern should contain match groups (expressed in parentheses). Example: "S(\d+)E(\d+)" -r, --replacement - Replacement pattern for the matched filenames. + Replacement pattern for the matched file names. You can use `\1`, `\2`, etc. to reference the match groups in the pattern. There are also the following tags available: * {full_name} - file name with extension - * {name} - filename without extension + * {name} - file name without extension * {ext} - extension Example: "Season \1 Episode \2.{ext}" -w, --wildcard - Filename wildcard to filter the files to be renamed in the directory. + File name wildcard to filter the files to be renamed in the directory. For example, "*.mkv" will match all files with the ".mkv" extension. [default: *] diff --git a/src/main.rs b/src/main.rs index 9f0307c..aa385ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,25 @@ +//! # rmv: Renaming made easy with regex +//! +//! rmv is a command-line tool that allows you to rename files in a directory using regular +//! expressions. +//! You can use it to match patterns in file names and replace them with new patterns. +//! +//! More information on README.md + use clap::Parser; use glob::glob; use regex::Regex; use std::path::{Path, PathBuf}; -#[derive(Parser, Debug)] +/// Command line parser with clap +#[derive(Parser)] #[command(author, version, about)] struct Args { /// Path to the directory where the files to be renamed are located. #[arg(short = 'i', long)] path: String, - /// Regular expression pattern to match against the filenames in the directory. + /// Regular expression pattern to match against the file names in the directory. /// /// The pattern should contain match groups (expressed in parentheses). /// @@ -18,7 +27,7 @@ struct Args { #[arg(short = 's', long)] pattern: String, - /// Replacement pattern for the matched filenames. + /// Replacement pattern for the matched file names. /// /// You can use `\1`, `\2`, etc. to reference the match groups in the pattern. /// @@ -26,7 +35,7 @@ struct Args { /// /// * {full_name} - file name with extension /// - /// * {name} - filename without extension + /// * {name} - file name without extension /// /// * {ext} - extension /// @@ -34,24 +43,36 @@ struct Args { #[arg(short = 'r', long)] replacement: String, - /// Filename wildcard to filter the files to be renamed in the directory. + /// File name wildcard to filter the files to be renamed in the directory. /// /// For example, "*.mkv" will match all files with the ".mkv" extension. #[arg(short = 'w', long, default_value = "*")] wildcard: String, } -fn get_file_list(dir_path: &str, wildcard: &str) -> Vec { - let pattern = Path::new(dir_path).join(wildcard); +/// Returns a vector of file names that match the given `wildcard` pattern in the directory specified by `path`. +/// +/// # Arguments +/// +/// * `path` - The path to the directory. +/// * `wildcard` - The wildcard pattern to match against file names. +fn get_file_list(path: &str, wildcard: &str) -> Vec { + let pattern = Path::new(path).join(wildcard); let dir_entries: Vec> = glob(&pattern.to_string_lossy()).unwrap().collect(); dir_entries .into_iter() - .filter_map(|entry| entry.ok()) + .filter_map(Result::ok) .filter(|entry: &PathBuf| entry.is_file()) .map(|entry| entry.file_name().unwrap().to_string_lossy().to_string()) .collect() } +/// Replaces extra tags in the `new file_name` with corresponding values from the `original_file_name`. +/// +/// # Arguments +/// +/// * `original_file_name` - The original name of the file. +/// * `new_file_name` - The new name of the file with tags to replace. fn replace_extra_tags(original_file_name: &str, new_file_name: &str) -> String { let path = Path::new(original_file_name); let name = path.file_stem().unwrap().to_str().unwrap(); @@ -71,6 +92,13 @@ fn replace_extra_tags(original_file_name: &str, new_file_name: &str) -> String { .fold(String::new(), |result, s| result + &s) } +/// Replaces parts of the file name that match a regular expression pattern with a replacement string. +/// +/// # Arguments +/// +/// * `file_name` - The original name of the file. +/// * `pattern` - A regular expression pattern to match against the file name. +/// * `replacement` - The replacement text for the matched pattern. fn replace_name(file_name: &str, pattern: &str, replacement: &str) -> String { let mut new_file_name = String::from(file_name); let re = Regex::new(pattern).unwrap(); @@ -78,12 +106,12 @@ fn replace_name(file_name: &str, pattern: &str, replacement: &str) -> String { let mut replaced_text = String::from(replacement); for (i, capture) in captures.iter().enumerate() { if let Some(capture) = capture { - let capture_text = capture.as_str().to_string(); - let replace_key = format!("\\{}", i); + let capture_text = capture.as_str().to_owned(); + let replace_key = format!("\\{i}"); replaced_text = replaced_text.replace(&replace_key, &capture_text); } } - new_file_name = replaced_text + new_file_name = replaced_text; } replace_extra_tags(file_name, &new_file_name) } @@ -118,7 +146,7 @@ fn name_test() { const INPUT: &str = "The Best Show - S01E16 - Bla Bla Bla HDTV-720p.mkv"; const RESULT: &str = "The Best Show - S01E16 - Bla Bla Bla HDTV-720p.crap"; - const PATTERN: &str = r""; + const PATTERN: &str = r"."; const REPLACEMENT: &str = r"{name}.crap"; assert_eq!(replace_name(INPUT, PATTERN, REPLACEMENT), RESULT); @@ -129,7 +157,7 @@ fn full_name_test() { const INPUT: &str = "The Best Show - S01E16 - Bla Bla Bla HDTV-720p.mkv"; const RESULT: &str = "REVIEW - The Best Show - S01E16 - Bla Bla Bla HDTV-720p.mkv"; - const PATTERN: &str = r""; + const PATTERN: &str = r"."; const REPLACEMENT: &str = r"REVIEW - {full_name}"; assert_eq!(replace_name(INPUT, PATTERN, REPLACEMENT), RESULT);