Skip to main content

pimalaya_cli/clap/
args.rs

1//! Shared clap argument and flag parsers.
2
3use std::path::PathBuf;
4
5use clap::{Parser, ValueEnum};
6use log::LevelFilter;
7
8use crate::clap::parsers::path_parser;
9
10/// The account name flag parser.
11#[derive(Debug, Default, Parser)]
12pub struct AccountFlag {
13    /// Override the default account.
14    ///
15    /// An account name corresponds to an entry in the table at the
16    /// root level of your TOML configuration file.
17    #[arg(long = "account", short = 'a', global = true)]
18    #[arg(name = "account_name", value_name = "NAME")]
19    pub name: Option<String>,
20}
21
22/// The config path flags parser.
23#[derive(Debug, Default, Parser)]
24pub struct ConfigFlags {
25    /// Override the default configuration file path.
26    ///
27    /// The given paths are shell-expanded then canonicalized (if
28    /// applicable). If the first path does not point to a valid file, the
29    /// wizard will propose to assist you in the creation of the configuration
30    /// file. Other paths are merged with the first one, which allows you to
31    /// separate your public config from your private(s) one(s). Multiple paths
32    /// can also be provided by delimiting them with `:` (like `$PATH` in a
33    /// POSIX shell).
34    #[arg(short = 'c', long = "config", global = true)]
35    #[arg(name = "config_paths", value_name = "PATH")]
36    #[arg(value_parser = path_parser, value_delimiter = ':')]
37    pub paths: Vec<PathBuf>,
38}
39
40/// The account name flag parser.
41#[derive(Debug, Default, Parser)]
42pub struct AccountArg {
43    /// Override the default account.
44    ///
45    /// An account name corresponds to an entry in the table at the
46    /// root level of your TOML configuration file.
47    #[arg(name = "account_name", value_name = "NAME")]
48    pub name: String,
49}
50
51/// The JSON output flag parser.
52#[derive(Debug, Default, Parser)]
53pub struct JsonFlag {
54    /// Enable JSON output.
55    ///
56    /// When set, command output (data or errors) is displayed as JSON
57    /// string.
58    #[arg(long = "json", name = "json", global = true)]
59    pub enabled: bool,
60}
61
62/// The log level flag parser.
63#[derive(Debug, Default, Parser)]
64pub struct LogFlags {
65    /// Filter log output by level.
66    ///
67    /// When omitted, the `RUST_LOG` environment variable is consulted
68    /// (it supports per-target filters — see the `env_logger`
69    /// documentation). When present, this flag overrides `RUST_LOG`
70    /// entirely.
71    #[arg(name = "log-level", long = "log-level", visible_alias = "log")]
72    #[arg(value_enum, value_name = "LEVEL", global = true)]
73    pub level: Option<LogLevel>,
74
75    /// Append log output to the given file instead of stderr.
76    ///
77    /// Useful when interactive prompts (which always write to stderr)
78    /// would otherwise be intermixed with log lines. The file is
79    /// opened in append mode and created if it does not exist.
80    #[arg(long = "log-file", global = true, name = "log-file")]
81    #[arg(value_name = "PATH", value_parser = path_parser)]
82    pub file: Option<PathBuf>,
83}
84
85/// Log level matching [`log::LevelFilter`].
86#[derive(Debug, Default, Clone, Copy, ValueEnum)]
87pub enum LogLevel {
88    /// No logging.
89    #[default]
90    Off,
91    /// Errors only.
92    Error,
93    /// Warnings and errors.
94    Warn,
95    /// Informational messages and above.
96    Info,
97    /// Debug messages and above.
98    Debug,
99    /// Trace messages and above (most verbose).
100    Trace,
101}
102
103impl From<LogLevel> for LevelFilter {
104    fn from(level: LogLevel) -> Self {
105        match level {
106            LogLevel::Off => Self::Off,
107            LogLevel::Error => Self::Error,
108            LogLevel::Warn => Self::Warn,
109            LogLevel::Info => Self::Info,
110            LogLevel::Debug => Self::Debug,
111            LogLevel::Trace => Self::Trace,
112        }
113    }
114}
115
116/// Builds the long version string (version, enabled features, build
117/// target and git revision) for a binary's `--version` output.
118#[macro_export]
119macro_rules! long_version {
120    () => {
121        concat!(
122            "v",
123            env!("CARGO_PKG_VERSION"),
124            " ",
125            env!("CARGO_FEATURES"),
126            "\nbuild: ",
127            env!("CARGO_CFG_TARGET_OS"),
128            " ",
129            env!("CARGO_CFG_TARGET_ENV"),
130            " ",
131            env!("CARGO_CFG_TARGET_ARCH"),
132            "\ngit: ",
133            env!("GIT_DESCRIBE"),
134            ", rev ",
135            env!("GIT_REV"),
136        )
137    };
138}