A simple tool that asks for data until the data is valid.
If you run into any issues or need help with using read_input
in your project please email incoming+efunb/read_input@incoming.gitlab.com
When writing programs you will often need to take input from the user. If the user inputs invalid information the program needs to ask them again. Having to make this loop distracts from the useful logic in your program.
read_input
attempts to make it easy to get input from the user without having to think about converting types.
Add
toml
read_input = "0.4"
to your cargo.toml
under [dependencies]
and add
```rust
extern crate read_input;
use read_input::*; ``` to your main file.
You can get input with.
rust
let input = input_new::<Type>().get();
Where Type
is the type you want. Currently the you can use all types that implement std::str::FromStr
. This currently includes the standard library types isize
, usize
, i8
, u8
, i16
, u16
, f32
, i32
, u32
, f64
, i64
, u64
, i128
, u128
, char
, Ipv4Addr
, Ipv6Addr
, SocketAddrV4
, SocketAddrV6
and String
. Many crates also implement std::str::FromStr
for their types.
For example, if you want a valid unsigned 32bit value you could write.
rust
let input = input_new::<u32>().get();
Often rust can work out the type so you can skip explicitly stating the type.
rust
let input = input_new().get();
Custom messages are written on the same line as input and are specified with .msg()
. For example.
rust
let username: String = input_new().msg("Please input your name: ").get();
If the user presses enter before typing anything the program will return a default value when .default()
is used.
rust
let input = input_new().msg("Please input pi: ").default(3.141).get();
The default error message is "That value does not pass please try again". You can change the error message with .err()
. For example.
rust
let input = input_new::<u32>()
.msg("Please input a positive number: ")
.err("That does not look like a positive number. Please try again")
.get();
You can add your own checks to ensure the value meets your criteria. If you want a integer between 4 and 9 you could write.
rust
let input = input_new().add_test(|x| 4 < *x && *x < 9).get();
In the same style you can specify custom test errors and multiple tests. If you want a value between 4 and 9 that is not 6 you could write.
rust
let input = input_new()
.msg("Please input a number between 4 and 9 that is not 6: ")
.add_test(|x| 4 < *x && *x < 9)
.add_err_test(
|x| *x != 6,
"That value is 6! I dont want 6. Please try again"
)
.err("That does not look like a number between 4 and 9. Please try again")
.get();
You can specify custom error messages that depend on the errors produced by from_str()
with .err_match()
. An example of how this can be done can be seen here.
Using input_new().get()
can be a little verbose in simple situations. The functions simple_input()
and valid_input()
can make things simpler.
simple_input()
is the same as input_new().get()
.
valid_input(|x| 4 < *x && *x < 9)
is the same as input_new().add_test(|x| 4 < *x && *x < 9).get()
.
To use read_input
with a custom type you need to implement std::str::FromStr
for that type.
simple_guessing_game
. The guessing game form the rust book made to use read_input
.
guessing_game
. The guessing game form the rust book made to use read_input
+ some extra features.
how_long_until
. Program that uses read_input
with the crate chrono
.
point_input
. Program written to show the use of the err_match()
method.
If you are viewing this from GitHub then this is a read only copy. Please contribute to the GitLab copy here.