Lexopt is an argument parser for Rust. It tries to have the simplest possible design that‘s still correct. It’s so simple that it's a bit tedious to use.
Lexopt is:
OsStrings, forcing you to convert them explicitly. This lets you handle badly-encoded filenames.struct Args { thing: String, number: u32, shout: bool, } fn parse_args() -> Result<Args, lexopt::Error> { use lexopt::prelude::*; let mut thing = None; let mut number = 1; let mut shout = false; let mut parser = lexopt::Parser::from_env(); while let Some(arg) = parser.next()? { match arg { Short('n') | Long("number") => { number = parser.value()?.parse()?; } Long("shout") => { shout = true; } Value(val) if thing.is_none() => { thing = Some(val.string()?); } Long("help") => { println!("Usage: hello [-n|--number=NUM] [--shout] THING"); std::process::exit(0); } _ => return Err(arg.unexpected()), } } Ok(Args { thing: thing.ok_or("missing argument THING")?, number, shout, }) } fn main() -> Result<(), lexopt::Error> { let args = parse_args()?; let mut message = format!("Hello {}", args.thing); if args.shout { message = message.to_uppercase(); } for _ in 0..args.number { println!("{}", message); } Ok(()) }
Let's walk through this:
Parser::from_env().parser.next() in a loop to get all the arguments until they run out.Short and Long indicate an option.10 in -n 10) we call parser.value().OsString.use lexopt::prelude::* adds a .parse() method, analogous to str::parse.parser.value() is how we tell Parser that -n takes a value at all.Value indicates a free-standing argument.if thing.is_none() is a useful pattern for positional arguments. If we already found thing we pass it on to another case.OsString..string() method decodes it into a plain String.return Err(arg.unexpected()) to turn it into an error message.This covers most of the functionality in the library. Lexopt does very little for you.
For a larger example with useful patterns, see examples/cargo.rs.
The following conventions are supported:
-q)--verbose)-- to mark the end of options= to separate options from values (--option=value, -o=value)--option value, -o value)-ovalue)-abc to mean -a -b -c)-i, which can be used standalone or as -iSUFFIX) (Parser::optional_value())Parser::values())These are not supported out of the box:
-name)--num instead of --number if it can be expanded unambiguously)Parser::raw_args() and Parser::try_raw_args() offer an escape hatch for consuming the original command line. See examples/nonstandard.rs for an example of parsing non-standard option syntax.
This library supports unicode while tolerating non-unicode arguments.
Short options may be unicode, but only a single codepoint (a char).
Options can be combined with non-unicode arguments. That is, --option=��� will not cause an error or mangle the value.
Options themselves are patched as by String::from_utf8_lossy if they‘re not valid unicode. That typically means you’ll raise an error later when they're not recognized.
For a particular application I was looking for a small parser that‘s pedantically correct. There are other compact argument parsing libraries, but I couldn’t find one that handled OsStrings and implemented all the fiddly details of the argument syntax faithfully.
This library may also be useful if a lot of control is desired, like when the exact argument order matters or not all options are known ahead of time. It could be considered more of a lexer than a parser.
This library may not be worth using if:
getopt.