tex_fmt/
cli.rs

1//! Functionality to parse CLI arguments
2
3use crate::args::{OptionArgs, TabChar};
4use clap::ArgMatches;
5use clap_complete::{generate, Shell};
6use clap_mangen::Man;
7use log::LevelFilter;
8use std::io;
9
10// Get the clap CLI command from a separate file
11include!("command.rs");
12
13/// Read `ArgMatches` flag into `Option<bool>`
14fn get_flag(arg_matches: &ArgMatches, flag: &str) -> Option<bool> {
15    if arg_matches.get_flag(flag) {
16        Some(true)
17    } else {
18        None
19    }
20}
21
22/// Parse CLI arguments into `OptionArgs` struct
23///
24/// # Panics
25///
26/// This function panics if the man page cannot be written.
27pub fn get_cli_args(matches: Option<ArgMatches>) -> OptionArgs {
28    let mut command = get_cli_command();
29    let arg_matches = match matches {
30        Some(m) => m,
31        None => command.clone().get_matches(),
32    };
33
34    // Generate completions and exit
35    if let Some(shell) = arg_matches.get_one::<Shell>("completion") {
36        generate(*shell, &mut command, "tex-fmt", &mut io::stdout());
37        std::process::exit(0);
38    }
39
40    // Generate man page and exit
41    if arg_matches.get_flag("man") {
42        let man = Man::new(command);
43        man.render(&mut io::stdout()).unwrap();
44        std::process::exit(0);
45    }
46
47    let wrap: Option<bool> = if arg_matches.get_flag("nowrap") {
48        Some(false)
49    } else {
50        None
51    };
52    let tabchar = if arg_matches.get_flag("usetabs") {
53        Some(TabChar::Tab)
54    } else {
55        None
56    };
57    let verbosity = if arg_matches.get_flag("trace") {
58        Some(LevelFilter::Trace)
59    } else if arg_matches.get_flag("verbose") {
60        Some(LevelFilter::Info)
61    } else if arg_matches.get_flag("quiet") {
62        Some(LevelFilter::Error)
63    } else {
64        None
65    };
66    let args = OptionArgs {
67        check: get_flag(&arg_matches, "check"),
68        print: get_flag(&arg_matches, "print"),
69        fail_on_change: get_flag(&arg_matches, "fail-on-change"),
70        wrap,
71        wraplen: arg_matches.get_one::<u8>("wraplen").copied(),
72        wrapmin: None,
73        tabsize: arg_matches.get_one::<u8>("tabsize").copied(),
74        tabchar,
75        stdin: get_flag(&arg_matches, "stdin"),
76        config: arg_matches.get_one::<PathBuf>("config").cloned(),
77        noconfig: get_flag(&arg_matches, "noconfig"),
78        lists: vec![],
79        verbatims: vec![],
80        no_indent_envs: vec![],
81        wrap_chars: vec![],
82        verbosity,
83        arguments: get_flag(&arg_matches, "args"),
84        files: arg_matches
85            .get_many::<String>("files")
86            .unwrap_or_default()
87            .map(PathBuf::from)
88            .collect::<Vec<PathBuf>>(),
89        recursive: get_flag(&arg_matches, "recursive"),
90    };
91    args
92}