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
// requests a string from the user which passes the programmed validation:
impl<F: Fn(&str) -> Result<(), String>> TryRead for SimpleValidate<F>
// similar to `SimpleValidate`, but also transforms the output:
impl<F: Fn(String) -> Result<O, String>, O: Display> TryRead for TransformValidate<F, O>§List Constraints
These allow you to specify which inputs are allowed. Example: read!(["a", "b", "c"])
Implemented types:
// 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>; _]
impl<Data> TryRead for [InputOption<Data>; _]
// 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; _]
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
Implemented types:
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 (prompt message, default value, and input type) 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 defaultThe 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 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 with any other piece of syntax: 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
SimpleValidateandTransformValidate - list_
constraints - Contains implementations for
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
Structs§
- Default
NotAllowed Error - Useful pre-made error
- Prompt
NotAllowed Error - Useful pre-made error
Traits§
- TryRead
- This is what powers the whole crate. Any struct 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
Type Aliases§
- BoxResult
- Just
Result<T, Box<dyn Error>>, mostly for internal use