Skip to main content

kira_cdh/
cli.rs

1use clap::{Parser, ValueEnum};
2use std::path::PathBuf;
3
4/// Optional high-level mode: one-set (default) or two-set (if you pass --i2 or set --mode=two).
5#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
6pub enum Mode {
7    #[value(name = "one")]
8    One,
9    #[value(name = "two")]
10    Two,
11}
12
13/// Unified CLI mirroring CD-HIT flags.
14/// Now `--mode` is optional; if omitted, it is inferred from presence/absence of `--i2`.
15#[derive(Debug, Parser)]
16#[command(
17    name = "kira-cdh",
18    author,
19    version,
20    about = "Single-binary, CLI-compatible replacement for CD-HIT"
21)]
22pub struct Args {
23    /// High-level pipeline selection: one (default) or two.
24    /// If not provided: inferred as `two` when --i2 is present, otherwise `one`.
25    #[arg(long, value_enum)]
26    pub mode: Option<Mode>,
27
28    /// -i: input FASTA/FASTQ (.gz supported)
29    #[arg(short = 'i')]
30    pub input: PathBuf,
31
32    /// -o: output prefix (creates <prefix> and <prefix>.clstr)
33    #[arg(short = 'o')]
34    pub output: PathBuf,
35
36    /// -i2: second input for two-set mode
37    #[arg(long = "i2")]
38    pub input2: Option<PathBuf>,
39
40    /// -j: input R2 for paired-end (nucleotide only; parsed for compatibility)
41    #[arg(short = 'j')]
42    pub input_r2: Option<PathBuf>,
43
44    /// --op: output R2 for paired-end (nucleotide only; parsed for compatibility)
45    #[arg(long = "op")]
46    pub output_r2: Option<PathBuf>,
47
48    /// -c: identity threshold [0..1]
49    #[arg(short = 'c', default_value_t = 0.9)]
50    pub identity: f32,
51
52    /// -G: global(1)/local(0) identity mode (parsed for compatibility)
53    #[arg(short = 'G', default_value_t = 1)]
54    pub global_identity: i32,
55
56    /// -b: alignment band width (compat)
57    #[arg(short = 'b', default_value_t = 20)]
58    pub band_width: i32,
59
60    /// -M: memory limit in MB (advisory)
61    #[arg(short = 'M', default_value_t = 0)]
62    pub mem_mb: i32,
63
64    /// -T: threads (0=all)
65    #[arg(short = 'T', default_value_t = 1)]
66    pub threads: i32,
67
68    /// -n: word length (k)
69    #[arg(short = 'n')]
70    pub word_len: Option<usize>,
71
72    /// -l: minimal length
73    #[arg(short = 'l', default_value_t = 10)]
74    pub min_len: i32,
75
76    /// -t: tolerance
77    #[arg(short = 't', default_value_t = 2)]
78    pub tolerance: i32,
79
80    /// -d: description length in output (0=full)
81    #[arg(short = 'd', default_value_t = 0)]
82    pub desc_len: i32,
83
84    /// -s: length diff cutoff (fraction)
85    #[arg(short = 's', default_value_t = 0.0)]
86    pub s_len_diff_frac: f32,
87
88    /// -S: length diff cutoff (absolute)
89    #[arg(short = 'S', default_value_t = 999999)]
90    pub S_len_diff_abs: i32,
91
92    /// -aL: alignment coverage (longer)
93    #[arg(long = "aL", default_value_t = 0.0)]
94    pub aL: f32,
95
96    /// -AL: coverage control (longer, absolute)
97    #[arg(long = "AL", default_value_t = 99999999)]
98    pub AL: i32,
99
100    /// -aS: alignment coverage (shorter)
101    #[arg(long = "aS", default_value_t = 0.0)]
102    pub aS: f32,
103
104    /// -AS: coverage control (shorter, absolute)
105    #[arg(long = "AS", default_value_t = 99999999)]
106    pub AS: i32,
107
108    /// -A: minimal coverage for both
109    #[arg(short = 'A', default_value_t = 0)]
110    pub A_both_min: i32,
111
112    /// -uL: max unmatched % (longer)
113    #[arg(long = "uL", default_value_t = 1.0)]
114    pub uL: f32,
115
116    /// -uS: max unmatched % (shorter)
117    #[arg(long = "uS", default_value_t = 1.0)]
118    pub uS: f32,
119
120    /// -U: max unmatched absolute length
121    #[arg(short = 'U', default_value_t = 99999999)]
122    pub U_unmatched_len: i32,
123
124    /// -p: print alignment overlap in .clstr
125    #[arg(short = 'p', default_value_t = 0)]
126    pub print_overlap: i32,
127
128    /// -g: greedy mode (0 fast, 1 accurate)
129    #[arg(short = 'g', default_value_t = 0)]
130    pub greedy: i32,
131
132    /// -sc: sort clusters by size
133    #[arg(long = "sc", default_value_t = 0)]
134    pub sort_clusters_by_size: i32,
135
136    /// -sf: sort fasta by cluster size
137    #[arg(long = "sf", default_value_t = 0)]
138    pub sort_fasta_by_size: i32,
139
140    /// --bak: write backup cluster file
141    #[arg(long = "bak", default_value_t = 0)]
142    pub write_backup: i32,
143
144    /// -P: paired-end input (nucleotide modes)
145    #[arg(short = 'P', default_value_t = 0)]
146    pub paired_end: i32,
147
148    /// --cx: trim R1
149    #[arg(long = "cx", default_value_t = 0)]
150    pub cx_trim_r1: i32,
151
152    /// --cy: trim R2
153    #[arg(long = "cy", default_value_t = 0)]
154    pub cy_trim_r2: i32,
155
156    /// --ap: alignment position constraint
157    #[arg(long = "ap", default_value_t = 0)]
158    pub ap_pos_constraint: i32,
159
160    /// -r: strand mode (0 +/+; 1 both)
161    #[arg(short = 'r', default_value_t = 1)]
162    pub r_strand_mode: i32,
163
164    /// --mask: masking letters
165    #[arg(long = "mask")]
166    pub mask_letters: Option<String>,
167
168    /// --match: score
169    #[arg(long = "match", default_value_t = 2)]
170    pub score_match: i32,
171
172    /// --mismatch: score
173    #[arg(long = "mismatch", default_value_t = -2)]
174    pub score_mismatch: i32,
175
176    /// --gap: open
177    #[arg(long = "gap", default_value_t = -6)]
178    pub score_gap_open: i32,
179
180    /// --gap-ext: extension
181    #[arg(long = "gap-ext", default_value_t = -1)]
182    pub score_gap_ext: i32,
183}