src/cli/args.rs

//! `clap` derive structs for every subcommand.
//!
//! Centralizing the flags makes it easy for shell completion to enumerate
//! every option without mirroring the layout.

use std::path::PathBuf;

use clap::{Args, Parser, Subcommand, ValueEnum};

#[derive(Debug, Parser)]
#[command(
    name = "ripgrab",
    version,
    about = "A Rust log tailer that applies regex filters and named-capture extraction.",
    long_about = "See https://mercemay.top/src/ripgrab/ for the full manual."
)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Command,
}

#[derive(Debug, Subcommand)]
pub enum Command {
    /// Follow one or more files and print matching lines.
    Tail(TailArgs),

    /// Grep-style one-shot scan without follow.
    Grep(GrepArgs),

    /// Emit each matching line as a JSON object on stdout.
    Json(JsonArgs),

    /// Micro-benchmark the filter pipeline on fixture data.
    Bench(BenchArgs),

    /// Print shell completion script to stdout.
    Completions(CompletionArgs),
}

#[derive(Debug, Args)]
pub struct TailArgs {
    /// Paths to tail. Use `-` to read from stdin.
    #[arg(required = true)]
    pub paths: Vec<PathBuf>,

    /// Include lines matching this regex (repeatable).
    #[arg(short = 'i', long = "include")]
    pub includes: Vec<String>,

    /// Exclude lines matching this regex (repeatable).
    #[arg(short = 'e', long = "exclude")]
    pub excludes: Vec<String>,

    /// Filter expression using the DSL (see crate docs).
    #[arg(long = "where")]
    pub where_clause: Option<String>,

    /// Start from the last N lines of the file (0 = from beginning).
    #[arg(long, default_value_t = 0)]
    pub from_end: u64,

    /// Hide the source-name prefix.
    #[arg(long)]
    pub no_origin: bool,
}

#[derive(Debug, Args)]
pub struct GrepArgs {
    #[arg(required = true)]
    pub paths: Vec<PathBuf>,

    #[arg(short = 'i', long = "include")]
    pub includes: Vec<String>,

    #[arg(long = "where")]
    pub where_clause: Option<String>,
}

#[derive(Debug, Args)]
pub struct JsonArgs {
    #[arg(required = true)]
    pub paths: Vec<PathBuf>,

    #[arg(long)]
    pub pretty: bool,

    #[arg(long = "where")]
    pub where_clause: Option<String>,
}

#[derive(Debug, Args)]
pub struct BenchArgs {
    #[arg(long, default_value = "tests/fixtures/logs/access.log")]
    pub input: PathBuf,

    #[arg(long, default_value_t = 10_000)]
    pub iterations: u32,
}

#[derive(Debug, Args)]
pub struct CompletionArgs {
    #[arg(value_enum)]
    pub shell: Shell,
}

#[derive(Debug, Copy, Clone, ValueEnum)]
pub enum Shell {
    Bash,
    Zsh,
    Fish,
    Powershell,
}