use std::path::PathBuf;
use clap::{Parser, ValueEnum};
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum OutputFormat {
Auto,
Fasta,
Fastq,
}
#[derive(Parser, Debug)]
#[command(
version,
about = "Extract reads from a FASTQ or FASTA file based on taxonomic classification via Kraken2.",
author = "Sam Sims"
)]
pub struct Cli {
#[arg(short = 'i', long = "input", num_args(1..=2), required = true)]
pub input: Vec<PathBuf>,
#[arg(short = 'o', long = "output", num_args(1..=2), required = true)]
pub output: Vec<PathBuf>,
#[arg(short = 'k', long = "kraken", required = true)]
pub kraken: PathBuf,
#[arg(short = 'r', long = "report", required_if_eq_any([("parents", "true"), ("children", "true")]))]
pub report: Option<PathBuf>,
#[arg(short = 't', long = "taxid", required = true, num_args(1..))]
pub taxid: Vec<i32>,
#[arg(short = 'p', long)]
pub parents: bool,
#[arg(short = 'c', long)]
pub children: bool,
#[arg(long = "compression-format", value_parser(validate_compression))]
pub output_type: Option<niffler::Format>,
#[arg(
long = "compression-level",
default_value = "2",
value_parser(validate_compression_level)
)]
pub compression_level: niffler::Level,
#[arg(long)]
pub exclude: bool,
#[arg(long = "output-format", value_enum, default_value = "auto")]
pub output_format: OutputFormat,
#[arg(long = "summary")]
pub summary: bool,
#[arg(long = "no-header-detect")]
pub no_report_header_detect: bool,
#[arg(short, long)]
pub verbose: bool,
}
fn validate_compression(s: &str) -> Result<niffler::Format, String> {
match s {
"gz" => Ok(niffler::Format::Gzip),
"bz2" => Ok(niffler::Format::Bzip),
"none" => Ok(niffler::Format::No),
_ => Err(format!("Unknown compression type: {s}")),
}
}
fn validate_compression_level(s: &str) -> Result<niffler::Level, String> {
match s.parse::<u32>() {
Ok(1) => Ok(niffler::Level::One),
Ok(2) => Ok(niffler::Level::Two),
Ok(3) => Ok(niffler::Level::Three),
Ok(4) => Ok(niffler::Level::Four),
Ok(5) => Ok(niffler::Level::Five),
Ok(6) => Ok(niffler::Level::Six),
Ok(7) => Ok(niffler::Level::Seven),
Ok(8) => Ok(niffler::Level::Eight),
Ok(9) => Ok(niffler::Level::Nine),
_ => Err(format!(
"Unknown compression level: {s} Try a value between 1-9"
)),
}
}