1/// Allows you to pull the version from your Cargo.toml at compile time as
2/// `MAJOR.MINOR.PATCH_PKGVERSION_PRE`
3///
4/// # Examples
5///
6/// ```no_run
7/// # use clap_builder as clap;
8/// # use clap::crate_version;
9/// # use clap::Command;
10/// let m = Command::new("cmd")
11/// .version(crate_version!())
12/// .get_matches();
13/// ```
14#[cfg(feature = "cargo")]
15#[macro_export]
16macro_rules! crate_version {
17 () => {
18 env!("CARGO_PKG_VERSION")
19 };
20}
21
22/// Allows you to pull the authors for the command from your Cargo.toml at
23/// compile time in the form:
24/// `"author1 lastname <author1@example.com>:author2 lastname <author2@example.com>"`
25///
26/// You can replace the colons with a custom separator by supplying a
27/// replacement string, so, for example,
28/// `crate_authors!(",\n")` would become
29/// `"author1 lastname <author1@example.com>,\nauthor2 lastname <author2@example.com>,\nauthor3 lastname <author3@example.com>"`
30///
31/// # Examples
32///
33/// ```no_run
34/// # use clap_builder as clap;
35/// # use clap::crate_authors;
36/// # use clap::Command;
37/// let m = Command::new("cmd")
38/// .author(crate_authors!("\n"))
39/// .get_matches();
40/// ```
41#[cfg(feature = "cargo")]
42#[macro_export]
43macro_rules! crate_authors {
44 ($sep:expr) => {{
45 static authors: &str = env!("CARGO_PKG_AUTHORS");
46 if authors.contains(':') {
47 static CACHED: std::sync::OnceLock<String> = std::sync::OnceLock::new();
48 let s = CACHED.get_or_init(|| authors.replace(':', $sep));
49 let s: &'static str = &*s;
50 s
51 } else {
52 authors
53 }
54 }};
55 () => {
56 env!("CARGO_PKG_AUTHORS")
57 };
58}
59
60/// Allows you to pull the description from your Cargo.toml at compile time.
61///
62/// # Examples
63///
64/// ```no_run
65/// # use clap_builder as clap;
66/// # use clap::crate_description;
67/// # use clap::Command;
68/// let m = Command::new("cmd")
69/// .about(crate_description!())
70/// .get_matches();
71/// ```
72#[cfg(feature = "cargo")]
73#[macro_export]
74macro_rules! crate_description {
75 () => {
76 env!("CARGO_PKG_DESCRIPTION")
77 };
78}
79
80/// Allows you to pull the name from your Cargo.toml at compile time.
81///
82/// **NOTE:** This macro extracts the name from an environment variable `CARGO_PKG_NAME`.
83/// When the crate name is set to something different from the package name,
84/// use environment variables `CARGO_CRATE_NAME` or `CARGO_BIN_NAME`.
85/// See [the Cargo Book](https://doc.rust-lang.org/cargo/reference/environment-variables.html)
86/// for more information.
87///
88/// # Examples
89///
90/// ```no_run
91/// # use clap_builder as clap;
92/// # use clap::crate_name;
93/// # use clap::Command;
94/// let m = Command::new(crate_name!())
95/// .get_matches();
96/// ```
97#[cfg(feature = "cargo")]
98#[macro_export]
99macro_rules! crate_name {
100 () => {
101 env!("CARGO_PKG_NAME")
102 };
103}
104
105/// Allows you to build the `Command` instance from your Cargo.toml at compile time.
106///
107/// **NOTE:** Changing the values in your `Cargo.toml` does not trigger a re-build automatically,
108/// and therefore won't change the generated output until you recompile.
109///
110/// In some cases you can "trick" the compiler into triggering a rebuild when your
111/// `Cargo.toml` is changed by including this in your `src/main.rs` file
112/// `include_str!("../Cargo.toml");`
113///
114/// # Examples
115///
116/// ```no_run
117/// # use clap_builder as clap;
118/// # use clap::command;
119/// let m = command!().get_matches();
120/// ```
121#[cfg(feature = "cargo")]
122#[macro_export]
123macro_rules! command {
124 () => {{
125 $crate::command!($crate::crate_name!())
126 }};
127 ($name:expr) => {{
128 let mut cmd = $crate::Command::new($name).version($crate::crate_version!());
129
130 let author = $crate::crate_authors!();
131 if !author.is_empty() {
132 cmd = cmd.author(author)
133 }
134
135 let about = $crate::crate_description!();
136 if !about.is_empty() {
137 cmd = cmd.about(about)
138 }
139
140 cmd
141 }};
142}
143
144/// Requires `cargo` feature flag to be enabled.
145#[cfg(not(feature = "cargo"))]
146#[macro_export]
147macro_rules! command {
148 () => {{
149 compile_error!("`cargo` feature flag is required");
150 }};
151 ($name:expr) => {{
152 compile_error!("`cargo` feature flag is required");
153 }};
154}
155
156#[doc(hidden)]
157#[macro_export]
158macro_rules! arg_impl {
159 ( @string $val:ident ) => {
160 stringify!($val)
161 };
162 ( @string $val:literal ) => {{
163 let ident_or_string_literal: &str = $val;
164 ident_or_string_literal
165 }};
166 ( @string $val:tt ) => {
167 ::std::compile_error!("Only identifiers or string literals supported");
168 };
169 ( @string ) => {
170 None
171 };
172
173 ( @char $val:ident ) => {{
174 let ident_or_char_literal = stringify!($val);
175 debug_assert_eq!(
176 ident_or_char_literal.len(),
177 1,
178 "Single-letter identifier expected, got {ident_or_char_literal}",
179 );
180 ident_or_char_literal.chars().next().unwrap()
181 }};
182 ( @char $val:literal ) => {{
183 let ident_or_char_literal: char = $val;
184 ident_or_char_literal
185 }};
186 ( @char ) => {{
187 None
188 }};
189
190 (
191 @arg
192 ($arg:expr)
193 --$long:ident
194 $($tail:tt)*
195 ) => {{
196 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
197 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
198
199 let mut arg = $arg;
200 let long = $crate::arg_impl! { @string $long };
201 if arg.get_id() == "" {
202 arg = arg.id(long);
203 }
204 let action = $crate::ArgAction::SetTrue;
205 let arg = arg
206 .long(long)
207 .action(action);
208 let arg = $crate::arg_impl! {
209 @arg (arg) $($tail)*
210 };
211 arg
212 }};
213 (
214 @arg
215 ($arg:expr)
216 --$long:literal
217 $($tail:tt)*
218 ) => {{
219 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
220 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
221
222 let mut arg = $arg;
223 let long = $crate::arg_impl! { @string $long };
224 if arg.get_id() == "" {
225 arg = arg.id(long);
226 }
227 let action = $crate::ArgAction::SetTrue;
228 let arg = arg
229 .long(long)
230 .action(action);
231 let arg = $crate::arg_impl! {
232 @arg (arg) $($tail)*
233 };
234 arg
235 }};
236 (
237 @arg
238 ($arg:expr)
239 -$short:ident
240 $($tail:tt)*
241 ) => {{
242 debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
243 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
244 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
245
246 let action = $crate::ArgAction::SetTrue;
247 let arg = $arg
248 .short($crate::arg_impl! { @char $short })
249 .action(action);
250 let arg = $crate::arg_impl! {
251 @arg (arg) $($tail)*
252 };
253 arg
254 }};
255 (
256 @arg
257 ($arg:expr)
258 -$short:literal
259 $($tail:tt)*
260 ) => {{
261 debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
262 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
263 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
264
265 let action = $crate::ArgAction::SetTrue;
266 let arg = $arg
267 .short($crate::arg_impl! { @char $short })
268 .action(action);
269 let arg = $crate::arg_impl! {
270 @arg (arg) $($tail)*
271 };
272 arg
273 }};
274 (
275 @arg
276 ($arg:expr)
277 <$value_name:ident>
278 $($tail:tt)*
279 ) => {{
280 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
281 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
282
283 let mut arg = $arg;
284
285 if arg.get_long().is_none() && arg.get_short().is_none() {
286 arg = arg.required(true);
287 }
288
289 let value_name = $crate::arg_impl! { @string $value_name };
290 if arg.get_id() == "" {
291 arg = arg.id(value_name);
292 }
293 let arg = arg
294 .value_name(value_name)
295 .action($crate::ArgAction::Set);
296 let arg = $crate::arg_impl! {
297 @arg (arg) $($tail)*
298 };
299 arg
300 }};
301 (
302 @arg
303 ($arg:expr)
304 <$value_name:literal>
305 $($tail:tt)*
306 ) => {{
307 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
308 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
309
310 let mut arg = $arg;
311
312 if arg.get_long().is_none() && arg.get_short().is_none() {
313 arg = arg.required(true);
314 }
315
316 let value_name = $crate::arg_impl! { @string $value_name };
317 if arg.get_id() == "" {
318 arg = arg.id(value_name);
319 }
320 let arg = arg
321 .value_name(value_name)
322 .action($crate::ArgAction::Set);
323 let arg = $crate::arg_impl! {
324 @arg (arg) $($tail)*
325 };
326 arg
327 }};
328 (
329 @arg
330 ($arg:expr)
331 [$value_name:ident]
332 $($tail:tt)*
333 ) => {{
334 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
335 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
336
337 let mut arg = $arg;
338
339 if arg.get_long().is_none() && arg.get_short().is_none() {
340 arg = arg.required(false);
341 } else {
342 arg = arg.num_args(0..=1);
343 }
344
345 let value_name = $crate::arg_impl! { @string $value_name };
346 if arg.get_id() == "" {
347 arg = arg.id(value_name);
348 }
349 let arg = arg
350 .value_name(value_name)
351 .action($crate::ArgAction::Set);
352 let arg = $crate::arg_impl! {
353 @arg (arg) $($tail)*
354 };
355 arg
356 }};
357 (
358 @arg
359 ($arg:expr)
360 [$value_name:literal]
361 $($tail:tt)*
362 ) => {{
363 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
364 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
365
366 let mut arg = $arg;
367
368 if arg.get_long().is_none() && arg.get_short().is_none() {
369 arg = arg.required(false);
370 } else {
371 arg = arg.num_args(0..=1);
372 }
373
374 let value_name = $crate::arg_impl! { @string $value_name };
375 if arg.get_id() == "" {
376 arg = arg.id(value_name);
377 }
378 let arg = arg
379 .value_name(value_name)
380 .action($crate::ArgAction::Set);
381 let arg = $crate::arg_impl! {
382 @arg (arg) $($tail)*
383 };
384 arg
385 }};
386 (
387 @arg
388 ($arg:expr)
389 ...
390 $($tail:tt)*
391 ) => {{
392 let arg = match $arg.get_action() {
393 $crate::ArgAction::Set => {
394 if $arg.get_long().is_none() && $arg.get_short().is_none() {
395 $arg.num_args(1..)
396 // Allow collecting arguments interleaved with flags
397 .action($crate::ArgAction::Append)
398 } else {
399 $arg.action($crate::ArgAction::Append)
400 }
401 },
402 $crate::ArgAction::SetTrue | $crate::ArgAction::Help | $crate::ArgAction::Version => {
403 $arg.action($crate::ArgAction::Count)
404 }
405 action => {
406 panic!("Unexpected action {action:?}")
407 }
408 };
409 let arg = $crate::arg_impl! {
410 @arg (arg) $($tail)*
411 };
412 arg
413 }};
414 (
415 @arg
416 ($arg:expr)
417 $help:literal
418 ) => {{
419 $arg.help($help)
420 }};
421 (
422 @arg
423 ($arg:expr)
424 ) => {{
425 $arg
426 }};
427}
428
429/// Create an [`Arg`] from a usage string.
430///
431/// Allows creation of basic settings for the [`Arg`].
432///
433/// **NOTE**: Not all settings may be set using the usage string method. Some properties are
434/// only available via the builder pattern.
435///
436/// # Syntax
437///
438/// Usage strings typically following the form:
439///
440/// ```notrust
441/// [explicit name] [short] [long] [value names] [...] [help string]
442/// ```
443///
444/// ### Explicit Name
445///
446/// The name may be either a bare-word or a string, followed by a `:`, like `name:` or
447/// `"name":`.
448///
449/// *Note:* This is an optional field, if it's omitted the argument will use one of the additional
450/// fields as the name using the following priority order:
451///
452/// 1. Explicit Name
453/// 2. Long
454/// 3. Value Name
455///
456/// See [`Arg::id`][crate::Arg::id].
457///
458/// ### Short
459///
460/// A short flag is a `-` followed by either a bare-character or quoted character, like `-f` or
461/// `-'f'`.
462///
463/// See [`Arg::short`][crate::Arg::short].
464///
465/// ### Long
466///
467/// A long flag is a `--` followed by either a bare-word or a string, like `--foo` or
468/// `--"foo"`.
469///
470/// **NOTE:** Dashes in the long name (e.g. `--foo-bar`) is not supported and quoting is required
471/// (e.g. `--"foo-bar"`).
472///
473/// See [`Arg::long`][crate::Arg::long].
474///
475/// ### Values (Value Notation)
476///
477/// This is set by placing bare-word between:
478/// - `[]` like `[FOO]`
479/// - Positional argument: optional
480/// - Named argument: optional value
481/// - `<>` like `<FOO>`: required
482///
483/// See [`Arg::value_name`][crate::Arg::value_name].
484///
485/// ### `...`
486///
487/// `...` (three consecutive dots/periods) specifies that this argument may occur multiple
488/// times (not to be confused with multiple values per occurrence).
489///
490/// See [`ArgAction::Count`][crate::ArgAction::Count] and [`ArgAction::Append`][crate::ArgAction::Append].
491///
492/// ### Help String
493///
494/// The help string is denoted between a pair of double quotes `""` and may contain any
495/// characters.
496///
497/// # Examples
498///
499/// ```rust
500/// # use clap_builder as clap;
501/// # use clap::{Command, Arg, arg};
502/// let cmd = Command::new("prog")
503/// .args(&[
504/// arg!(--config <FILE> "a required file for the configuration and no short"),
505/// arg!(-d --debug ... "turns on debugging information and allows multiples"),
506/// arg!([input] "an optional input file to use")
507/// ]);
508///
509/// let m = cmd.try_get_matches_from(["prog", "--config", "file.toml"]).unwrap();
510/// assert_eq!(m.get_one::<String>("config").unwrap(), "file.toml");
511/// assert_eq!(*m.get_one::<u8>("debug").unwrap(), 0);
512/// assert_eq!(m.get_one::<String>("input"), None);
513/// ```
514/// [`Arg`]: crate::Arg
515#[macro_export]
516macro_rules! arg {
517 ( $name:ident: $($tail:tt)+ ) => {{
518 let arg = $crate::Arg::new($crate::arg_impl! { @string $name });
519 let arg = $crate::arg_impl! {
520 @arg (arg) $($tail)+
521 };
522 arg
523 }};
524 ( $($tail:tt)+ ) => {{
525 let arg = $crate::Arg::default();
526 let arg = $crate::arg_impl! {
527 @arg (arg) $($tail)+
528 };
529 debug_assert_ne!(arg.get_id(), "", "Without a value or long flag, the `name:` prefix is required");
530 arg
531 }};
532}
533
534#[cfg(feature = "debug")]
535macro_rules! debug {
536 ($($arg:tt)*) => ({
537 use std::fmt::Write as _;
538 let hint = anstyle::Style::new().dimmed();
539
540 let module_path = module_path!();
541 let body = format!($($arg)*);
542 let mut styled = $crate::builder::StyledStr::new();
543 let _ = write!(styled, "{}[{module_path:>28}]{body}{}\n", hint.render(), hint.render_reset());
544 let color = $crate::output::fmt::Colorizer::new($crate::output::fmt::Stream::Stderr, $crate::ColorChoice::Auto).with_content(styled);
545 let _ = color.print();
546 })
547}
548
549#[cfg(not(feature = "debug"))]
550macro_rules! debug {
551 ($($arg:tt)*) => {};
552}
553
554macro_rules! ok {
555 ($expr:expr) => {
556 match $expr {
557 Ok(val) => val,
558 Err(err) => {
559 return Err(err);
560 }
561 }
562 };
563}
564
565macro_rules! some {
566 ($expr:expr) => {
567 match $expr {
568 Some(val) => val,
569 None => {
570 return None;
571 }
572 }
573 };
574}
575