1#[cfg(feature = "cargo")]
15#[macro_export]
16macro_rules! crate_version {
17 () => {
18 env!("CARGO_PKG_VERSION")
19 };
20}
21
22#[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#[cfg(feature = "cargo")]
73#[macro_export]
74macro_rules! crate_description {
75 () => {
76 env!("CARGO_PKG_DESCRIPTION")
77 };
78}
79
80#[cfg(feature = "cargo")]
102#[macro_export]
103macro_rules! crate_name {
104 () => {
105 env!("CARGO_PKG_NAME")
106 };
107}
108
109#[cfg(feature = "cargo")]
130#[macro_export]
131macro_rules! command {
132 () => {{ $crate::command!($crate::crate_name!()) }};
133 ($name:expr) => {{
134 let mut cmd = $crate::Command::new($name).version($crate::crate_version!());
135
136 let author = $crate::crate_authors!();
137 if !author.is_empty() {
138 cmd = cmd.author(author)
139 }
140
141 let about = $crate::crate_description!();
142 if !about.is_empty() {
143 cmd = cmd.about(about)
144 }
145
146 cmd
147 }};
148}
149
150#[cfg(not(feature = "cargo"))]
152#[macro_export]
153macro_rules! command {
154 () => {{
155 compile_error!("`cargo` feature flag is required");
156 }};
157 ($name:expr) => {{
158 compile_error!("`cargo` feature flag is required");
159 }};
160}
161
162#[doc(hidden)]
163#[macro_export]
164macro_rules! arg_impl {
165 ( @string $val:ident ) => {
166 stringify!($val)
167 };
168 ( @string $val:literal ) => {{
169 let ident_or_string_literal: &str = $val;
170 ident_or_string_literal
171 }};
172 ( @string $val:tt ) => {
173 ::std::compile_error!("Only identifiers or string literals supported");
174 };
175 ( @string ) => {
176 None
177 };
178
179 ( @char $val:ident ) => {{
180 let ident_or_char_literal = stringify!($val);
181 debug_assert_eq!(
182 ident_or_char_literal.len(),
183 1,
184 "Single-letter identifier expected, got {ident_or_char_literal}",
185 );
186 ident_or_char_literal.chars().next().unwrap()
187 }};
188 ( @char $val:literal ) => {{
189 let ident_or_char_literal: char = $val;
190 ident_or_char_literal
191 }};
192 ( @char ) => {{
193 None
194 }};
195
196 (
197 @arg
198 ($arg:expr)
199 --$long:ident
200 $($tail:tt)*
201 ) => {{
202 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
203 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
204
205 let mut arg = $arg;
206 let long = $crate::arg_impl! { @string $long };
207 if arg.get_id() == "" {
208 arg = arg.id(long);
209 }
210 let action = $crate::ArgAction::SetTrue;
211 let arg = arg
212 .long(long)
213 .action(action);
214 let arg = $crate::arg_impl! {
215 @arg (arg) $($tail)*
216 };
217 arg
218 }};
219 (
220 @arg
221 ($arg:expr)
222 --$long:literal
223 $($tail:tt)*
224 ) => {{
225 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
226 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
227
228 let mut arg = $arg;
229 let long = $crate::arg_impl! { @string $long };
230 if arg.get_id() == "" {
231 arg = arg.id(long);
232 }
233 let action = $crate::ArgAction::SetTrue;
234 let arg = arg
235 .long(long)
236 .action(action);
237 let arg = $crate::arg_impl! {
238 @arg (arg) $($tail)*
239 };
240 arg
241 }};
242 (
243 @arg
244 ($arg:expr)
245 -$short:ident
246 $($tail:tt)*
247 ) => {{
248 debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
249 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
250 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
251
252 let action = $crate::ArgAction::SetTrue;
253 let arg = $arg
254 .short($crate::arg_impl! { @char $short })
255 .action(action);
256 let arg = $crate::arg_impl! {
257 @arg (arg) $($tail)*
258 };
259 arg
260 }};
261 (
262 @arg
263 ($arg:expr)
264 -$short:literal
265 $($tail:tt)*
266 ) => {{
267 debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
268 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
269 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
270
271 let action = $crate::ArgAction::SetTrue;
272 let arg = $arg
273 .short($crate::arg_impl! { @char $short })
274 .action(action);
275 let arg = $crate::arg_impl! {
276 @arg (arg) $($tail)*
277 };
278 arg
279 }};
280 (
281 @arg
282 ($arg:expr)
283 <$value_name:ident>
284 $($tail:tt)*
285 ) => {{
286 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
287 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
288
289 let mut arg = $arg;
290
291 if arg.get_long().is_none() && arg.get_short().is_none() {
292 arg = arg.required(true);
293 }
294
295 let value_name = $crate::arg_impl! { @string $value_name };
296 if arg.get_id() == "" {
297 arg = arg.id(value_name);
298 }
299 let arg = arg
300 .value_name(value_name)
301 .action($crate::ArgAction::Set);
302 let arg = $crate::arg_impl! {
303 @arg (arg) $($tail)*
304 };
305 arg
306 }};
307 (
308 @arg
309 ($arg:expr)
310 <$value_name:literal>
311 $($tail:tt)*
312 ) => {{
313 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
314 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
315
316 let mut arg = $arg;
317
318 if arg.get_long().is_none() && arg.get_short().is_none() {
319 arg = arg.required(true);
320 }
321
322 let value_name = $crate::arg_impl! { @string $value_name };
323 if arg.get_id() == "" {
324 arg = arg.id(value_name);
325 }
326 let arg = arg
327 .value_name(value_name)
328 .action($crate::ArgAction::Set);
329 let arg = $crate::arg_impl! {
330 @arg (arg) $($tail)*
331 };
332 arg
333 }};
334 (
335 @arg
336 ($arg:expr)
337 [$value_name:ident]
338 $($tail:tt)*
339 ) => {{
340 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
341 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
342
343 let mut arg = $arg;
344
345 if arg.get_long().is_none() && arg.get_short().is_none() {
346 arg = arg.required(false);
347 } else {
348 arg = arg.num_args(0..=1);
349 }
350
351 let value_name = $crate::arg_impl! { @string $value_name };
352 if arg.get_id() == "" {
353 arg = arg.id(value_name);
354 }
355 let arg = arg
356 .value_name(value_name)
357 .action($crate::ArgAction::Set);
358 let arg = $crate::arg_impl! {
359 @arg (arg) $($tail)*
360 };
361 arg
362 }};
363 (
364 @arg
365 ($arg:expr)
366 [$value_name:literal]
367 $($tail:tt)*
368 ) => {{
369 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
370 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
371
372 let mut arg = $arg;
373
374 if arg.get_long().is_none() && arg.get_short().is_none() {
375 arg = arg.required(false);
376 } else {
377 arg = arg.num_args(0..=1);
378 }
379
380 let value_name = $crate::arg_impl! { @string $value_name };
381 if arg.get_id() == "" {
382 arg = arg.id(value_name);
383 }
384 let arg = arg
385 .value_name(value_name)
386 .action($crate::ArgAction::Set);
387 let arg = $crate::arg_impl! {
388 @arg (arg) $($tail)*
389 };
390 arg
391 }};
392 (
393 @arg
394 ($arg:expr)
395 ...
396 $($tail:tt)*
397 ) => {{
398 let arg = match $arg.get_action() {
399 $crate::ArgAction::Set => {
400 if $arg.get_long().is_none() && $arg.get_short().is_none() {
401 $arg.num_args(1..)
402 .action($crate::ArgAction::Append)
404 } else {
405 $arg.action($crate::ArgAction::Append)
406 }
407 },
408 $crate::ArgAction::SetTrue | $crate::ArgAction::Help | $crate::ArgAction::Version => {
409 $arg.action($crate::ArgAction::Count)
410 }
411 action => {
412 panic!("Unexpected action {action:?}")
413 }
414 };
415 let arg = $crate::arg_impl! {
416 @arg (arg) $($tail)*
417 };
418 arg
419 }};
420 (
421 @arg
422 ($arg:expr)
423 $help:literal
424 ) => {{
425 $arg.help($help)
426 }};
427 (
428 @arg
429 ($arg:expr)
430 ) => {{
431 $arg
432 }};
433}
434
435#[macro_export]
530macro_rules! arg {
531 ( -$($tail:tt)+ ) => {{
532 let arg = $crate::Arg::default();
533 let arg = $crate::arg_impl! {
534 @arg (arg) -$($tail)+
535 };
536 debug_assert_ne!(arg.get_id(), "", "Without a value or long flag, the `name:` prefix is required");
537 arg
538 }};
539 ( $name:ident: $($tail:tt)+ ) => {{
540 let arg = $crate::Arg::new($crate::arg_impl! { @string $name });
541 let arg = $crate::arg_impl! {
542 @arg (arg) $($tail)+
543 };
544 arg
545 }};
546 ( $name:literal: $($tail:tt)+ ) => {{
547 let arg = $crate::Arg::new($crate::arg_impl! { @string $name });
548 let arg = $crate::arg_impl! {
549 @arg (arg) $($tail)+
550 };
551 arg
552 }};
553 ( $($tail:tt)+ ) => {{
554 let arg = $crate::Arg::default();
555 let arg = $crate::arg_impl! {
556 @arg (arg) $($tail)+
557 };
558 debug_assert_ne!(arg.get_id(), "", "Without a value or long flag, the `name:` prefix is required");
559 arg
560 }};
561}
562
563#[cfg(feature = "debug")]
564macro_rules! debug {
565 ($($arg:tt)*) => ({
566 use std::fmt::Write as _;
567 let hint = anstyle::Style::new().dimmed();
568
569 let module_path = module_path!();
570 let body = format!($($arg)*);
571 let mut styled = $crate::builder::StyledStr::new();
572 let _ = write!(styled, "{hint}[{module_path:>28}]{body}{hint:#}\n");
573 let color = $crate::output::fmt::Colorizer::new($crate::output::fmt::Stream::Stderr, $crate::ColorChoice::Auto).with_content(styled);
574 let _ = color.print();
575 })
576}
577
578#[cfg(not(feature = "debug"))]
579macro_rules! debug {
580 ($($arg:tt)*) => {};
581}
582
583macro_rules! ok {
584 ($expr:expr) => {
585 match $expr {
586 Ok(val) => val,
587 Err(err) => {
588 return Err(err);
589 }
590 }
591 };
592}
593
594macro_rules! some {
595 ($expr:expr) => {
596 match $expr {
597 Some(val) => val,
598 None => {
599 return None;
600 }
601 }
602 };
603}