Expand description
Complex but easy ways to read user input
§Functionality in this crate is defined by types that implement TryRead
.
§Types that implement TryRead
:
This is basically a list of all default functionality, if you want to know more about one of these types, the header name is the same as the module which contains the type
§Basics
impl TryRead for () // requests any string from the user
impl TryRead for NonEmptyInput // requests a non-empty string from the user
impl TryRead for NonWhitespaceInput // requests a non-whitespace string from the user
impl TryRead for BoolInput // requests a true/false/t/f string from the user
impl TryRead for YesNoInput // requests a yes/no/y/n string from the user
impl TryRead for CharInput // requests a single-char string from the user
// requests a number from the user that can be converted to a specific type:
impl TryRead for U8Input, U16Input, U32Input, U64Input, U128Input, USizeInput
impl TryRead for I8Input, I16Input, I32Input, I64Input, I128Input, ISizeInput
impl TryRead for F32Input
impl TryRead for F64Input
§Input Validations
These allow you to easily add custom logic to specific reads
// requests a string from the user which passes the programmed validation:
impl<F> TryRead for SimpleValidate<F> where F: Fn(&str) -> Result<(), String>
// similar to `SimpleValidate`, but also transforms the output:
impl<F, O> TryRead for TransformValidate<F, O> where F: Fn(String) -> Result<O, String>, O: Display
§List Constraints
These allow you to specify which inputs are allowed. Example: read!(["a", "b", "c"])
NOTE: The default value for these types denotes the index of the default option
// requests a string from the user that matches any of the names from the `InputOption`s:
impl<Data> TryRead for &[InputOption<Data>]
impl<Data> TryRead for &[InputOption<Data>; N]
impl<Data> TryRead for [InputOption<Data>; N]
// requests a string from the user that matches any value in the list:
impl<T: Display> TryRead for &[T]
impl<T: Display> TryRead for [T; N]
impl<T: Display> TryRead for Vec<T>
impl<T: Display> TryRead for VecDeque<T>
impl<T: Display> TryRead for LinkedList<T>
§Range Constraints
These allow you to take a number within a specified range. Example: read!(1. ..= 100.)
, read!(10..)
, etc
impl<T> TryRead for Range<T> where T: Display + FromStr + PartialOrd<T>, <T as FromStr>::Err: Display
impl<T> TryRead for RangeInclusive<T> where T: Display + FromStr + PartialOrd<T>, <T as FromStr>::Err: Display
impl<T> TryRead for RangeTo<T> where T: Display + FromStr + PartialOrd<T>, <T as FromStr>::Err: Display
impl<T> TryRead for RangeFrom<T> where T: Display + FromStr + PartialOrd<T>, <T as FromStr>::Err: Display
impl<T> TryRead for RangeToInclusive<T> where T: Display + FromStr + PartialOrd<T>, <T as FromStr>::Err: Display
§Macro Syntax
Prompt macros: prompt!("message to user"; [default_value] input_type)
Read macros: read!([default_value] input_type)
All components are optional (except the message in prompts) and all are expressions.
Some examples:
read!([2] 1..=10); // take a number from 1 to 10, with 2 as the default
prompt!(messages[i]; UsizeInput); // request a positive integer for the current prompt
prompt!("continue?"; [true] YesNoInput); // request a yes/no input with yes being the default
The input type is what determines the functionality of the input. It is another expression, and the type of the resulting value is what determines which impl of TryRead
is used. For example, if you have read!(1..10)
then the impl for Range<i32>
is used. Also, when you have something like read!(UsizeInput)
, you are creating a new UsizeInput
value and passing it to the macro.
Some input types have special syntax that can be substituted for the input_type component, they are:
// this:
read!()
// is this:
read!(())
// this:
read!(= 1, 2, 3)
// is this:
read!([1, 2, 3])
// this:
read!(=
"1_bulletin"; "1_display_name"; ["1_alt_name_1", ...]; 1_data,
"2_bulletin"; "2_display_name"; ["2_alt_name_1", ...]; 2_data,
...
)
// is this:
read!([
InputOption::new("1_bulletin", vec!("1_display_name", "1_alt_name_1", ...), 1_data),
InputOption::new("2_bulletin", vec!("2_display_name", "2_alt_name_1", ...), 2_data),
...
])
And of course, you can combine this special input type syntax with everything else: prompt!("Enter a color: "; ["red"] = "red", "green", "blue")
If you have ideas for more functionality (including things you’ve found to be useful yourself), feel free to open an issue / pull request
Modules§
- basics
- Contains implementations for
()
,UsizeInput
,NonEmptyInput
, etc - input_
validation - Contains implementations for
SimpleValidate
andTransformValidate
- list_
constraints - Contains implementations for
&[T]
,[T; N]
,Vec<T>
,read!(= a, b, c)
, etc - prelude
- Easy way to use existing functionality. If you want to extend functionality instead, you can do
use smart_read::*;
- range_
constraints - Contains implementations for
Range<T>
,RangeFrom<T>
, etc
Macros§
- prompt
- Same as
read!()
, but also prints a prompt - read
- Reads a line of text, a number, etc
- try_
prompt - Same as
prompt!()
, but returns a result - try_
read - Same as
read!()
, but returns a result
Traits§
- TryRead
- This is what powers the whole crate. Any type that implements this can be used with the macros
Functions§
- clear_
term - Tiny utility function, clears the terminal output, but you should probably use the ClearScreen crate instead
- read_
stdin - Utility function, mostly for internal use
- wait_
for_ enter - Waits for the user to press enter, prints “Press enter to continue “
Type Aliases§
- BoxResult
- Just
Result<T, Box<dyn Error>>
, mostly for internal use