diff --git a/src/exec/job.rs b/src/exec/job.rs index 409b7e5..b85e19e 100644 --- a/src/exec/job.rs +++ b/src/exec/job.rs @@ -10,16 +10,12 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex}; use std::sync::mpsc::Receiver; -use super::TokenizedCommand; +use super::CommandTemplate; /// An event loop that listens for inputs from the `rx` receiver. Each received input will /// generate a command with the supplied command template. The generated command will then /// be executed, and this process will continue until the receiver's sender has closed. -pub fn job( - rx: Arc>>, - cmd: Arc, - out_perm: Arc>, -) { +pub fn job(rx: Arc>>, cmd: Arc, out_perm: Arc>) { loop { // Create a lock on the shared receiver for this thread. let lock = rx.lock().unwrap(); diff --git a/src/exec/mod.rs b/src/exec/mod.rs index d0dff33..ce6a7a6 100644 --- a/src/exec/mod.rs +++ b/src/exec/mod.rs @@ -24,52 +24,17 @@ use self::command::execute_command; use self::token::Token; pub use self::job::job; -/// Contains a collection of `TokenizedArgument`s that are utilized to generate command strings. +/// Represents a template that is utilized to generate command strings. /// -/// The arguments are a representation of the supplied command template, and are meant to be coupled -/// with an input in order to generate a command. The `generate_and_execute()` method will be used -/// to generate a command and execute it. +/// The template is meant to be coupled with an input in order to generate a command. The +/// `generate_and_execute()` method will be used to generate a command and execute it. #[derive(Debug, Clone, PartialEq)] -pub struct TokenizedCommand { - args: Vec, +pub struct CommandTemplate { + args: Vec, } -/// Represents a single command argument. -/// -/// The argument is either a collection of `Token`s including at least one placeholder variant, -/// or a fixed text. -#[derive(Clone, Debug, PartialEq)] -enum TokenizedArgument { - Tokens(Vec), - Text(String), -} - -impl TokenizedArgument { - pub fn generate<'a>(&'a self, path: &str) -> Cow<'a, str> { - use self::Token::*; - - match *self { - TokenizedArgument::Tokens(ref tokens) => { - let mut s = String::new(); - for token in tokens { - match *token { - Basename => s += basename(path), - BasenameNoExt => s += remove_extension(basename(path)), - NoExt => s += remove_extension(path), - Parent => s += dirname(path), - Placeholder => s += path, - Text(ref string) => s += string, - } - } - Cow::Owned(s) - } - TokenizedArgument::Text(ref text) => Cow::Borrowed(text), - } - } -} - -impl TokenizedCommand { - pub fn new(input: I) -> TokenizedCommand +impl CommandTemplate { + pub fn new(input: I) -> CommandTemplate where I: IntoIterator, S: AsRef, @@ -109,7 +74,7 @@ impl TokenizedCommand { // Without a placeholder, the argument is just fixed text. if tokens.is_empty() { - args.push(TokenizedArgument::Text(arg.to_owned())); + args.push(ArgumentTemplate::Text(arg.to_owned())); continue; } @@ -118,15 +83,15 @@ impl TokenizedCommand { tokens.push(Token::Text(arg[start..].to_owned())); } - args.push(TokenizedArgument::Tokens(tokens)); + args.push(ArgumentTemplate::Tokens(tokens)); } // If a placeholder token was not supplied, append one at the end of the command. if !has_placeholder { - args.push(TokenizedArgument::Tokens(vec![Token::Placeholder])); + args.push(ArgumentTemplate::Tokens(vec![Token::Placeholder])); } - TokenizedCommand { args: args } + CommandTemplate { args: args } } /// Generates and executes a command. @@ -149,28 +114,62 @@ impl TokenizedCommand { } } +/// Represents a template for a single command argument. +/// +/// The argument is either a collection of `Token`s including at least one placeholder variant, or +/// a fixed text. +#[derive(Clone, Debug, PartialEq)] +enum ArgumentTemplate { + Tokens(Vec), + Text(String), +} + +impl ArgumentTemplate { + pub fn generate<'a>(&'a self, path: &str) -> Cow<'a, str> { + use self::Token::*; + + match *self { + ArgumentTemplate::Tokens(ref tokens) => { + let mut s = String::new(); + for token in tokens { + match *token { + Basename => s += basename(path), + BasenameNoExt => s += remove_extension(basename(path)), + NoExt => s += remove_extension(path), + Parent => s += dirname(path), + Placeholder => s += path, + Text(ref string) => s += string, + } + } + Cow::Owned(s) + } + ArgumentTemplate::Text(ref text) => Cow::Borrowed(text), + } + } +} + #[cfg(test)] mod tests { - use super::{TokenizedCommand, TokenizedArgument, Token}; + use super::{CommandTemplate, ArgumentTemplate, Token}; #[test] fn tokens() { - let expected = TokenizedCommand { + let expected = CommandTemplate { args: vec![ - TokenizedArgument::Text("echo".into()), - TokenizedArgument::Text("${SHELL}:".into()), - TokenizedArgument::Tokens(vec![Token::Placeholder]), + ArgumentTemplate::Text("echo".into()), + ArgumentTemplate::Text("${SHELL}:".into()), + ArgumentTemplate::Tokens(vec![Token::Placeholder]), ], }; - assert_eq!(TokenizedCommand::new(&[&"echo", &"${SHELL}:"]), expected); + assert_eq!(CommandTemplate::new(&[&"echo", &"${SHELL}:"]), expected); assert_eq!( - TokenizedCommand::new(&["echo", "{.}"]), - TokenizedCommand { + CommandTemplate::new(&["echo", "{.}"]), + CommandTemplate { args: vec![ - TokenizedArgument::Text("echo".into()), - TokenizedArgument::Tokens(vec![Token::NoExt]), + ArgumentTemplate::Text("echo".into()), + ArgumentTemplate::Tokens(vec![Token::NoExt]), ], } ); diff --git a/src/internal.rs b/src/internal.rs index 972c796..604d18e 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -10,7 +10,7 @@ use std::process; use std::time; use std::io::Write; -use exec::TokenizedCommand; +use exec::CommandTemplate; use lscolors::LsColors; use walk::FileType; use regex_syntax::{Expr, ExprBuilder}; @@ -76,7 +76,7 @@ pub struct FdOptions { pub extension: Option, /// If a value is supplied, each item found will be used to generate and execute commands. - pub command: Option, + pub command: Option, /// A list of glob patterns that should be excluded from the search. pub exclude_patterns: Vec, diff --git a/src/main.rs b/src/main.rs index c1d56fe..bfdbe91 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,7 +39,7 @@ use std::time; use atty::Stream; use regex::RegexBuilder; -use exec::TokenizedCommand; +use exec::CommandTemplate; use internal::{error, pattern_has_uppercase_char, FdOptions, PathDisplay}; use lscolors::LsColors; use walk::FileType; @@ -105,7 +105,7 @@ fn main() { None }; - let command = matches.values_of("exec").map(TokenizedCommand::new); + let command = matches.values_of("exec").map(CommandTemplate::new); let config = FdOptions { case_sensitive,