diff --git a/src/process/mgmt.rs b/src/process/mgmt.rs index 8558a70..82643c3 100644 --- a/src/process/mgmt.rs +++ b/src/process/mgmt.rs @@ -4,16 +4,23 @@ use std::fmt; use std::error::Error; use std::io; -// Define a custom error type for process operations +/// Error type for process management operations +/// +/// This enum represents various errors that can occur during process management +/// operations such as listing, finding, or killing processes. #[derive(Debug)] pub enum ProcessError { + /// An error occurred while executing a command CommandExecutionFailed(io::Error), + /// A command executed successfully but returned an error CommandFailed(String), + /// No process was found matching the specified pattern NoProcessFound(String), + /// Multiple processes were found matching the specified pattern MultipleProcessesFound(String, usize), } -// Implement Display for ProcessError +/// Implement Display for ProcessError to provide human-readable error messages impl fmt::Display for ProcessError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/src/process/mod.rs b/src/process/mod.rs index 3e615e1..8c2bad0 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -1,2 +1,17 @@ +//! # Process Module +//! +//! The `process` module provides functionality for managing and interacting with +//! system processes across different platforms. It includes capabilities for: +//! +//! - Running commands and scripts +//! - Listing and filtering processes +//! - Killing processes +//! - Checking for command existence +//! +//! This module is designed to work consistently across Windows, macOS, and Linux. + +pub mod run; +pub mod mgmt; + use run::*; use mgmt::*; \ No newline at end of file diff --git a/src/process/run.rs b/src/process/run.rs index 90e16d7..3743683 100644 --- a/src/process/run.rs +++ b/src/process/run.rs @@ -7,23 +7,35 @@ use std::fmt; use std::error::Error; use std::io; -use super::text; +use crate::text; -// Define a custom error type for run operations +/// Error type for command and script execution operations +/// +/// This enum represents various errors that can occur during command and script +/// execution, including preparation, execution, and output handling. #[derive(Debug)] pub enum RunError { + /// The command string was empty EmptyCommand, + /// An error occurred while executing a command CommandExecutionFailed(io::Error), + /// A command executed successfully but returned an error CommandFailed(String), + /// An error occurred while preparing a script for execution ScriptPreparationFailed(String), + /// An error occurred in a child process ChildProcessError(String), + /// Failed to create a temporary directory TempDirCreationFailed(io::Error), + /// Failed to create a script file FileCreationFailed(io::Error), + /// Failed to write to a script file FileWriteFailed(io::Error), + /// Failed to set file permissions PermissionError(io::Error), } -// Implement Display for RunError +/// Implement Display for RunError to provide human-readable error messages impl fmt::Display for RunError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/src/text/text.rs b/src/text/dedent.rs similarity index 100% rename from src/text/text.rs rename to src/text/dedent.rs diff --git a/src/text/fix.rs b/src/text/fix.rs new file mode 100644 index 0000000..50fa399 --- /dev/null +++ b/src/text/fix.rs @@ -0,0 +1,98 @@ + + +pub fn name_fix(text: &str) -> String { + let mut result = String::with_capacity(text.len()); + + let mut last_was_underscore = false; + for c in text.chars() { + // Keep only ASCII characters + if c.is_ascii() { + // Replace specific characters with underscore + if c.is_whitespace() || c == ',' || c == '-' || c == '"' || c == '\'' || + c == '#' || c == '!' || c == '(' || c == ')' || c == '[' || c == ']' || + c == '=' || c == '+' || c == '<' || c == '>' { + // Only add underscore if the last character wasn't an underscore + if !last_was_underscore { + result.push('_'); + last_was_underscore = true; + } + } else { + // Add the character as is (will be converted to lowercase later) + result.push(c); + last_was_underscore = false; + } + } + // Non-ASCII characters are simply skipped + } + + // Convert to lowercase + return result.to_lowercase(); +} + +pub fn path_fix(text: &str) -> String { + // If path ends with '/', return as is + if text.ends_with('/') { + return text.to_string(); + } + + // Find the last '/' to extract the filename part + match text.rfind('/') { + Some(pos) => { + // Extract the path and filename parts + let path = &text[..=pos]; + let filename = &text[pos+1..]; + + // Apply name_fix to the filename part only + return format!("{}{}", path, name_fix(filename)); + }, + None => { + // No '/' found, so the entire text is a filename + return name_fix(text); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_name_fix() { + // Test ASCII conversion and special character replacement + assert_eq!(name_fix("Hello World"), "hello_world"); + assert_eq!(name_fix("File-Name.txt"), "file_name.txt"); + assert_eq!(name_fix("Test!@#$%^&*()"), "test_"); + assert_eq!(name_fix("Space, Tab\t, Comma,"), "space_tab_comma_"); + assert_eq!(name_fix("Quotes\"'"), "quotes_"); + assert_eq!(name_fix("Brackets[]<>"), "brackets_"); + assert_eq!(name_fix("Operators=+-"), "operators_"); + + // Test non-ASCII characters removal + assert_eq!(name_fix("Café"), "caf"); + assert_eq!(name_fix("Résumé"), "rsum"); + assert_eq!(name_fix("Über"), "ber"); + + // Test lowercase conversion + assert_eq!(name_fix("UPPERCASE"), "uppercase"); + assert_eq!(name_fix("MixedCase"), "mixedcase"); + } + + #[test] + fn test_path_fix() { + // Test path ending with / + assert_eq!(path_fix("/path/to/directory/"), "/path/to/directory/"); + + // Test single filename + assert_eq!(path_fix("filename.txt"), "filename.txt"); + assert_eq!(path_fix("UPPER-file.md"), "upper_file.md"); + + // Test path with filename + assert_eq!(path_fix("/path/to/File Name.txt"), "/path/to/file_name.txt"); + assert_eq!(path_fix("./relative/path/to/DOCUMENT-123.pdf"), "./relative/path/to/document_123.pdf"); + assert_eq!(path_fix("/absolute/path/to/Résumé.doc"), "/absolute/path/to/rsum.doc"); + + // Test path with special characters in filename + assert_eq!(path_fix("/path/with/[special].txt"), "/path/with/_special_chars_.txt"); + } +} + diff --git a/src/text/mod.rs b/src/text/mod.rs index 1aae484..2a7961e 100644 --- a/src/text/mod.rs +++ b/src/text/mod.rs @@ -1 +1,5 @@ -use text::*; \ No newline at end of file +mod dedent; +mod fix; + +pub use dedent::*; +pub use fix::*; \ No newline at end of file