pub struct Parser { /* private fields */ }Expand description
A parser for command line arguments.
Implementations§
Source§impl Parser
impl Parser
Sourcepub fn next(&mut self) -> Result<Option<Arg<'_>>, Error>
pub fn next(&mut self) -> Result<Option<Arg<'_>>, Error>
Get the next option or positional argument.
A return value of Ok(None) means the command line has been exhausted.
Options that are not valid unicode are transformed with replacement
characters as by String::from_utf8_lossy.
§Errors
Error::UnexpectedValue is returned if the last option had a
value that hasn’t been consumed, as in --option=value or -o=value.
It’s possible to continue parsing after an error (but this is rarely useful).
Examples found in repository?
17fn main() -> Result<(), lexopt::Error> {
18 use lexopt::prelude::*;
19
20 let mut parser = lexopt::Parser::from_env();
21 parser.set_short_equals(false);
22 let mut free = Vec::new();
23 while let Some(arg) = parser.next()? {
24 match arg {
25 Short('n') | Long("number") => {
26 let num: u16 = parser.value()?.parse()?;
27 println!("Got number {}", num);
28 }
29 Long("shout") => {
30 println!("Got --shout");
31 }
32 Value(val) => {
33 free.push(val);
34 free.extend(parser.raw_args()?);
35 }
36 _ => return Err(arg.unexpected()),
37 }
38 }
39 println!("Got free args {:?}", free);
40 Ok(())
41}More examples
7fn parse_args() -> Result<Args, lexopt::Error> {
8 use lexopt::prelude::*;
9
10 let mut thing = None;
11 let mut number = 1;
12 let mut shout = false;
13 let mut parser = lexopt::Parser::from_env();
14 while let Some(arg) = parser.next()? {
15 match arg {
16 Short('n') | Long("number") => {
17 number = parser.value()?.parse()?;
18 }
19 Long("shout") => {
20 shout = true;
21 }
22 Value(val) if thing.is_none() => {
23 thing = Some(val.string()?);
24 }
25 Long("help") => {
26 println!("Usage: hello [-n|--number=NUM] [--shout] THING");
27 std::process::exit(0);
28 }
29 _ => return Err(arg.unexpected()),
30 }
31 }
32
33 Ok(Args {
34 thing: thing.ok_or("missing argument THING")?,
35 number,
36 shout,
37 })
38}20fn main() -> Result<(), lexopt::Error> {
21 use lexopt::prelude::*;
22
23 let mut parser = lexopt::Parser::from_env();
24 loop {
25 if let Some(num) = parse_dashnum(&mut parser) {
26 println!("Got number {}", num);
27 } else if let Some(arg) = parser.next()? {
28 match arg {
29 Short('f') | Long("follow") => {
30 println!("Got --follow");
31 }
32 Short('n') | Long("number") => {
33 let num: u64 = parser.value()?.parse()?;
34 println!("Got number {}", num);
35 }
36 Value(path) => {
37 let path = PathBuf::from(path);
38 println!("Got file {}", path.display());
39 }
40 _ => return Err(arg.unexpected()),
41 }
42 } else {
43 break;
44 }
45 }
46
47 Ok(())
48}49fn parse_args() -> Result<AppArgs, lexopt::Error> {
50 use lexopt::prelude::*;
51
52 let mut number = None;
53 let mut opt_number = None;
54 let mut width = 10;
55 let mut input = None;
56
57 let mut parser = lexopt::Parser::from_env();
58 while let Some(arg) = parser.next()? {
59 match arg {
60 Short('h') | Long("help") => {
61 print!("{}", HELP);
62 std::process::exit(0);
63 }
64 Long("number") => number = Some(parser.value()?.parse()?),
65 Long("opt-number") => opt_number = Some(parser.value()?.parse()?),
66 Long("width") => width = parser.value()?.parse_with(parse_width)?,
67 Value(path) if input.is_none() => input = Some(path.into()),
68 _ => return Err(arg.unexpected()),
69 }
70 }
71 Ok(AppArgs {
72 number: number.ok_or("missing required option --number")?,
73 opt_number,
74 width,
75 input: input.ok_or("missing required argument INPUT")?,
76 })
77}9fn main() -> Result<(), lexopt::Error> {
10 use lexopt::prelude::*;
11
12 let mut settings = GlobalSettings {
13 toolchain: "stable".to_owned(),
14 color: Color::Auto,
15 offline: false,
16 quiet: false,
17 verbose: false,
18 };
19
20 let mut parser = lexopt::Parser::from_env();
21 while let Some(arg) = parser.next()? {
22 match arg {
23 Long("color") => {
24 settings.color = parser.value()?.parse()?;
25 }
26 Long("offline") => {
27 settings.offline = true;
28 }
29 Long("quiet") => {
30 settings.quiet = true;
31 settings.verbose = false;
32 }
33 Long("verbose") => {
34 settings.verbose = true;
35 settings.quiet = false;
36 }
37 Long("help") => {
38 println!("{}", HELP);
39 std::process::exit(0);
40 }
41 Value(value) => {
42 let value = value.string()?;
43 match value.as_str() {
44 value if value.starts_with('+') => {
45 settings.toolchain = value[1..].to_owned();
46 }
47 "install" => {
48 return install(settings, parser);
49 }
50 value => {
51 return Err(format!("unknown subcommand '{}'", value).into());
52 }
53 }
54 }
55 _ => return Err(arg.unexpected()),
56 }
57 }
58
59 println!("{}", HELP);
60 Ok(())
61}
62
63#[derive(Debug)]
64struct GlobalSettings {
65 toolchain: String,
66 color: Color,
67 offline: bool,
68 quiet: bool,
69 verbose: bool,
70}
71
72fn install(settings: GlobalSettings, mut parser: lexopt::Parser) -> Result<(), lexopt::Error> {
73 use lexopt::prelude::*;
74
75 let mut package: Option<String> = None;
76 let mut root: Option<PathBuf> = None;
77 let mut jobs: u16 = get_no_of_cpus();
78
79 while let Some(arg) = parser.next()? {
80 match arg {
81 Value(value) if package.is_none() => {
82 package = Some(value.string()?);
83 }
84 Long("root") => {
85 root = Some(parser.value()?.into());
86 }
87 Short('j') | Long("jobs") => {
88 jobs = parser.value()?.parse()?;
89 }
90 Long("help") => {
91 println!("cargo install [OPTIONS] CRATE");
92 std::process::exit(0);
93 }
94 _ => return Err(arg.unexpected()),
95 }
96 }
97
98 println!("Settings: {:#?}", settings);
99 println!(
100 "Installing {} into {:?} with {} jobs",
101 package.ok_or("missing CRATE argument")?,
102 root,
103 jobs
104 );
105
106 Ok(())
107}Sourcepub fn value(&mut self) -> Result<OsString, Error>
pub fn value(&mut self) -> Result<OsString, Error>
Get a value for an option.
This function should normally be called right after seeing an option
that expects a value, with positional arguments being collected
using next().
A value is collected even if it looks like an option
(i.e., starts with -).
§Errors
An Error::MissingValue is returned if the end of the command
line is reached.
Examples found in repository?
17fn main() -> Result<(), lexopt::Error> {
18 use lexopt::prelude::*;
19
20 let mut parser = lexopt::Parser::from_env();
21 parser.set_short_equals(false);
22 let mut free = Vec::new();
23 while let Some(arg) = parser.next()? {
24 match arg {
25 Short('n') | Long("number") => {
26 let num: u16 = parser.value()?.parse()?;
27 println!("Got number {}", num);
28 }
29 Long("shout") => {
30 println!("Got --shout");
31 }
32 Value(val) => {
33 free.push(val);
34 free.extend(parser.raw_args()?);
35 }
36 _ => return Err(arg.unexpected()),
37 }
38 }
39 println!("Got free args {:?}", free);
40 Ok(())
41}More examples
7fn parse_args() -> Result<Args, lexopt::Error> {
8 use lexopt::prelude::*;
9
10 let mut thing = None;
11 let mut number = 1;
12 let mut shout = false;
13 let mut parser = lexopt::Parser::from_env();
14 while let Some(arg) = parser.next()? {
15 match arg {
16 Short('n') | Long("number") => {
17 number = parser.value()?.parse()?;
18 }
19 Long("shout") => {
20 shout = true;
21 }
22 Value(val) if thing.is_none() => {
23 thing = Some(val.string()?);
24 }
25 Long("help") => {
26 println!("Usage: hello [-n|--number=NUM] [--shout] THING");
27 std::process::exit(0);
28 }
29 _ => return Err(arg.unexpected()),
30 }
31 }
32
33 Ok(Args {
34 thing: thing.ok_or("missing argument THING")?,
35 number,
36 shout,
37 })
38}20fn main() -> Result<(), lexopt::Error> {
21 use lexopt::prelude::*;
22
23 let mut parser = lexopt::Parser::from_env();
24 loop {
25 if let Some(num) = parse_dashnum(&mut parser) {
26 println!("Got number {}", num);
27 } else if let Some(arg) = parser.next()? {
28 match arg {
29 Short('f') | Long("follow") => {
30 println!("Got --follow");
31 }
32 Short('n') | Long("number") => {
33 let num: u64 = parser.value()?.parse()?;
34 println!("Got number {}", num);
35 }
36 Value(path) => {
37 let path = PathBuf::from(path);
38 println!("Got file {}", path.display());
39 }
40 _ => return Err(arg.unexpected()),
41 }
42 } else {
43 break;
44 }
45 }
46
47 Ok(())
48}49fn parse_args() -> Result<AppArgs, lexopt::Error> {
50 use lexopt::prelude::*;
51
52 let mut number = None;
53 let mut opt_number = None;
54 let mut width = 10;
55 let mut input = None;
56
57 let mut parser = lexopt::Parser::from_env();
58 while let Some(arg) = parser.next()? {
59 match arg {
60 Short('h') | Long("help") => {
61 print!("{}", HELP);
62 std::process::exit(0);
63 }
64 Long("number") => number = Some(parser.value()?.parse()?),
65 Long("opt-number") => opt_number = Some(parser.value()?.parse()?),
66 Long("width") => width = parser.value()?.parse_with(parse_width)?,
67 Value(path) if input.is_none() => input = Some(path.into()),
68 _ => return Err(arg.unexpected()),
69 }
70 }
71 Ok(AppArgs {
72 number: number.ok_or("missing required option --number")?,
73 opt_number,
74 width,
75 input: input.ok_or("missing required argument INPUT")?,
76 })
77}9fn main() -> Result<(), lexopt::Error> {
10 use lexopt::prelude::*;
11
12 let mut settings = GlobalSettings {
13 toolchain: "stable".to_owned(),
14 color: Color::Auto,
15 offline: false,
16 quiet: false,
17 verbose: false,
18 };
19
20 let mut parser = lexopt::Parser::from_env();
21 while let Some(arg) = parser.next()? {
22 match arg {
23 Long("color") => {
24 settings.color = parser.value()?.parse()?;
25 }
26 Long("offline") => {
27 settings.offline = true;
28 }
29 Long("quiet") => {
30 settings.quiet = true;
31 settings.verbose = false;
32 }
33 Long("verbose") => {
34 settings.verbose = true;
35 settings.quiet = false;
36 }
37 Long("help") => {
38 println!("{}", HELP);
39 std::process::exit(0);
40 }
41 Value(value) => {
42 let value = value.string()?;
43 match value.as_str() {
44 value if value.starts_with('+') => {
45 settings.toolchain = value[1..].to_owned();
46 }
47 "install" => {
48 return install(settings, parser);
49 }
50 value => {
51 return Err(format!("unknown subcommand '{}'", value).into());
52 }
53 }
54 }
55 _ => return Err(arg.unexpected()),
56 }
57 }
58
59 println!("{}", HELP);
60 Ok(())
61}
62
63#[derive(Debug)]
64struct GlobalSettings {
65 toolchain: String,
66 color: Color,
67 offline: bool,
68 quiet: bool,
69 verbose: bool,
70}
71
72fn install(settings: GlobalSettings, mut parser: lexopt::Parser) -> Result<(), lexopt::Error> {
73 use lexopt::prelude::*;
74
75 let mut package: Option<String> = None;
76 let mut root: Option<PathBuf> = None;
77 let mut jobs: u16 = get_no_of_cpus();
78
79 while let Some(arg) = parser.next()? {
80 match arg {
81 Value(value) if package.is_none() => {
82 package = Some(value.string()?);
83 }
84 Long("root") => {
85 root = Some(parser.value()?.into());
86 }
87 Short('j') | Long("jobs") => {
88 jobs = parser.value()?.parse()?;
89 }
90 Long("help") => {
91 println!("cargo install [OPTIONS] CRATE");
92 std::process::exit(0);
93 }
94 _ => return Err(arg.unexpected()),
95 }
96 }
97
98 println!("Settings: {:#?}", settings);
99 println!(
100 "Installing {} into {:?} with {} jobs",
101 package.ok_or("missing CRATE argument")?,
102 root,
103 jobs
104 );
105
106 Ok(())
107}Sourcepub fn values(&mut self) -> Result<ValuesIter<'_>, Error>
pub fn values(&mut self) -> Result<ValuesIter<'_>, Error>
Gather multiple values for an option.
This is used for options that take multiple arguments, such as a
--command flag that’s invoked as app --command echo 'Hello world'.
It will gather arguments until another option is found, or -- is found, or
the end of the command line is reached. This differs from .value(), which
takes a value even if it looks like an option.
On success the resulting iterator will yield at least one value.
An equals sign (=) will limit this to a single value. That means -a=b c and
--opt=b c will only yield "b" while -a b c, -ab c and --opt b c will
yield "b", "c".
(If short_equals is disabled then -a=b c will yield
"=b", "c".)
§Errors
If not at least one value is found then Error::MissingValue is returned.
§Example
let arguments: Vec<OsString> = parser.values()?.collect();
let at_most_three_files: Vec<PathBuf> = parser.values()?.take(3).map(Into::into).collect();
for value in parser.values()? {
// ...
}Sourcepub fn raw_args(&mut self) -> Result<RawArgs<'_>, Error>
pub fn raw_args(&mut self) -> Result<RawArgs<'_>, Error>
Take raw arguments from the original command line.
This returns an iterator of OsStrings. Any arguments that are not
consumed are kept, so you can continue parsing after you’re done with
the iterator.
To inspect an argument without consuming it, use RawArgs::peek or
RawArgs::as_slice.
§Errors
Returns an Error::UnexpectedValue if the last option had a left-over
argument, as in --option=value, -ovalue, or if it was midway through
an option chain, as in -abc. The iterator only yields whole arguments.
To avoid this, use try_raw_args().
After this error the method is guaranteed to succeed, as it consumes the rest of the argument.
§Example
As soon as a free-standing argument is found, consume the other arguments as-is, and build them into a command.
Value(prog) => {
let args: Vec<_> = parser.raw_args()?.collect();
let command = std::process::Command::new(prog).args(args);
}Examples found in repository?
17fn main() -> Result<(), lexopt::Error> {
18 use lexopt::prelude::*;
19
20 let mut parser = lexopt::Parser::from_env();
21 parser.set_short_equals(false);
22 let mut free = Vec::new();
23 while let Some(arg) = parser.next()? {
24 match arg {
25 Short('n') | Long("number") => {
26 let num: u16 = parser.value()?.parse()?;
27 println!("Got number {}", num);
28 }
29 Long("shout") => {
30 println!("Got --shout");
31 }
32 Value(val) => {
33 free.push(val);
34 free.extend(parser.raw_args()?);
35 }
36 _ => return Err(arg.unexpected()),
37 }
38 }
39 println!("Got free args {:?}", free);
40 Ok(())
41}Sourcepub fn try_raw_args(&mut self) -> Option<RawArgs<'_>>
pub fn try_raw_args(&mut self) -> Option<RawArgs<'_>>
Take raw arguments from the original command line, if the current argument has finished processing.
Unlike raw_args() this does not consume any value
in case of a left-over argument. This makes it safe to call at any time.
It returns None exactly when optional_value()
would return Some.
Note: If no arguments are left then it returns an empty iterator (not None).
§Example
Process arguments of the form -123 as numbers. For a complete runnable version of
this example, see
examples/nonstandard.rs.
fn parse_dashnum(parser: &mut lexopt::Parser) -> Option<u64> {
let mut raw = parser.try_raw_args()?;
let arg = raw.peek()?.to_str()?;
let num = arg.strip_prefix('-')?.parse::<u64>().ok()?;
raw.next(); // Consume the argument we just parsed
Some(num)
}
loop {
if let Some(num) = parse_dashnum(&mut parser) {
println!("Got number {}", num);
} else if let Some(arg) = parser.next()? {
match arg {
// ...
}
} else {
break;
}
}Sourcepub fn bin_name(&self) -> Option<&str>
pub fn bin_name(&self) -> Option<&str>
The name of the command, as in the zeroth argument of the process.
This is intended for use in messages. If the name is not valid unicode
it will be sanitized with replacement characters as by
String::from_utf8_lossy.
To get the current executable, use std::env::current_exe.
§Example
let mut parser = lexopt::Parser::from_env();
let bin_name = parser.bin_name().unwrap_or("myapp");
println!("{}: Some message", bin_name);Sourcepub fn optional_value(&mut self) -> Option<OsString>
pub fn optional_value(&mut self) -> Option<OsString>
Get a value only if it’s concatenated to an option, as in -ovalue or
--option=value or -o=value, but not -o value or --option value.
Sourcepub fn from_env() -> Parser
pub fn from_env() -> Parser
Create a parser from the environment using std::env::args_os.
This is the usual way to create a Parser.
Examples found in repository?
17fn main() -> Result<(), lexopt::Error> {
18 use lexopt::prelude::*;
19
20 let mut parser = lexopt::Parser::from_env();
21 parser.set_short_equals(false);
22 let mut free = Vec::new();
23 while let Some(arg) = parser.next()? {
24 match arg {
25 Short('n') | Long("number") => {
26 let num: u16 = parser.value()?.parse()?;
27 println!("Got number {}", num);
28 }
29 Long("shout") => {
30 println!("Got --shout");
31 }
32 Value(val) => {
33 free.push(val);
34 free.extend(parser.raw_args()?);
35 }
36 _ => return Err(arg.unexpected()),
37 }
38 }
39 println!("Got free args {:?}", free);
40 Ok(())
41}More examples
7fn parse_args() -> Result<Args, lexopt::Error> {
8 use lexopt::prelude::*;
9
10 let mut thing = None;
11 let mut number = 1;
12 let mut shout = false;
13 let mut parser = lexopt::Parser::from_env();
14 while let Some(arg) = parser.next()? {
15 match arg {
16 Short('n') | Long("number") => {
17 number = parser.value()?.parse()?;
18 }
19 Long("shout") => {
20 shout = true;
21 }
22 Value(val) if thing.is_none() => {
23 thing = Some(val.string()?);
24 }
25 Long("help") => {
26 println!("Usage: hello [-n|--number=NUM] [--shout] THING");
27 std::process::exit(0);
28 }
29 _ => return Err(arg.unexpected()),
30 }
31 }
32
33 Ok(Args {
34 thing: thing.ok_or("missing argument THING")?,
35 number,
36 shout,
37 })
38}20fn main() -> Result<(), lexopt::Error> {
21 use lexopt::prelude::*;
22
23 let mut parser = lexopt::Parser::from_env();
24 loop {
25 if let Some(num) = parse_dashnum(&mut parser) {
26 println!("Got number {}", num);
27 } else if let Some(arg) = parser.next()? {
28 match arg {
29 Short('f') | Long("follow") => {
30 println!("Got --follow");
31 }
32 Short('n') | Long("number") => {
33 let num: u64 = parser.value()?.parse()?;
34 println!("Got number {}", num);
35 }
36 Value(path) => {
37 let path = PathBuf::from(path);
38 println!("Got file {}", path.display());
39 }
40 _ => return Err(arg.unexpected()),
41 }
42 } else {
43 break;
44 }
45 }
46
47 Ok(())
48}49fn parse_args() -> Result<AppArgs, lexopt::Error> {
50 use lexopt::prelude::*;
51
52 let mut number = None;
53 let mut opt_number = None;
54 let mut width = 10;
55 let mut input = None;
56
57 let mut parser = lexopt::Parser::from_env();
58 while let Some(arg) = parser.next()? {
59 match arg {
60 Short('h') | Long("help") => {
61 print!("{}", HELP);
62 std::process::exit(0);
63 }
64 Long("number") => number = Some(parser.value()?.parse()?),
65 Long("opt-number") => opt_number = Some(parser.value()?.parse()?),
66 Long("width") => width = parser.value()?.parse_with(parse_width)?,
67 Value(path) if input.is_none() => input = Some(path.into()),
68 _ => return Err(arg.unexpected()),
69 }
70 }
71 Ok(AppArgs {
72 number: number.ok_or("missing required option --number")?,
73 opt_number,
74 width,
75 input: input.ok_or("missing required argument INPUT")?,
76 })
77}9fn main() -> Result<(), lexopt::Error> {
10 use lexopt::prelude::*;
11
12 let mut settings = GlobalSettings {
13 toolchain: "stable".to_owned(),
14 color: Color::Auto,
15 offline: false,
16 quiet: false,
17 verbose: false,
18 };
19
20 let mut parser = lexopt::Parser::from_env();
21 while let Some(arg) = parser.next()? {
22 match arg {
23 Long("color") => {
24 settings.color = parser.value()?.parse()?;
25 }
26 Long("offline") => {
27 settings.offline = true;
28 }
29 Long("quiet") => {
30 settings.quiet = true;
31 settings.verbose = false;
32 }
33 Long("verbose") => {
34 settings.verbose = true;
35 settings.quiet = false;
36 }
37 Long("help") => {
38 println!("{}", HELP);
39 std::process::exit(0);
40 }
41 Value(value) => {
42 let value = value.string()?;
43 match value.as_str() {
44 value if value.starts_with('+') => {
45 settings.toolchain = value[1..].to_owned();
46 }
47 "install" => {
48 return install(settings, parser);
49 }
50 value => {
51 return Err(format!("unknown subcommand '{}'", value).into());
52 }
53 }
54 }
55 _ => return Err(arg.unexpected()),
56 }
57 }
58
59 println!("{}", HELP);
60 Ok(())
61}Sourcepub fn from_iter<I>(args: I) -> Parser
pub fn from_iter<I>(args: I) -> Parser
Create a parser from an iterator. This is useful for testing among other things.
The first item from the iterator must be the binary name, as from std::env::args_os.
The iterator is consumed immediately.
§Example
let mut parser = lexopt::Parser::from_iter(&["myapp", "-n", "10", "./foo.bar"]);Sourcepub fn from_args<I>(args: I) -> Parser
pub fn from_args<I>(args: I) -> Parser
Create a parser from an iterator that does not include the binary name.
The iterator is consumed immediately.
bin_name() will return None. Consider using
Parser::from_iter instead.
Sourcepub fn set_short_equals(&mut self, on: bool)
pub fn set_short_equals(&mut self, on: bool)
Configure whether to parse an equals sign (=) for short options.
If this is true (the default), -o=foobar will be interpreted as
the option -o with the value foobar.
If this is false, -o=foobar will be interpreted as
the option -o with the value =foobar.
Note that even if this is true the equals sign is optional. That is,
-ofoobar and -o foobar are always interpreted as -o with the value
foobar regardless of this setting.
Most other argument parsers treat the equals sign as part of the value,
but the syntax is notably accepted by clap
and by Python’s argparse.
You may want to disable this setting if it’s common for an option’s value
to start with an equals sign. The Unix cut command for example is sometimes
used with -d=, where "=" is the value belonging to the -d option. By default
the empty string "" is parsed instead.
§Example
You can configure this right after creating the parser:
let mut parser = lexopt::Parser::from_env();
parser.set_short_equals(false);You could also do it temporarily, for an individual option:
Short('d') | Long("delimiter") => {
parser.set_short_equals(false);
delimiter = Some(parser.value()?.string()?);
parser.set_short_equals(true);
}Examples found in repository?
17fn main() -> Result<(), lexopt::Error> {
18 use lexopt::prelude::*;
19
20 let mut parser = lexopt::Parser::from_env();
21 parser.set_short_equals(false);
22 let mut free = Vec::new();
23 while let Some(arg) = parser.next()? {
24 match arg {
25 Short('n') | Long("number") => {
26 let num: u16 = parser.value()?.parse()?;
27 println!("Got number {}", num);
28 }
29 Long("shout") => {
30 println!("Got --shout");
31 }
32 Value(val) => {
33 free.push(val);
34 free.extend(parser.raw_args()?);
35 }
36 _ => return Err(arg.unexpected()),
37 }
38 }
39 println!("Got free args {:?}", free);
40 Ok(())
41}