rust-parallel 1.22.0

Fast command line app in rust/tokio to run commands in parallel. Similar interface to GNU parallel or xargs.
pub mod buffered;
pub mod command_line;
pub mod pipe;
mod regex;

use std::sync::{Arc, OnceLock};

use crate::{
    command_line_args::CommandLineArgs, common::OwnedCommandAndArgs, parser::pipe::PipeModeParser,
};

use self::{
    buffered::BufferedInputLineParser, command_line::CommandLineArgsParser, regex::RegexProcessor,
};

struct ShellCommandAndArgs(Option<Vec<String>>);

impl ShellCommandAndArgs {
    fn new(command_line_args: &CommandLineArgs) -> Self {
        Self(if command_line_args.shell {
            Some(vec![
                command_line_args.shell_path.clone(),
                command_line_args.shell_argument.clone(),
            ])
        } else {
            None
        })
    }
}

fn build_owned_command_and_args(
    shell_command_and_args: &ShellCommandAndArgs,
    command_and_args: Vec<String>,
) -> Option<OwnedCommandAndArgs> {
    match &shell_command_and_args.0 {
        None => OwnedCommandAndArgs::try_from(command_and_args).ok(),
        Some(shell_command_and_args) => {
            let mut result = Vec::with_capacity(shell_command_and_args.len() + 1);

            result.extend(shell_command_and_args.iter().cloned());
            result.push(command_and_args.join(" "));

            OwnedCommandAndArgs::try_from(result).ok()
        }
    }
}

pub struct Parsers {
    buffered_input_line_parser: OnceLock<BufferedInputLineParser>,
    command_line_args_parser: OnceLock<CommandLineArgsParser>,
    pipe_mode_parser: OnceLock<PipeModeParser>,
    regex_processor: Arc<RegexProcessor>,
    command_line_args: &'static CommandLineArgs,
}

impl Parsers {
    pub fn new(command_line_args: &'static CommandLineArgs) -> anyhow::Result<Self> {
        let regex_processor = RegexProcessor::new(command_line_args)?;

        Ok(Self {
            buffered_input_line_parser: OnceLock::new(),
            command_line_args_parser: OnceLock::new(),
            pipe_mode_parser: OnceLock::new(),
            regex_processor,
            command_line_args,
        })
    }

    pub fn buffered_input_line_parser(&self) -> &BufferedInputLineParser {
        self.buffered_input_line_parser.get_or_init(|| {
            BufferedInputLineParser::new(self.command_line_args, &self.regex_processor)
        })
    }

    pub fn command_line_args_parser(&self) -> &CommandLineArgsParser {
        self.command_line_args_parser.get_or_init(|| {
            CommandLineArgsParser::new(self.command_line_args, &self.regex_processor)
        })
    }

    pub fn pipe_mode_parser(&self) -> &PipeModeParser {
        self.pipe_mode_parser
            .get_or_init(|| PipeModeParser::new(self.command_line_args))
    }
}