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