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