This blog post is the fifth in a series that describes the structure of the wink command line program that I have written in rust and that I use to invoke other Windows and Linux programs from bash and Windows shells under Windows Subsystem for Linux. This post describes the WinkConfig struct used to represent command line arguments to the program, defined in the /src/winkconfig.rs file and hence crate::winkconfig:WinkConfig.
- Anatomy of a Rust Program, Part I: Wink cargo.toml – rustapopoulos.com
- /src/winkconfig.rs: Defines and implements the WinkConfig struct used to model command line arguments to the wink program.
The file /src/winkconfig.rs defines the WinkConfig struct and the implementation of its members (crate::winkconfig::WinkConfig). WinkConfig represents command line parameters passed to the wink command.
Before the definition of the WinkConfig struct, this line enables the serde library to serialize the fields in the struct as JSON. Compilations will fail if the struct does not meet requirements for serde. For my purposes, all fields are public.
The fmt() function renders the WinkConfig as JSON for debugging purposes, repurposing the -p parameter used by the wink command itself to enable pretty-printing of JSON exports of its configuration.
Most of the logic is in the new() function, which accepts a vector (ordered list) of strings that the main() method in /src/main.rs determines from command line arguments and passes to new().
The first command line argument is the name of the command, such as wink or wink.exe or /path/to/wink. The new() function ignores that at first, iterating the command line arguments until it finds “help” or one that does not begin with a slash or a dash, which should be the command code that indicates which invocable to invoke. Any other command line options enable options or render help.
Note the use of to_owned. Rust enforces scope in a way that sometimes requires use of constructs to control which variables determine when the system frees memory.
The new() method then constructs a WinkConfig. Note that when field names match variable names, we can specify field names without the matching variable names.
If there is no reason to render usage information, then the new() method returns the WinkConfig in an Ok enumeration. Otherwise, it returns the WinkConfig and Box that contains a HelpError (/src/helperror.rs) that informs the caller to render usage information for the command.
To demonstrate testing, this class includes a mod named tests, which is a naming convention. When run with cargo run, a special main() method invokes tests attributed such as these.
The it_get_from_command_line_args() function removes some command line arguments that may appear when running under cargo test.
- Rust Warning: Cargo Test Passes Its Command Line Arguments to Your (Test) Programs – rustapopoulos.com
The it_has_a_path() test panics, which means crashing the program, but the #[should_panic] attribute interprets only a panic as a successful test. This is useful for determining absolute paths to things – run the tests for the thing and see its path.