Skip to main content

fibertools_rs/
cli.rs

1use anstyle;
2use clap::{Args, Command, CommandFactory, Parser, Subcommand};
3use clap_complete::{generate, Generator, Shell};
4use std::{fmt::Debug, io};
5
6// Reference the modules for the subcommands
7mod center_opts;
8mod clear_kinetics_opts;
9mod ddda_to_m6a_opts;
10mod decorator_opts;
11mod extract_opts;
12mod fiber_hmm;
13mod fire_opts;
14mod footprint_opts;
15mod nucleosome_opts;
16mod pg_inject_opts;
17mod pg_lift_opts;
18mod pg_pansn_opts;
19mod pileup_opts;
20mod predict_opts;
21mod qc_opts;
22mod strip_basemods_opts;
23mod validate_opts;
24
25// include the subcommand modules as top level functions and structs in the cli module
26pub use center_opts::*;
27pub use clear_kinetics_opts::*;
28pub use ddda_to_m6a_opts::*;
29pub use decorator_opts::*;
30pub use extract_opts::*;
31pub use fiber_hmm::*;
32pub use fire_opts::*;
33pub use footprint_opts::*;
34pub use nucleosome_opts::*;
35pub use pg_inject_opts::*;
36pub use pg_lift_opts::*;
37pub use pg_pansn_opts::*;
38pub use pileup_opts::*;
39pub use predict_opts::*;
40pub use qc_opts::*;
41pub use strip_basemods_opts::*;
42pub use validate_opts::ValidateOptions;
43
44//
45// The main CLI structure
46//
47#[derive(Parser)]
48#[clap(
49    author,
50    version,
51    about,
52    propagate_version = true,
53    subcommand_required = true,
54    infer_subcommands = true,
55    arg_required_else_help = true
56)]
57#[command(version = &**crate::FULL_VERSION)]
58#[command(styles=get_styles())]
59pub struct Cli {
60    #[clap(flatten)]
61    pub global: GlobalOpts,
62    /// Subcommands for fibertools-rs
63    #[clap(subcommand)]
64    pub command: Option<Commands>,
65}
66
67//
68// Global options available to all subcommands
69//
70#[derive(Debug, Args, PartialEq, Eq)]
71pub struct GlobalOpts {
72    /// Threads
73    #[clap(
74        global = true,
75        short,
76        long,
77        default_value_t = 8,
78        help_heading = "Global-Options"
79    )]
80    pub threads: usize,
81
82    /// Logging level [-v: Info, -vv: Debug, -vvv: Trace]
83    #[clap(
84        global = true,
85        short,
86        long,
87        action = clap::ArgAction::Count,
88        help_heading = "Debug-Options"
89    )]
90    pub verbose: u8,
91    /// Turn off all logging
92    #[clap(global = true, long, help_heading = "Debug-Options")]
93    pub quiet: bool,
94}
95
96impl std::default::Default for GlobalOpts {
97    fn default() -> Self {
98        Self {
99            threads: 8,
100            verbose: 0,
101            quiet: false,
102        }
103    }
104}
105
106//
107// This structure contains all the subcommands and their help descriptions.
108//
109#[derive(Subcommand, Debug)]
110pub enum Commands {
111    /// Predict m6A positions using HiFi kinetics data and encode the results in the MM and ML bam tags. Also adds nucleosome (nl, ns) and MTase sensitive patches (al, as).
112    #[clap(visible_aliases = &["m6A", "m6a"])]
113    PredictM6A(PredictM6AOptions),
114    /// Add nucleosomes to a bam file with m6a predictions
115    AddNucleosomes(AddNucleosomeOptions),
116    /// Add FIREs (Fiber-seq Inferred Regulatory Elements) to a bam file with m6a predictions
117    Fire(FireOptions),
118    /// Extract fiberseq data into plain text files.
119    ///
120    /// See https://fiberseq.github.io/fibertools/extracting/extract.html for a description of the outputs.
121    #[clap(visible_aliases = &["ex", "e"])]
122    Extract(ExtractOptions),
123    /// This command centers fiberseq data around given reference positions. This is useful for making aggregate m6A and CpG observations, as well as visualization of SVs.
124    ///
125    ///  See https://fiberseq.github.io/fibertools/extracting/center.html for a description of the output.
126    #[clap(visible_aliases = &["c", "ct"])]
127    Center(CenterOptions),
128    /// Infer footprints from fiberseq data
129    Footprint(FootprintOptions),
130    /// Collect QC metrics from a fiberseq bam file
131    Qc(QcOpts),
132    /// Make decorated bed files for fiberseq data
133    TrackDecorators(DecoratorOptions),
134    /// Make a pileup track of Fiber-seq features from a FIRE bam
135    Pileup(PileupOptions),
136    /// Remove HiFi kinetics tags from the input bam file
137    ClearKinetics(ClearKineticsOptions),
138    /// Strip out select base modifications
139    StripBasemods(StripBasemodsOptions),
140    /// Convert a DddA BAM file to pseudo m6A BAM file
141    DddaToM6a(DddaToM6aOptions),
142    /// Apply FiberHMM to a bam file
143    FiberHmm(FiberHmmOptions),
144    /// Validate a Fiber-seq BAM file for m6A, nucleosome, and optionally FIRE calls
145    Validate(ValidateOptions),
146    /// Create a mock BAM file from a reference FASTA with perfectly aligned sequences
147    #[clap(name = "pg-inject")]
148    PgInject(PgInjectOptions),
149    /// Lift annotations through a pangenome graph from source to target coordinates
150    #[clap(name = "pg-lift")]
151    PgLift(PgLiftOptions),
152    /// Add or strip panSN-spec prefixes from BAM contig names
153    #[clap(name = "pg-pansn")]
154    PgPansn(PgPansnOptions),
155    /// Make command line completions
156    #[clap(hide = true)]
157    Completions(CompletionOptions),
158    /// Make a man page for fibertools-rs
159    ///
160    /// Writes file for `man` to stdout.
161    #[clap(hide = true)]
162    Man {},
163}
164
165//
166// CLI utility functions
167//
168
169/// This function is used to generate the styles for the CLI help messages.
170fn get_styles() -> clap::builder::Styles {
171    let cmd_color = anstyle::AnsiColor::Magenta;
172    let header_color = anstyle::AnsiColor::BrightGreen;
173    let placeholder_color = anstyle::AnsiColor::Cyan;
174    let header_style = anstyle::Style::new()
175        .bold()
176        .underline()
177        .fg_color(Some(anstyle::Color::Ansi(header_color)));
178    let cmd_style = anstyle::Style::new()
179        .bold()
180        .fg_color(Some(anstyle::Color::Ansi(cmd_color)));
181    let placeholder_style = anstyle::Style::new()
182        //.bold()
183        .fg_color(Some(anstyle::Color::Ansi(placeholder_color)));
184    clap::builder::Styles::styled()
185        .header(header_style)
186        .literal(cmd_style)
187        .usage(header_style)
188        .placeholder(placeholder_style)
189}
190
191pub fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
192    generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout());
193}
194
195pub fn make_cli_parse() -> Cli {
196    Cli::parse()
197}
198
199pub fn make_cli_app() -> Command {
200    Cli::command()
201}
202
203#[derive(Args, Debug, PartialEq, Eq)]
204pub struct CompletionOptions {
205    /// If provided, outputs the completion file for given shell
206    #[arg(value_enum)]
207    pub shell: Shell,
208}