read_input/
shortcut.rs

1//! Collection of functions that make things a little less verbose.
2//!
3//! Using `input().get()` can be a little verbose in simple situations.
4
5use crate::{test_generators::InsideFunc, InputBuild, InputBuilder};
6use std::{error::Error, fmt::Display, str::FromStr};
7
8/// Shortcut function. Fetches input that is validated with a test function.
9///
10/// `valid_input(|x| 4 < *x && *x < 9)` is the same as `input().add_test(|x| 4 < *x && *x < 9).get()`.
11pub fn valid_input<T, F>(test: F) -> T
12where
13    T: FromStr,
14    F: Fn(&T) -> bool + 'static,
15{
16    input().add_test(test).get()
17}
18
19/// `input_inside(..)` is the same as `input().inside(..).get()`.
20///
21/// Shortcut function. Fetches input that is within a range, array or vector.
22pub fn input_inside<T, U>(constraint: U) -> T
23where
24    T: FromStr,
25    U: InsideFunc<T>,
26{
27    input().inside(constraint).get()
28}
29
30/// `simple_input()` is the same as `input().get()`.
31///
32/// Fetches input that is valid for whatever type needed.
33pub fn simple_input<T: FromStr>() -> T {
34    input().get()
35}
36
37/// Creates a new instance of [`InputBuilder`] with generic, minimal settings.
38pub fn input<T: FromStr>() -> InputBuilder<T> {
39    InputBuilder::new()
40}
41
42/// [input_d] works like [input] but uses the default input settings that are specified by the [DefaultBuilderSettings] trait.
43pub fn input_d<T: DefaultBuilderSettings>() -> InputBuilder<T> {
44    T::settings()
45}
46
47/// Trait for describing specifically tailored input settings for types.
48pub trait DefaultBuilderSettings: FromStr {
49    /// Returns tailored `InputBuilder`.
50    fn settings() -> InputBuilder<Self>;
51}
52
53impl DefaultBuilderSettings for bool {
54    fn settings() -> InputBuilder<Self> {
55        input()
56            .repeat_msg("Please input true or false: ")
57            .err("Only type true or false.")
58    }
59}
60
61impl DefaultBuilderSettings for char {
62    fn settings() -> InputBuilder<Self> {
63        input()
64            .repeat_msg("Please input a character: ")
65            .err("Only type a single character.")
66    }
67}
68
69macro_rules! impl_default_builder_for_int {
70    ($($t:ty),*) => {$(
71    impl DefaultBuilderSettings for $t {
72        fn settings() -> InputBuilder<Self> {
73            input()
74                .repeat_msg("Please input an integer: ")
75                .err("Only type integers.")
76        }
77    }
78    )*}
79}
80
81impl_default_builder_for_int! { i8, i16, i32, i64, i128, isize }
82
83macro_rules! impl_default_builder_for_whole {
84    ($($t:ty),*) => {$(
85    impl DefaultBuilderSettings for $t {
86        fn settings() -> InputBuilder<Self> {
87            input()
88                .repeat_msg("Please input a positive integer: ")
89                .err("Only type positive integers.")
90        }
91    }
92    )*}
93}
94
95impl_default_builder_for_whole! { u8, u16, u32, u64, u128, usize }
96
97macro_rules! impl_default_builder_for_float {
98    ($($t:ty),*) => {$(
99    impl DefaultBuilderSettings for $t {
100        fn settings() -> InputBuilder<Self> {
101            input()
102                .repeat_msg("Please input a number: ")
103                .err("Only type numbers or decimal point.")
104        }
105    }
106    )*}
107}
108
109impl_default_builder_for_float! { f32, f64 }
110
111/// This function can be used if [`Err`](https://doc.rust-lang.org/std/str/trait.FromStr.html#associatedtype.Err) associated type for the [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) implementation for the type you are using implements [`Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html). This can give quick error messages.
112///
113///
114/// It is for use in [InputBuild::err_match] it like this
115///
116/// ```no_run
117/// use read_input::shortcut::with_display;
118/// # use read_input::prelude::*;
119/// let number = input::<i16>()
120///     .err_match(with_display)
121///     .repeat_msg("Please input a number: ")
122///     .get();
123/// ```
124pub fn with_display<T: Display>(x: &T) -> Option<String> {
125    Some(format!("Error: \"{}\"", x))
126}
127
128#[deprecated(
129    since = "0.8.4",
130    note = "Deprecated due to the depreciation of `std::error::Error::description`. Please use the `with_display` function instead."
131)]
132#[allow(deprecated)]
133/// Produces an error message from an error type. Made for use in [InputBuild::err_match]
134pub fn with_description<T: Error>(x: &T) -> Option<String> {
135    Some(format!("Error: \"{}\"", (*x).description()))
136}