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}