pub struct FlagSpec {
pub name: &'static str,
pub short: Option<char>,
pub doc: &'static str,
pub env: Option<&'static str>,
}Expand description
Specification for Flag.
Note that noargs does not support flags with only short names.
Fields§
§name: &'static strFlag long name (usually kebab-case).
short: Option<char>Flag short name.
doc: &'static strDocumentation.
env: Option<&'static str>Environment variable name.
If a non-empty value is set to this variable, this flag is considered to be set.
Implementations§
Source§impl FlagSpec
impl FlagSpec
Sourcepub const fn new(name: &'static str) -> Self
pub const fn new(name: &'static str) -> Self
Makes an FlagSpec instance with a specified name (equivalent to noargs::flag(name)).
Sourcepub const fn short(self, name: char) -> Self
pub const fn short(self, name: char) -> Self
Updates the value of FlagSpec::short.
Examples found in repository?
examples/subcommands.rs (line 32)
22fn try_run_hello(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
23 if !noargs::cmd("hello")
24 .doc("Print a greeting")
25 .take(args)
26 .is_present()
27 {
28 return Ok(false);
29 }
30
31 let loud = noargs::flag("loud")
32 .short('l')
33 .doc("Print greeting in upper case")
34 .take(args)
35 .is_present();
36 let name: String = noargs::arg("<NAME>")
37 .doc("Name to greet")
38 .example("Alice")
39 .take(args)
40 .then(|a| a.value().parse())?;
41
42 if args.metadata().help_mode {
43 return Ok(true);
44 }
45
46 let message = format!("Hello, {name}!");
47 if loud {
48 println!("{}", message.to_uppercase());
49 } else {
50 println!("{message}");
51 }
52 Ok(true)
53}
54
55fn try_run_sum(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
56 if !noargs::cmd("sum")
57 .doc("Add two integers")
58 .take(args)
59 .is_present()
60 {
61 return Ok(false);
62 }
63
64 let repeat: usize = noargs::opt("repeat")
65 .short('r')
66 .ty("N")
67 .doc("Print result multiple times")
68 .default("1")
69 .take(args)
70 .then(|o| o.value().parse())?;
71 let left: i64 = noargs::arg("<LEFT>")
72 .doc("Left operand")
73 .example("3")
74 .take(args)
75 .then(|a| a.value().parse())?;
76 let right: i64 = noargs::arg("<RIGHT>")
77 .doc("Right operand")
78 .example("4")
79 .take(args)
80 .then(|a| a.value().parse())?;
81
82 if args.metadata().help_mode {
83 return Ok(true);
84 }
85
86 let total = left + right;
87 for _ in 0..repeat {
88 println!("{total}");
89 }
90 Ok(true)
91}
92
93fn try_run_echo(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
94 if !noargs::cmd("echo")
95 .doc("Print a message")
96 .take(args)
97 .is_present()
98 {
99 return Ok(false);
100 }
101
102 let upper = noargs::flag("upper")
103 .short('u')
104 .doc("Uppercase the message")
105 .take(args)
106 .is_present();
107 let text: String = noargs::arg("<TEXT>")
108 .doc("Message text")
109 .example("hello world")
110 .take(args)
111 .then(|a| a.value().parse())?;
112
113 if args.metadata().help_mode {
114 return Ok(true);
115 }
116
117 if upper {
118 println!("{}", text.to_uppercase());
119 } else {
120 println!("{text}");
121 }
122 Ok(true)
123}More examples
examples/basics.rs (line 20)
1fn main() -> noargs::Result<()> {
2 let mut args = noargs::raw_args();
3 args.metadata_mut().app_name = env!("CARGO_PKG_NAME");
4 args.metadata_mut().app_description = env!("CARGO_PKG_DESCRIPTION");
5
6 if noargs::VERSION_FLAG.take(&mut args).is_present() {
7 println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
8 return Ok(());
9 }
10 noargs::HELP_FLAG.take_help(&mut args);
11
12 // Important: call flag()/opt() before arg().
13 // Otherwise values like "-v" — or any unknown "--bogus" — can be silently
14 // consumed as positional arguments.
15 //
16 // Required option / positional: set example("...") so help mode renders
17 // a meaningful Usage / Example line. Optional fields covered by default()
18 // or present_and_then() do not need example().
19 let verbose = noargs::flag("verbose")
20 .short('v')
21 .doc("Enable verbose output")
22 .take(&mut args)
23 .is_present();
24 let dry_run = noargs::flag("dry-run")
25 .doc("Print parsed values and exit without running processing")
26 .take(&mut args)
27 .is_present();
28 let retries: usize = noargs::opt("retries")
29 .short('r')
30 .ty("N")
31 .doc("How many times to retry")
32 .default("1")
33 .take(&mut args)
34 .then(|o| o.value().parse())?;
35 let endpoint: String = noargs::opt("endpoint")
36 .ty("URL")
37 .doc("Server endpoint")
38 .env("NOARGS_ENDPOINT")
39 .default("http://localhost:8080")
40 .take(&mut args)
41 .then(|o| o.value().parse())?;
42 let format: String = noargs::opt("format")
43 .ty("FORMAT")
44 .doc("Output format")
45 .example("json")
46 .take(&mut args)
47 .then(|o| o.value().parse())?;
48 let timeout_secs: Option<u64> = noargs::opt("timeout")
49 .ty("SECONDS")
50 .doc("Optional timeout in seconds")
51 .take(&mut args)
52 .present_and_then(|o| o.value().parse())?;
53
54 let input: String = noargs::arg("<INPUT>")
55 .doc("Input file path")
56 .example("input.txt")
57 .take(&mut args)
58 .then(|a| a.value().parse())?;
59 // Optional positional with default(): the value is always a String —
60 // absent uses "out.txt", present uses the given path.
61 // For "absent vs present" distinction, use present_and_then() and bind
62 // to Option<String> — see the README's [BAZ] example.
63 let output: String = noargs::arg("[OUTPUT]")
64 .doc("Output file path")
65 .default("out.txt")
66 .take(&mut args)
67 .then(|a| a.value().parse())?;
68
69 if let Some(help) = args.finish()? {
70 // When help is requested, finish() returns the built help text.
71 // Print it here and exit without running application logic.
72 print!("{help}");
73 return Ok(());
74 }
75
76 if dry_run {
77 println!(
78 "dry-run: verbose={verbose}, retries={retries}, endpoint={endpoint}, format={format}, timeout_secs={timeout_secs:?}, input={input}, output={output}"
79 );
80 return Ok(());
81 }
82
83 println!("processing: {input} -> {output}");
84 println!("using endpoint={endpoint}, format={format}, retries={retries}");
85 if verbose {
86 println!("verbose: timeout_secs={timeout_secs:?}");
87 }
88
89 Ok(())
90}Sourcepub const fn doc(self, doc: &'static str) -> Self
pub const fn doc(self, doc: &'static str) -> Self
Updates the value of FlagSpec::doc.
Examples found in repository?
examples/subcommands.rs (line 33)
22fn try_run_hello(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
23 if !noargs::cmd("hello")
24 .doc("Print a greeting")
25 .take(args)
26 .is_present()
27 {
28 return Ok(false);
29 }
30
31 let loud = noargs::flag("loud")
32 .short('l')
33 .doc("Print greeting in upper case")
34 .take(args)
35 .is_present();
36 let name: String = noargs::arg("<NAME>")
37 .doc("Name to greet")
38 .example("Alice")
39 .take(args)
40 .then(|a| a.value().parse())?;
41
42 if args.metadata().help_mode {
43 return Ok(true);
44 }
45
46 let message = format!("Hello, {name}!");
47 if loud {
48 println!("{}", message.to_uppercase());
49 } else {
50 println!("{message}");
51 }
52 Ok(true)
53}
54
55fn try_run_sum(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
56 if !noargs::cmd("sum")
57 .doc("Add two integers")
58 .take(args)
59 .is_present()
60 {
61 return Ok(false);
62 }
63
64 let repeat: usize = noargs::opt("repeat")
65 .short('r')
66 .ty("N")
67 .doc("Print result multiple times")
68 .default("1")
69 .take(args)
70 .then(|o| o.value().parse())?;
71 let left: i64 = noargs::arg("<LEFT>")
72 .doc("Left operand")
73 .example("3")
74 .take(args)
75 .then(|a| a.value().parse())?;
76 let right: i64 = noargs::arg("<RIGHT>")
77 .doc("Right operand")
78 .example("4")
79 .take(args)
80 .then(|a| a.value().parse())?;
81
82 if args.metadata().help_mode {
83 return Ok(true);
84 }
85
86 let total = left + right;
87 for _ in 0..repeat {
88 println!("{total}");
89 }
90 Ok(true)
91}
92
93fn try_run_echo(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
94 if !noargs::cmd("echo")
95 .doc("Print a message")
96 .take(args)
97 .is_present()
98 {
99 return Ok(false);
100 }
101
102 let upper = noargs::flag("upper")
103 .short('u')
104 .doc("Uppercase the message")
105 .take(args)
106 .is_present();
107 let text: String = noargs::arg("<TEXT>")
108 .doc("Message text")
109 .example("hello world")
110 .take(args)
111 .then(|a| a.value().parse())?;
112
113 if args.metadata().help_mode {
114 return Ok(true);
115 }
116
117 if upper {
118 println!("{}", text.to_uppercase());
119 } else {
120 println!("{text}");
121 }
122 Ok(true)
123}More examples
examples/basics.rs (line 21)
1fn main() -> noargs::Result<()> {
2 let mut args = noargs::raw_args();
3 args.metadata_mut().app_name = env!("CARGO_PKG_NAME");
4 args.metadata_mut().app_description = env!("CARGO_PKG_DESCRIPTION");
5
6 if noargs::VERSION_FLAG.take(&mut args).is_present() {
7 println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
8 return Ok(());
9 }
10 noargs::HELP_FLAG.take_help(&mut args);
11
12 // Important: call flag()/opt() before arg().
13 // Otherwise values like "-v" — or any unknown "--bogus" — can be silently
14 // consumed as positional arguments.
15 //
16 // Required option / positional: set example("...") so help mode renders
17 // a meaningful Usage / Example line. Optional fields covered by default()
18 // or present_and_then() do not need example().
19 let verbose = noargs::flag("verbose")
20 .short('v')
21 .doc("Enable verbose output")
22 .take(&mut args)
23 .is_present();
24 let dry_run = noargs::flag("dry-run")
25 .doc("Print parsed values and exit without running processing")
26 .take(&mut args)
27 .is_present();
28 let retries: usize = noargs::opt("retries")
29 .short('r')
30 .ty("N")
31 .doc("How many times to retry")
32 .default("1")
33 .take(&mut args)
34 .then(|o| o.value().parse())?;
35 let endpoint: String = noargs::opt("endpoint")
36 .ty("URL")
37 .doc("Server endpoint")
38 .env("NOARGS_ENDPOINT")
39 .default("http://localhost:8080")
40 .take(&mut args)
41 .then(|o| o.value().parse())?;
42 let format: String = noargs::opt("format")
43 .ty("FORMAT")
44 .doc("Output format")
45 .example("json")
46 .take(&mut args)
47 .then(|o| o.value().parse())?;
48 let timeout_secs: Option<u64> = noargs::opt("timeout")
49 .ty("SECONDS")
50 .doc("Optional timeout in seconds")
51 .take(&mut args)
52 .present_and_then(|o| o.value().parse())?;
53
54 let input: String = noargs::arg("<INPUT>")
55 .doc("Input file path")
56 .example("input.txt")
57 .take(&mut args)
58 .then(|a| a.value().parse())?;
59 // Optional positional with default(): the value is always a String —
60 // absent uses "out.txt", present uses the given path.
61 // For "absent vs present" distinction, use present_and_then() and bind
62 // to Option<String> — see the README's [BAZ] example.
63 let output: String = noargs::arg("[OUTPUT]")
64 .doc("Output file path")
65 .default("out.txt")
66 .take(&mut args)
67 .then(|a| a.value().parse())?;
68
69 if let Some(help) = args.finish()? {
70 // When help is requested, finish() returns the built help text.
71 // Print it here and exit without running application logic.
72 print!("{help}");
73 return Ok(());
74 }
75
76 if dry_run {
77 println!(
78 "dry-run: verbose={verbose}, retries={retries}, endpoint={endpoint}, format={format}, timeout_secs={timeout_secs:?}, input={input}, output={output}"
79 );
80 return Ok(());
81 }
82
83 println!("processing: {input} -> {output}");
84 println!("using endpoint={endpoint}, format={format}, retries={retries}");
85 if verbose {
86 println!("verbose: timeout_secs={timeout_secs:?}");
87 }
88
89 Ok(())
90}Sourcepub const fn env(self, variable_name: &'static str) -> Self
pub const fn env(self, variable_name: &'static str) -> Self
Updates the value of FlagSpec::env.
Sourcepub fn take(self, args: &mut RawArgs) -> Flag
pub fn take(self, args: &mut RawArgs) -> Flag
Takes the first Flag instance that satisfies this specification from the raw arguments.
Examples found in repository?
examples/subcommands.rs (line 6)
1fn main() -> noargs::Result<()> {
2 let mut args = noargs::raw_args();
3 args.metadata_mut().app_name = env!("CARGO_PKG_NAME");
4 args.metadata_mut().app_description = env!("CARGO_PKG_DESCRIPTION");
5
6 if noargs::VERSION_FLAG.take(&mut args).is_present() {
7 println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
8 return Ok(());
9 }
10 noargs::HELP_FLAG.take_help(&mut args);
11
12 // In real applications, split each `try_run_*` command into separate modules/files.
13 let _ = try_run_hello(&mut args)? || try_run_sum(&mut args)? || try_run_echo(&mut args)?;
14
15 if let Some(help) = args.finish()? {
16 print!("{help}");
17 }
18
19 Ok(())
20}
21
22fn try_run_hello(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
23 if !noargs::cmd("hello")
24 .doc("Print a greeting")
25 .take(args)
26 .is_present()
27 {
28 return Ok(false);
29 }
30
31 let loud = noargs::flag("loud")
32 .short('l')
33 .doc("Print greeting in upper case")
34 .take(args)
35 .is_present();
36 let name: String = noargs::arg("<NAME>")
37 .doc("Name to greet")
38 .example("Alice")
39 .take(args)
40 .then(|a| a.value().parse())?;
41
42 if args.metadata().help_mode {
43 return Ok(true);
44 }
45
46 let message = format!("Hello, {name}!");
47 if loud {
48 println!("{}", message.to_uppercase());
49 } else {
50 println!("{message}");
51 }
52 Ok(true)
53}
54
55fn try_run_sum(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
56 if !noargs::cmd("sum")
57 .doc("Add two integers")
58 .take(args)
59 .is_present()
60 {
61 return Ok(false);
62 }
63
64 let repeat: usize = noargs::opt("repeat")
65 .short('r')
66 .ty("N")
67 .doc("Print result multiple times")
68 .default("1")
69 .take(args)
70 .then(|o| o.value().parse())?;
71 let left: i64 = noargs::arg("<LEFT>")
72 .doc("Left operand")
73 .example("3")
74 .take(args)
75 .then(|a| a.value().parse())?;
76 let right: i64 = noargs::arg("<RIGHT>")
77 .doc("Right operand")
78 .example("4")
79 .take(args)
80 .then(|a| a.value().parse())?;
81
82 if args.metadata().help_mode {
83 return Ok(true);
84 }
85
86 let total = left + right;
87 for _ in 0..repeat {
88 println!("{total}");
89 }
90 Ok(true)
91}
92
93fn try_run_echo(args: &mut noargs::RawArgs) -> noargs::Result<bool> {
94 if !noargs::cmd("echo")
95 .doc("Print a message")
96 .take(args)
97 .is_present()
98 {
99 return Ok(false);
100 }
101
102 let upper = noargs::flag("upper")
103 .short('u')
104 .doc("Uppercase the message")
105 .take(args)
106 .is_present();
107 let text: String = noargs::arg("<TEXT>")
108 .doc("Message text")
109 .example("hello world")
110 .take(args)
111 .then(|a| a.value().parse())?;
112
113 if args.metadata().help_mode {
114 return Ok(true);
115 }
116
117 if upper {
118 println!("{}", text.to_uppercase());
119 } else {
120 println!("{text}");
121 }
122 Ok(true)
123}More examples
examples/arrays.rs (line 6)
1fn main() -> noargs::Result<()> {
2 let mut args = noargs::raw_args();
3 args.metadata_mut().app_name = env!("CARGO_PKG_NAME");
4 args.metadata_mut().app_description = env!("CARGO_PKG_DESCRIPTION");
5
6 if noargs::VERSION_FLAG.take(&mut args).is_present() {
7 println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
8 return Ok(());
9 }
10 noargs::HELP_FLAG.take_help(&mut args);
11
12 // Same-name options can be collected by calling take() in a loop.
13 let include_opt = noargs::opt("include")
14 .short('I')
15 .ty("PATH")
16 .doc("Include path (can be specified multiple times)");
17 let mut includes = Vec::<String>::new();
18 while let Some(path) = include_opt
19 .take(&mut args)
20 .present_and_then(|o| o.value().parse())?
21 {
22 includes.push(path);
23 }
24
25 let label_opt = noargs::opt("label")
26 .short('l')
27 .ty("LABEL")
28 .doc("Label value (can be specified multiple times)");
29 let mut labels = Vec::<String>::new();
30 while let Some(label) = label_opt
31 .take(&mut args)
32 .present_and_then(|o| o.value().parse())?
33 {
34 labels.push(label);
35 }
36
37 let output: String = noargs::opt("output")
38 .short('o')
39 .ty("PATH")
40 .doc("Output path")
41 .default("summary.txt")
42 .take(&mut args)
43 .then(|o| o.value().parse())?;
44
45 // Positional arrays are handled with one required argument + optional rest.
46 // Naming convention: use `<NAME>...` for required-many and `[NAME]...` for optional-many.
47 // The `<>` / `[]` / `...` markers are cosmetic (used only in help output);
48 // required-ness is enforced below: `.then()` makes the first input required,
49 // the loop with `.present_and_then()` consumes zero or more rest inputs.
50 let first_input: String = noargs::arg("<INPUT>")
51 .doc("First input (required)")
52 .example("a.txt")
53 .take(&mut args)
54 .then(|a| a.value().parse())?;
55 let rest_input_arg = noargs::arg("[INPUT]...").doc("Additional inputs");
56 let mut inputs = vec![first_input];
57 while let Some(input) = rest_input_arg
58 .take(&mut args)
59 .present_and_then(|a| a.value().parse())?
60 {
61 inputs.push(input);
62 }
63
64 if let Some(help) = args.finish()? {
65 print!("{help}");
66 return Ok(());
67 }
68
69 println!("includes={includes:?}");
70 println!("labels={labels:?}");
71 println!("inputs={inputs:?}");
72 println!("output={output}");
73 Ok(())
74}examples/basics.rs (line 6)
1fn main() -> noargs::Result<()> {
2 let mut args = noargs::raw_args();
3 args.metadata_mut().app_name = env!("CARGO_PKG_NAME");
4 args.metadata_mut().app_description = env!("CARGO_PKG_DESCRIPTION");
5
6 if noargs::VERSION_FLAG.take(&mut args).is_present() {
7 println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
8 return Ok(());
9 }
10 noargs::HELP_FLAG.take_help(&mut args);
11
12 // Important: call flag()/opt() before arg().
13 // Otherwise values like "-v" — or any unknown "--bogus" — can be silently
14 // consumed as positional arguments.
15 //
16 // Required option / positional: set example("...") so help mode renders
17 // a meaningful Usage / Example line. Optional fields covered by default()
18 // or present_and_then() do not need example().
19 let verbose = noargs::flag("verbose")
20 .short('v')
21 .doc("Enable verbose output")
22 .take(&mut args)
23 .is_present();
24 let dry_run = noargs::flag("dry-run")
25 .doc("Print parsed values and exit without running processing")
26 .take(&mut args)
27 .is_present();
28 let retries: usize = noargs::opt("retries")
29 .short('r')
30 .ty("N")
31 .doc("How many times to retry")
32 .default("1")
33 .take(&mut args)
34 .then(|o| o.value().parse())?;
35 let endpoint: String = noargs::opt("endpoint")
36 .ty("URL")
37 .doc("Server endpoint")
38 .env("NOARGS_ENDPOINT")
39 .default("http://localhost:8080")
40 .take(&mut args)
41 .then(|o| o.value().parse())?;
42 let format: String = noargs::opt("format")
43 .ty("FORMAT")
44 .doc("Output format")
45 .example("json")
46 .take(&mut args)
47 .then(|o| o.value().parse())?;
48 let timeout_secs: Option<u64> = noargs::opt("timeout")
49 .ty("SECONDS")
50 .doc("Optional timeout in seconds")
51 .take(&mut args)
52 .present_and_then(|o| o.value().parse())?;
53
54 let input: String = noargs::arg("<INPUT>")
55 .doc("Input file path")
56 .example("input.txt")
57 .take(&mut args)
58 .then(|a| a.value().parse())?;
59 // Optional positional with default(): the value is always a String —
60 // absent uses "out.txt", present uses the given path.
61 // For "absent vs present" distinction, use present_and_then() and bind
62 // to Option<String> — see the README's [BAZ] example.
63 let output: String = noargs::arg("[OUTPUT]")
64 .doc("Output file path")
65 .default("out.txt")
66 .take(&mut args)
67 .then(|a| a.value().parse())?;
68
69 if let Some(help) = args.finish()? {
70 // When help is requested, finish() returns the built help text.
71 // Print it here and exit without running application logic.
72 print!("{help}");
73 return Ok(());
74 }
75
76 if dry_run {
77 println!(
78 "dry-run: verbose={verbose}, retries={retries}, endpoint={endpoint}, format={format}, timeout_secs={timeout_secs:?}, input={input}, output={output}"
79 );
80 return Ok(());
81 }
82
83 println!("processing: {input} -> {output}");
84 println!("using endpoint={endpoint}, format={format}, retries={retries}");
85 if verbose {
86 println!("verbose: timeout_secs={timeout_secs:?}");
87 }
88
89 Ok(())
90}Sourcepub fn take_help(self, args: &mut RawArgs) -> Flag
pub fn take_help(self, args: &mut RawArgs) -> Flag
Similar to FlagSpec::take(), but updates the help-related metadata of args when the flag is present.
Specifically, the following code is executed:
args.metadata_mut().help_mode = true;
args.metadata_mut().help_flag_name = Some(flag.spec().name);
if matches!(flag, Flag::Long { .. }) {
args.metadata_mut().full_help = true;
}Examples found in repository?
examples/subcommands.rs (line 10)
1fn main() -> noargs::Result<()> {
2 let mut args = noargs::raw_args();
3 args.metadata_mut().app_name = env!("CARGO_PKG_NAME");
4 args.metadata_mut().app_description = env!("CARGO_PKG_DESCRIPTION");
5
6 if noargs::VERSION_FLAG.take(&mut args).is_present() {
7 println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
8 return Ok(());
9 }
10 noargs::HELP_FLAG.take_help(&mut args);
11
12 // In real applications, split each `try_run_*` command into separate modules/files.
13 let _ = try_run_hello(&mut args)? || try_run_sum(&mut args)? || try_run_echo(&mut args)?;
14
15 if let Some(help) = args.finish()? {
16 print!("{help}");
17 }
18
19 Ok(())
20}More examples
examples/arrays.rs (line 10)
1fn main() -> noargs::Result<()> {
2 let mut args = noargs::raw_args();
3 args.metadata_mut().app_name = env!("CARGO_PKG_NAME");
4 args.metadata_mut().app_description = env!("CARGO_PKG_DESCRIPTION");
5
6 if noargs::VERSION_FLAG.take(&mut args).is_present() {
7 println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
8 return Ok(());
9 }
10 noargs::HELP_FLAG.take_help(&mut args);
11
12 // Same-name options can be collected by calling take() in a loop.
13 let include_opt = noargs::opt("include")
14 .short('I')
15 .ty("PATH")
16 .doc("Include path (can be specified multiple times)");
17 let mut includes = Vec::<String>::new();
18 while let Some(path) = include_opt
19 .take(&mut args)
20 .present_and_then(|o| o.value().parse())?
21 {
22 includes.push(path);
23 }
24
25 let label_opt = noargs::opt("label")
26 .short('l')
27 .ty("LABEL")
28 .doc("Label value (can be specified multiple times)");
29 let mut labels = Vec::<String>::new();
30 while let Some(label) = label_opt
31 .take(&mut args)
32 .present_and_then(|o| o.value().parse())?
33 {
34 labels.push(label);
35 }
36
37 let output: String = noargs::opt("output")
38 .short('o')
39 .ty("PATH")
40 .doc("Output path")
41 .default("summary.txt")
42 .take(&mut args)
43 .then(|o| o.value().parse())?;
44
45 // Positional arrays are handled with one required argument + optional rest.
46 // Naming convention: use `<NAME>...` for required-many and `[NAME]...` for optional-many.
47 // The `<>` / `[]` / `...` markers are cosmetic (used only in help output);
48 // required-ness is enforced below: `.then()` makes the first input required,
49 // the loop with `.present_and_then()` consumes zero or more rest inputs.
50 let first_input: String = noargs::arg("<INPUT>")
51 .doc("First input (required)")
52 .example("a.txt")
53 .take(&mut args)
54 .then(|a| a.value().parse())?;
55 let rest_input_arg = noargs::arg("[INPUT]...").doc("Additional inputs");
56 let mut inputs = vec![first_input];
57 while let Some(input) = rest_input_arg
58 .take(&mut args)
59 .present_and_then(|a| a.value().parse())?
60 {
61 inputs.push(input);
62 }
63
64 if let Some(help) = args.finish()? {
65 print!("{help}");
66 return Ok(());
67 }
68
69 println!("includes={includes:?}");
70 println!("labels={labels:?}");
71 println!("inputs={inputs:?}");
72 println!("output={output}");
73 Ok(())
74}examples/basics.rs (line 10)
1fn main() -> noargs::Result<()> {
2 let mut args = noargs::raw_args();
3 args.metadata_mut().app_name = env!("CARGO_PKG_NAME");
4 args.metadata_mut().app_description = env!("CARGO_PKG_DESCRIPTION");
5
6 if noargs::VERSION_FLAG.take(&mut args).is_present() {
7 println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
8 return Ok(());
9 }
10 noargs::HELP_FLAG.take_help(&mut args);
11
12 // Important: call flag()/opt() before arg().
13 // Otherwise values like "-v" — or any unknown "--bogus" — can be silently
14 // consumed as positional arguments.
15 //
16 // Required option / positional: set example("...") so help mode renders
17 // a meaningful Usage / Example line. Optional fields covered by default()
18 // or present_and_then() do not need example().
19 let verbose = noargs::flag("verbose")
20 .short('v')
21 .doc("Enable verbose output")
22 .take(&mut args)
23 .is_present();
24 let dry_run = noargs::flag("dry-run")
25 .doc("Print parsed values and exit without running processing")
26 .take(&mut args)
27 .is_present();
28 let retries: usize = noargs::opt("retries")
29 .short('r')
30 .ty("N")
31 .doc("How many times to retry")
32 .default("1")
33 .take(&mut args)
34 .then(|o| o.value().parse())?;
35 let endpoint: String = noargs::opt("endpoint")
36 .ty("URL")
37 .doc("Server endpoint")
38 .env("NOARGS_ENDPOINT")
39 .default("http://localhost:8080")
40 .take(&mut args)
41 .then(|o| o.value().parse())?;
42 let format: String = noargs::opt("format")
43 .ty("FORMAT")
44 .doc("Output format")
45 .example("json")
46 .take(&mut args)
47 .then(|o| o.value().parse())?;
48 let timeout_secs: Option<u64> = noargs::opt("timeout")
49 .ty("SECONDS")
50 .doc("Optional timeout in seconds")
51 .take(&mut args)
52 .present_and_then(|o| o.value().parse())?;
53
54 let input: String = noargs::arg("<INPUT>")
55 .doc("Input file path")
56 .example("input.txt")
57 .take(&mut args)
58 .then(|a| a.value().parse())?;
59 // Optional positional with default(): the value is always a String —
60 // absent uses "out.txt", present uses the given path.
61 // For "absent vs present" distinction, use present_and_then() and bind
62 // to Option<String> — see the README's [BAZ] example.
63 let output: String = noargs::arg("[OUTPUT]")
64 .doc("Output file path")
65 .default("out.txt")
66 .take(&mut args)
67 .then(|a| a.value().parse())?;
68
69 if let Some(help) = args.finish()? {
70 // When help is requested, finish() returns the built help text.
71 // Print it here and exit without running application logic.
72 print!("{help}");
73 return Ok(());
74 }
75
76 if dry_run {
77 println!(
78 "dry-run: verbose={verbose}, retries={retries}, endpoint={endpoint}, format={format}, timeout_secs={timeout_secs:?}, input={input}, output={output}"
79 );
80 return Ok(());
81 }
82
83 println!("processing: {input} -> {output}");
84 println!("using endpoint={endpoint}, format={format}, retries={retries}");
85 if verbose {
86 println!("verbose: timeout_secs={timeout_secs:?}");
87 }
88
89 Ok(())
90}Trait Implementations§
impl Copy for FlagSpec
impl Eq for FlagSpec
impl StructuralPartialEq for FlagSpec
Auto Trait Implementations§
impl Freeze for FlagSpec
impl RefUnwindSafe for FlagSpec
impl Send for FlagSpec
impl Sync for FlagSpec
impl Unpin for FlagSpec
impl UnsafeUnpin for FlagSpec
impl UnwindSafe for FlagSpec
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more