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 page token argument parser.
63#[derive(Debug, Default, Parser)]
64pub struct PageTokenArg {
65    /// Resume a listing at the given page.
66    ///
67    /// The token is the `nextPage` value a previous listing printed,
68    /// given back as it is.
69    #[arg(long = "page-token", name = "page_token", value_name = "TOKEN")]
70    pub token: Option<String>,
71}
72
73/// The log level flag parser.
74#[derive(Debug, Default, Parser)]
75pub struct LogFlags {
76    /// Filter log output by level.
77    ///
78    /// When omitted, the `RUST_LOG` environment variable is consulted
79    /// (it supports per-target filters — see the `env_logger`
80    /// documentation). When present, this flag overrides `RUST_LOG`
81    /// entirely.
82    #[arg(name = "log-level", long = "log-level", visible_alias = "log")]
83    #[arg(value_enum, value_name = "LEVEL", global = true)]
84    pub level: Option<LogLevel>,
85
86    /// Append log output to the given file instead of stderr.
87    ///
88    /// Useful when interactive prompts (which always write to stderr)
89    /// would otherwise be intermixed with log lines. The file is
90    /// opened in append mode and created if it does not exist.
91    #[arg(long = "log-file", global = true, name = "log-file")]
92    #[arg(value_name = "PATH", value_parser = path_parser)]
93    pub file: Option<PathBuf>,
94}
95
96/// Log level matching [`log::LevelFilter`].
97#[derive(Debug, Default, Clone, Copy, ValueEnum)]
98pub enum LogLevel {
99    /// No logging.
100    #[default]
101    Off,
102    /// Errors only.
103    Error,
104    /// Warnings and errors.
105    Warn,
106    /// Informational messages and above.
107    Info,
108    /// Debug messages and above.
109    Debug,
110    /// Trace messages and above (most verbose).
111    Trace,
112}
113
114impl From<LogLevel> for LevelFilter {
115    fn from(level: LogLevel) -> Self {
116        match level {
117            LogLevel::Off => Self::Off,
118            LogLevel::Error => Self::Error,
119            LogLevel::Warn => Self::Warn,
120            LogLevel::Info => Self::Info,
121            LogLevel::Debug => Self::Debug,
122            LogLevel::Trace => Self::Trace,
123        }
124    }
125}
126
127/// Builds the long version string (version, enabled features, build
128/// target and git revision) for a binary's `--version` output.
129#[macro_export]
130macro_rules! long_version {
131    () => {
132        concat!(
133            "v",
134            env!("CARGO_PKG_VERSION"),
135            " ",
136            env!("CARGO_FEATURES"),
137            "\nbuild: ",
138            env!("CARGO_CFG_TARGET_OS"),
139            " ",
140            env!("CARGO_CFG_TARGET_ENV"),
141            " ",
142            env!("CARGO_CFG_TARGET_ARCH"),
143            "\ngit: ",
144            env!("GIT_DESCRIBE"),
145            ", rev ",
146            env!("GIT_REV"),
147        )
148    };
149}
150
151/// Builds the --help footer, with link to bug tracker and sponsor.
152#[macro_export]
153macro_rules! footer {
154    () => {
155        concat!(
156	    "This program is part of Pimalaya, free software funded entirely by grants and donations.\n",
157            "If you find it useful, consider supporting its development:\n",
158	    "\n",
159	    "Report bugs to:\n",
160	    "  ", env!("CARGO_PKG_REPOSITORY"), "/issues/\n",
161	    "\n",
162	    "Sponsoring:\n",
163	    "  https://pimalaya.org/sponsor/\n",
164        )
165    };
166}