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 "Report bugs to:\n",
157 " ", env!("CARGO_PKG_REPOSITORY"), "/issues/\n",
158 "\n",
159 "Sponsoring:\n",
160 " https://pimalaya.org/sponsor/\n",
161 "\n",
162 "This program is part of Pimalaya, free software funded entirely by grants and donations.\n",
163 "If you find it useful, consider sponsoring its development.",
164 )
165 };
166}