typos-git-commit 0.8.2

This program analyzes a json file produced with `typos` and makes commits for each correction.
Documentation
use clap::{crate_name, CommandFactory, Parser, ValueEnum};
use clap_complete::{generate, Shell};
use fluent_i18n::t;
use std::io;
use std::process::exit;

// displayed when --contributors is invoked
static CONTRIBUTORS: &str = include_str!("../Contributors");

// displayed when --changelog is invoked
static CHANGELOG: &str = include_str!("../ChangeLog");

#[derive(Parser, Debug)]
/// This program analyzes a json file produced with `typos` and makes commits
/// for each correction.
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
#[allow(clippy::struct_excessive_bools)]
pub struct Cli {
    /// typos file filename to analyze
    #[arg(long, default_value = "")]
    pub filename: String,

    /// minimum length of the typo correction to be considered as correctable automatically.
    #[arg(long, default_value_t = 6)]
    pub minlen: usize,

    /// Prints what it will do without doing it
    #[arg(long, default_value_t = false)]
    pub noop: bool,

    /// Lists typos found in a brief way (does not modify anything)
    #[arg(long)]
    pub only_list_typos: Option<TypoType>,

    /// Details output of --only-list-typos option
    #[arg(long, default_value_t = false)]
    pub details: bool,

    /// Message to be used in commits. It may use '{typo}' and '{correction}'.
    #[arg(long, default_value = "fix(typo): corrects '{typo}' into '{correction}'")]
    pub message: String,

    /// Corrects only this typo (use multiple times add a typo to be corrected)
    #[arg(long)]
    pub typo: Option<Vec<String>>,

    /// Excludes file from being included in corrections (use multiple times to exclude more than one file)
    #[arg(long)]
    pub exclude_file: Option<Vec<String>>,

    /// Excludes typo from being corrected (use multiple times to exclude more than one typo)
    #[arg(long)]
    pub exclude_typo: Option<Vec<String>>,

    /// Excludes a correction from being correctable (use multiple times to exclude more than one correction)
    #[arg(long)]
    pub exclude_correction: Option<Vec<String>>,

    /// Debug options that prints information to know what is going on
    #[arg(long, default_value_t = false)]
    pub debug: bool,

    /// prints typos-git-commit contributor's list
    #[arg(long, default_value_t = false)]
    pub contributors: bool,

    /// prints typos-git-commit changelog
    #[arg(long, default_value_t = false)]
    pub changelog: bool,

    /// prints typos-git-commit bash completion's shell script
    #[arg(long, default_value = None)]
    pub completion: Option<Shell>,
}

#[derive(ValueEnum, Debug, Clone)]
pub enum TypoType {
    All,
    Corrected,
    NotCorrected,
}

impl Cli {
    pub fn analyze() -> Self {
        /* Parsing Cli to either print contributors, changelog, shell's completion
         * scripts or be sure that --filename option has been filed.
         */
        let cli = Cli::parse();

        if cli.contributors {
            print!("{CONTRIBUTORS}");
            exit(0);
        }

        if cli.changelog {
            print!("{CHANGELOG}");
            exit(0);
        }

        if let Some(shell) = cli.completion {
            let mut cmd = Cli::command();
            generate(shell, &mut cmd, crate_name!(), &mut io::stdout());
            exit(0);
        }

        if cli.filename.is_empty() {
            let mut cmd = Cli::command();
            match cmd.print_help() {
                Ok(()) => eprintln!("\n{}", t!("cli-error-command")),
                Err(e) => eprintln!("{}", t!("cli-error-help", {"e" => e.to_string()})),
            }
            exit(1);
        }

        cli
    }
}