mirror of
https://github.com/clap-rs/clap
synced 2024-12-12 22:02:35 +00:00
docs(tutorial): Demonstrate custom parsing
Adds a more in depth validator to validate that the port is in range in the derive and builder tutorial (section 4.2). This supersedes #3416
This commit is contained in:
parent
1b5f9e6450
commit
ee3eab1614
7 changed files with 143 additions and 11 deletions
10
Cargo.toml
10
Cargo.toml
|
@ -240,6 +240,11 @@ name = "04_01_enum"
|
||||||
path = "examples/tutorial_builder/04_01_enum.rs"
|
path = "examples/tutorial_builder/04_01_enum.rs"
|
||||||
required-features = ["cargo", "derive"]
|
required-features = ["cargo", "derive"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "04_02_parse"
|
||||||
|
path = "examples/tutorial_builder/04_02_parse.rs"
|
||||||
|
required-features = ["cargo"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "04_02_validate"
|
name = "04_02_validate"
|
||||||
path = "examples/tutorial_builder/04_02_validate.rs"
|
path = "examples/tutorial_builder/04_02_validate.rs"
|
||||||
|
@ -316,6 +321,11 @@ name = "04_01_enum_derive"
|
||||||
path = "examples/tutorial_derive/04_01_enum.rs"
|
path = "examples/tutorial_derive/04_01_enum.rs"
|
||||||
required-features = ["derive"]
|
required-features = ["derive"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "04_02_parse_derive"
|
||||||
|
path = "examples/tutorial_derive/04_02_parse.rs"
|
||||||
|
required-features = ["derive"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "04_02_validate_derive"
|
name = "04_02_validate_derive"
|
||||||
path = "examples/tutorial_derive/04_02_validate.rs"
|
path = "examples/tutorial_derive/04_02_validate.rs"
|
||||||
|
|
17
examples/tutorial_builder/04_02_parse.rs
Normal file
17
examples/tutorial_builder/04_02_parse.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
use clap::{app_from_crate, arg};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let matches = app_from_crate!()
|
||||||
|
.arg(
|
||||||
|
arg!(<PORT>)
|
||||||
|
.help("Network port to use")
|
||||||
|
.validator(|s| s.parse::<usize>()),
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
// Note, it's safe to call unwrap() because the arg is required
|
||||||
|
let port: usize = matches
|
||||||
|
.value_of_t("PORT")
|
||||||
|
.expect("'PORT' is required and parsing will fail if its missing");
|
||||||
|
println!("PORT = {}", port);
|
||||||
|
}
|
|
@ -1,12 +1,24 @@
|
||||||
use clap::{app_from_crate, arg};
|
use clap::{app_from_crate, arg};
|
||||||
|
use std::ops::RangeInclusive;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
const PORT_RANGE: RangeInclusive<usize> = 1..=65535;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = app_from_crate!()
|
let matches = app_from_crate!()
|
||||||
.arg(
|
.arg(arg!(<PORT>).help("Network port to use").validator(|s| {
|
||||||
arg!(<PORT>)
|
usize::from_str(s)
|
||||||
.help("Network port to use")
|
.map(|port| PORT_RANGE.contains(&port))
|
||||||
.validator(|s| s.parse::<usize>()),
|
.map_err(|e| e.to_string())
|
||||||
)
|
.and_then(|result| match result {
|
||||||
|
true => Ok(()),
|
||||||
|
false => Err(format!(
|
||||||
|
"Port not in range {}-{}",
|
||||||
|
PORT_RANGE.start(),
|
||||||
|
PORT_RANGE.end()
|
||||||
|
)),
|
||||||
|
})
|
||||||
|
}))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
// Note, it's safe to call unwrap() because the arg is required
|
// Note, it's safe to call unwrap() because the arg is required
|
||||||
|
|
|
@ -449,7 +449,36 @@ For more information try --help
|
||||||
|
|
||||||
### Validated values
|
### Validated values
|
||||||
|
|
||||||
More generally, you can validate and parse into any data type.
|
More generally, you can parse into any data type.
|
||||||
|
|
||||||
|
[Example:](04_02_parse.rs)
|
||||||
|
```console
|
||||||
|
$ 04_02_parse --help
|
||||||
|
clap [..]
|
||||||
|
A simple to use, efficient, and full-featured Command Line Argument Parser
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
04_02_parse[EXE] <PORT>
|
||||||
|
|
||||||
|
ARGS:
|
||||||
|
<PORT> Network port to use
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-h, --help Print help information
|
||||||
|
-V, --version Print version information
|
||||||
|
|
||||||
|
$ 04_02_parse 22
|
||||||
|
PORT = 22
|
||||||
|
|
||||||
|
$ 04_02_parse foobar
|
||||||
|
? failed
|
||||||
|
error: Invalid value "foobar" for '<PORT>': invalid digit found in string
|
||||||
|
|
||||||
|
For more information try --help
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
A custom validator can be used to improve the error messages or provide additional validation:
|
||||||
|
|
||||||
[Example:](04_02_validate.rs)
|
[Example:](04_02_validate.rs)
|
||||||
```console
|
```console
|
||||||
|
@ -470,9 +499,9 @@ OPTIONS:
|
||||||
$ 04_02_validate 22
|
$ 04_02_validate 22
|
||||||
PORT = 22
|
PORT = 22
|
||||||
|
|
||||||
$ 04_02_validate foobar
|
$ 04_02_validate 0
|
||||||
? failed
|
? failed
|
||||||
error: Invalid value "foobar" for '<PORT>': invalid digit found in string
|
error: Invalid value "0" for '<PORT>': Port not in range 1-65535
|
||||||
|
|
||||||
For more information try --help
|
For more information try --help
|
||||||
|
|
||||||
|
|
15
examples/tutorial_derive/04_02_parse.rs
Normal file
15
examples/tutorial_derive/04_02_parse.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
use clap::Parser;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[clap(author, version, about, long_about = None)]
|
||||||
|
struct Cli {
|
||||||
|
/// Network port to use
|
||||||
|
#[clap(parse(try_from_str))]
|
||||||
|
port: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
println!("PORT = {}", cli.port);
|
||||||
|
}
|
|
@ -1,10 +1,14 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use std::ops::RangeInclusive;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
const PORT_RANGE: RangeInclusive<usize> = 1..=65535;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[clap(author, version, about, long_about = None)]
|
#[clap(author, version, about, long_about = None)]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
/// Network port to use
|
/// Network port to use
|
||||||
#[clap(parse(try_from_str))]
|
#[clap(validator = port_in_range)]
|
||||||
port: usize,
|
port: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,3 +17,17 @@ fn main() {
|
||||||
|
|
||||||
println!("PORT = {}", cli.port);
|
println!("PORT = {}", cli.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn port_in_range(s: &str) -> Result<(), String> {
|
||||||
|
usize::from_str(s)
|
||||||
|
.map(|port| PORT_RANGE.contains(&port))
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
.and_then(|result| match result {
|
||||||
|
true => Ok(()),
|
||||||
|
false => Err(format!(
|
||||||
|
"Port not in range {}-{}",
|
||||||
|
PORT_RANGE.start(),
|
||||||
|
PORT_RANGE.end()
|
||||||
|
)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -417,6 +417,37 @@ For more information try --help
|
||||||
|
|
||||||
More generally, you can validate and parse into any data type.
|
More generally, you can validate and parse into any data type.
|
||||||
|
|
||||||
|
More generally, you can parse into any data type.
|
||||||
|
|
||||||
|
[Example:](04_02_parse.rs)
|
||||||
|
```console
|
||||||
|
$ 04_02_parse_derive --help
|
||||||
|
clap [..]
|
||||||
|
A simple to use, efficient, and full-featured Command Line Argument Parser
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
04_02_parse_derive[EXE] <PORT>
|
||||||
|
|
||||||
|
ARGS:
|
||||||
|
<PORT> Network port to use
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-h, --help Print help information
|
||||||
|
-V, --version Print version information
|
||||||
|
|
||||||
|
$ 04_02_parse_derive 22
|
||||||
|
PORT = 22
|
||||||
|
|
||||||
|
$ 04_02_parse_derive foobar
|
||||||
|
? failed
|
||||||
|
error: Invalid value "foobar" for '<PORT>': invalid digit found in string
|
||||||
|
|
||||||
|
For more information try --help
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
A custom validator can be used to improve the error messages or provide additional validation:
|
||||||
|
|
||||||
[Example:](04_02_validate.rs)
|
[Example:](04_02_validate.rs)
|
||||||
```console
|
```console
|
||||||
$ 04_02_validate_derive --help
|
$ 04_02_validate_derive --help
|
||||||
|
@ -436,9 +467,9 @@ OPTIONS:
|
||||||
$ 04_02_validate_derive 22
|
$ 04_02_validate_derive 22
|
||||||
PORT = 22
|
PORT = 22
|
||||||
|
|
||||||
$ 04_02_validate_derive foobar
|
$ 04_02_validate_derive 0
|
||||||
? failed
|
? failed
|
||||||
error: Invalid value "foobar" for '<PORT>': invalid digit found in string
|
error: Invalid value "0" for '<PORT>': Port not in range 1-65535
|
||||||
|
|
||||||
For more information try --help
|
For more information try --help
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue