Skip to content

Commit

Permalink
doc,comment: added descriptions for parse_with method of Cmd (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
sttk authored Jun 17, 2024
1 parent c8bc5c2 commit d0db13f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 3 deletions.
64 changes: 61 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This library provides the following functionalities:
- This library supports `--` option.
- This library doesn't support numeric short option.
- This library supports not `-ofoo` but `-o=foo` as an alternative to `-o foo` for short option.
- Supports parsing with option configurations. *(To be added)*
- Supports parsing with option configurations.
- Supports parsing with an object which stores option values and has annotations of fields. *(To be added)*
- Is able to parse command line arguments including sub commands. *(To be added)*
- Generates help text from option configurations. *(To be added)*
Expand Down Expand Up @@ -86,16 +86,74 @@ All command line arguments after `--` are command arguments, even they starts wi
use cliargs::Cmd;
use cliargs::errors::InvalidOption;
let cmd = Cmd::with_strings(vec![ /* ... */ ]);
let mut cmd = Cmd::with_strings(vec![ /* ... */ ]);
match cmd.parse() {
Ok(_) => { /* ... */ },
Err(InvalidOption::OptionContainsInvalidChar { option }) => {
panic!("Option contains invalid character: {option}");
},
Err(errr) => panic!("Invalid option: {}", err.option()),
Err(err) => panic!("Invalid option: {}", err.option()),
}
```

### Parses with configurations

The `Cmd` struct has the method `parse_with` which parses command line arguments with configurations.
This method takes an array of option configurations: `OptCfg`, and divides command line arguments to options and command arguments according to this configurations..

An option configuration has fields: `store_key`, `names`, `has_arg`, `is_array`, `defaults`, `desc`, `arg_in_help`, and `validator`.

`store_key` field is specified the key name to store the option value to the option map in the `Cmd` instance.
If this field is not specified, the first element of `names` field is used instead.

`names` field is a string array and specified the option names, that are both long options and short options.
The order of elements in this field is used in a help text.
If you want to prioritize the output of short option name first in the help text, like `-f, --foo-bar`, but use the long option name as the key in the option map, write `store_key` and `names` fields as follows: `OptCfg::with(&[store_key("foo-bar"), names(&["f", "foo-bar"])])`.

`has_arg` field indicates the option requires one or more values.
`is_array` field indicates the option can have multiple values.
`defaults` field is an array of string which is used as default one or more option arguments if the option is not specified.
`desc` is a description of the option for help text.
`arg_n_help` field is a text which is output after option name and aliases as an option value in help text.

`validator` field is to set a function pointer which validates an option argument.
This crate provides the validator `cliargs::validators::validate_number<T>` which validates whether an option argument is valid format as a number.

```
use cliargs::{Cmd, OptCfg};
use cliargs::OptCfgParam::{names, has_arg, defaults, validator, desc, arg_in_help};
use cliargs::validators::validate_number;
use cliargs::errors::InvalidOption;
let mut cmd = Cmd::with_strings(vec![ /* ... */ ]);
let opt_cfgs = vec![
OptCfg::with(&[
names(&["foo-bar"]),
desc("This is description of foo-bar."),
]),
OptCfg::with(&[
names(&["baz", "z"]),
has_arg(true),
defaults(&["1"]),
desc("This is description of baz."),
arg_in_help("<num>"),
validator(validate_number::<u32>),
]),
];
match cmd.parse_with(&opt_cfgs) {
Ok(_) => { /* ... */ },
Err(InvalidOption::OptionContainsInvalidChar { option }) => { /* ... */ },
Err(InvalidOption::UnconfiguredOption { option }) => { /* ... */ },
Err(InvalidOption::OptionNeedsArg { option, .. }) => { /* ... */ },
Err(InvalidOption::OptionTakesNoArg { option, .. }) => { /* ... */ },
Err(InvalidOption::OptionIsNotArray { option, .. }) => { /* ... */ },
Err(InvalidOption::OptionArgIsInvalid { option, opt_arg, details, .. }) => { /* ... */ },
Err(err) => panic!("Invalid option: {}", err.option()),
}
```


## Supporting Rust versions

This crate supports Rust 1.74.1 or later.
Expand Down
14 changes: 14 additions & 0 deletions src/parse/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ impl<'a> Cmd<'a> {
/// Since the results of parsing are stored into this `Cmd` instance, this
/// method returns a [Result] which contains an unit value (`()`) if
/// succeeding, or a `errors::InvalidOption` if failing.
///
/// ```rust
/// use cliargs::Cmd;
/// use cliargs::errors::InvalidOption;
///
/// let mut cmd = Cmd::with_strings(vec![ /* ... */ ]);
/// match cmd.parse() {
/// Ok(_) => { /* ... */ },
/// Err(InvalidOption::OptionContainsInvalidChar { option }) => {
/// panic!("Option contains invalid character: {option}");
/// },
/// Err(err) => panic!("Invalid option: {}", err.option()),
/// }
/// ```
pub fn parse(&mut self) -> Result<(), InvalidOption> {
let collect_args = |arg| {
self.args.push(arg);
Expand Down
34 changes: 34 additions & 0 deletions src/parse/parse_with.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,40 @@ impl<'a> Cmd<'a> {
/// basically.
/// An option configuration has fields: `store_key`, `names`, `has_arg`,
/// `is_array`, `defaults`, `desc`, `arg_in_help`, and `validator`.
///
/// ```
/// use cliargs::{Cmd, OptCfg};
/// use cliargs::OptCfgParam::{names, has_arg, defaults, validator, desc, arg_in_help};
/// use cliargs::validators::validate_number;
/// use cliargs::errors::InvalidOption;
///
/// let mut cmd = Cmd::with_strings(vec![ /* ... */ ]);
/// let opt_cfgs = vec![
/// OptCfg::with(&[
/// names(&["foo-bar"]),
/// desc("This is description of foo-bar."),
/// ]),
/// OptCfg::with(&[
/// names(&["baz", "z"]),
/// has_arg(true),
/// defaults(&["1"]),
/// desc("This is description of baz."),
/// arg_in_help("<num>"),
/// validator(validate_number::<u32>),
/// ]),
/// ];
///
/// match cmd.parse_with(&opt_cfgs) {
/// Ok(_) => { /* ... */ },
/// Err(InvalidOption::OptionContainsInvalidChar { option }) => { /* ... */ },
/// Err(InvalidOption::UnconfiguredOption { option }) => { /* ... */ },
/// Err(InvalidOption::OptionNeedsArg { option, .. }) => { /* ... */ },
/// Err(InvalidOption::OptionTakesNoArg { option, .. }) => { /* ... */ },
/// Err(InvalidOption::OptionIsNotArray { option, .. }) => { /* ... */ },
/// Err(InvalidOption::OptionArgIsInvalid { option, opt_arg, details, .. }) => { /* ... */ },
/// Err(err) => panic!("Invalid option: {}", err.option()),
/// }
/// ```
pub fn parse_with(&mut self, opt_cfgs: &[OptCfg]) -> Result<(), InvalidOption> {
let mut cfg_map = HashMap::<&str, usize>::new();
let mut opt_map = HashMap::<&str, ()>::new();
Expand Down

0 comments on commit d0db13f

Please sign in to comment.