pub enum Opt {
Long {
spec: OptSpec,
metadata: Metadata,
index: usize,
value: String,
},
Short {
spec: OptSpec,
metadata: Metadata,
index: usize,
value: String,
},
Env {
spec: OptSpec,
metadata: Metadata,
value: String,
},
Default {
spec: OptSpec,
metadata: Metadata,
},
Example {
spec: OptSpec,
metadata: Metadata,
},
MissingValue {
spec: OptSpec,
long: bool,
},
None {
spec: OptSpec,
},
}Expand description
A named argument with value.
Variants§
Implementations§
Source§impl Opt
impl Opt
Sourcepub fn is_present(&self) -> bool
pub fn is_present(&self) -> bool
Returns true if this option is present.
Sourcepub fn is_value_present(&self) -> bool
pub fn is_value_present(&self) -> bool
Returns true if this option is present and has a value.
Sourcepub fn then<F, T, E>(self, f: F) -> Result<T, Error>
pub fn then<F, T, E>(self, f: F) -> Result<T, Error>
Applies additional conversion or validation to the option.
This method allows for chaining transformations and validations when an option is present. It first checks if the option has a value and then applies the provided function.
§Examples
let mut args = noargs::RawArgs::new(["example", "--num=42"].iter().map(|a| a.to_string()));
let opt = noargs::opt("num").take(&mut args);
// Parse as number and ensure it's positive
let num = opt.then(|opt| -> Result<_, Box<dyn std::error::Error>> {
let n: i32 = opt.value().parse()?;
if n <= 0 {
return Err("number must be positive".into());
}
Ok(n)
})?;§Errors
- Returns
Error::MissingOptifself.is_value_present()isfalse(option is missing) - Returns
Error::InvalidOptiff(self)returnsErr(_)(validation or conversion failed)
Examples found in repository?
examples/subcommands.rs (line 70)
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}More examples
examples/arrays.rs (line 43)
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 34)
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 present_and_then<F, T, E>(self, f: F) -> Result<Option<T>, Error>
pub fn present_and_then<F, T, E>(self, f: F) -> Result<Option<T>, Error>
Shorthand for self.present().map(|opt| opt.then(f)).transpose().
Examples found in repository?
examples/arrays.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 // 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}More examples
examples/basics.rs (line 52)
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 value(&self) -> &str
pub fn value(&self) -> &str
Returns the raw value of this option, or an empty string if not present.
Examples found in repository?
examples/subcommands.rs (line 70)
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}More examples
examples/arrays.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 // 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 34)
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 Eq for Opt
impl StructuralPartialEq for Opt
Auto Trait Implementations§
impl Freeze for Opt
impl RefUnwindSafe for Opt
impl Send for Opt
impl Sync for Opt
impl Unpin for Opt
impl UnsafeUnpin for Opt
impl UnwindSafe for Opt
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