quick_input/
lib.rs

1//! # Quick Input
2//!
3//! This lightweight library offers a quick and easy way of handling user input, which can then
4//! be assigned to a variable directly. All functions handle the possibility of invalid values by
5//! looping until the desired type is inputted.
6//!
7//! Both an initial prompt message and error message are customisable and optional.
8//! If the error message is left empty (None), a default error message will be displayed
9//! (relaying on the default message should be avoided when possible).
10//!
11//! # Author
12//! - Kevin Claramonte Soler (kevclasol@proton.me).
13//! - 16/03/2025
14
15use std::io;
16use std::io::Write;
17
18// ----- MACROS ----- //
19
20#[macro_export]
21macro_rules! read_string {
22    () => {{
23        use std::io::Write;
24
25        std::io::stdout().flush().expect("Failed to flush stdout.");
26
27        let mut input = String::new();
28        std::io::stdin().read_line(&mut input).expect("Failed to read line.");
29
30        input.trim().to_string()
31    }};
32    ($message:expr) => {{
33        print!("{}", $message);
34        read_string!()
35    }};
36}
37
38#[macro_export]
39macro_rules! read_i32 {
40    () => {{
41        let mut input = String::new();
42
43        while input.trim().parse::<i32>().is_err() {
44            input.clear();
45            flush_and_read(&mut input);
46
47            if input.trim().parse::<i32>().is_err() {
48                println!("---");
49                print!("Please enter a valid number (32 bits): ");
50            }
51        }
52
53        input.trim().parse().unwrap()
54    }};
55
56    ($message:expr) => {{
57       let mut input = String::new();
58
59        while input.trim().parse::<i32>().is_err() {
60            input.clear();
61
62            print!("{}", $message);
63            flush_and_read(&mut input);
64
65            if input.trim().parse::<i32>().is_err() {
66                println!("---");
67            }
68        }
69
70        input.trim().parse().unwrap()
71    }};
72
73    ($message:expr, $err_msg:expr) => {{
74        let mut input = String::new();
75
76        while input.trim().parse::<i32>().is_err() {
77            input.clear();
78
79            print!("{}", $message);
80            flush_and_read(&mut input);
81
82            if input.trim().parse::<i32>().is_err() {
83                println!($err_msg);
84                println!("---");
85            }
86        }
87
88        input.trim().parse().unwrap()
89    }};
90}
91
92// ----- MACROS ----- //
93
94// ----- FUNCTIONS ----- //
95
96#[deprecated(since = "0.1.10", note = "Please use `read_string!` macro instead.")]
97/// # ARGUMENTS #
98/// 'msg' (Option<&str>) - an optional message which will be printed at
99/// the same line as the input prompt. Must be set to Some("...") or None.
100///
101/// # DESCRIPTION #
102/// Prompts the user to type a string of text which will then be returned.
103///
104/// Provides an information message on the same line as the prompt if Some(...)
105/// is provided, and just the prompt if None is provided.
106///
107/// # RETURNS #
108/// A trimmed String value provided by the user.
109///
110/// # EXAMPLES #
111/// ```
112/// use quick_input::read_string;
113/// let user_str_with_msg = read_string(Some("Please input some text: "));
114///
115/// let user_str: String = read_string(None);
116/// ```
117pub fn read_string(msg: Option<&str>) -> String {
118    let mut input = String::new();
119
120    if msg.is_some() {
121        print!("{}", msg.unwrap());
122        flush_and_read(&mut input);
123    } else {
124        flush_and_read(&mut input);
125    }
126
127    input.trim().to_string()
128}
129
130#[deprecated(since = "0.1.10", note = "Please use `read_i32!` macro instead.")]
131/// # ARGUMENTS #
132/// 'msg' (Option<&str>) - an optional message which will be printed at
133/// the same line as the input prompt. Must be set to Some("...") or None.
134///
135/// 'err_msg' (Option<&str>) - an optional error message which will be printed
136/// if the user inputs an invalid value. Must be set to Some("...") or None.
137///
138/// # DESCRIPTION #
139/// Prompts the user to type an integer value (i32) which will then be returned.
140/// In case the user writes an invalid value, they will be prompted to try again.
141///
142/// Provides an information message on the same line as the prompt if Some("...")
143/// is provided, and just the prompt if None is provided.
144///
145/// If err_msg is set to None, a default message will be shown.
146///
147/// # RETURNS #
148/// An integer value of type i32 provided by the user.
149///
150/// # EXAMPLES #
151/// ```
152/// use quick_input::read_i32;
153/// let user_i32_with_msg = read_i32(Some("Please input a number: "), Some("Please input a valid number."));
154///
155/// let user_i32: i32 = read_i32(None, None);
156/// ```
157pub fn read_i32(msg: Option<&str>, err_msg: Option<&str>) -> i32 {
158    let mut input = String::new();
159
160    if msg.is_some() {
161        while input.trim().parse::<i32>().is_err() {
162            input.clear();
163            print!("{}", msg.unwrap());
164            flush_and_read(&mut input);
165
166            if input.trim().parse::<i32>().is_err() {
167                show_error_message(err_msg, "Please enter a valid number (32 bits).");
168            }
169        }
170    } else {
171        while input.trim().parse::<i32>().is_err() {
172            input.clear();
173            flush_and_read(&mut input);
174
175            if input.trim().parse::<i32>().is_err() {
176                show_error_message(err_msg, "Please enter a valid number (32 bits).");
177            }
178        }
179    }
180
181    input.trim().parse().unwrap()
182}
183
184/// # ARGUMENTS #
185/// 'msg' (Option<&str>) - an optional message which will be printed at
186/// the same line as the input prompt. Must be set to Some("...") or None.
187///
188/// 'err_msg' (Option<&str>) - an optional error message which will be printed
189/// if the user inputs an invalid value. Must be set to Some("...") or None.
190///
191/// # DESCRIPTION #
192/// Prompts the user to type an integer value (u32) which will then be returned.
193/// If user writes an invalid value, they will be prompted to try again.
194///
195/// Provides an information message on the same line as the prompt if Some("...")
196/// is provided, and just the prompt if None is provided.
197///
198/// If err_msg is set to None, a default message will be shown.
199///
200/// # RETURNS #
201/// An integer value of type u32 provided by the user.
202///
203/// # EXAMPLES #
204/// ```
205/// use quick_input::read_u32;
206/// let user_u32_with_msg = read_u32(Some("Please input a number: "), Some("Please input a valid number."));
207///
208/// let user_u32: u32 = read_u32(None, None);
209/// ```
210pub fn read_u32(msg: Option<&str>, err_msg: Option<&str>) -> u32 {
211    let mut input = String::new();
212
213    if msg.is_some() {
214        while input.trim().parse::<u32>().is_err() {
215            input.clear();
216            print!("{}", msg.unwrap());
217            flush_and_read(&mut input);
218
219            if input.trim().parse::<u32>().is_err() {
220                show_error_message(err_msg, "Please enter a valid positive number (32 bits).");
221            }
222        }
223    } else {
224        while input.trim().parse::<i32>().is_err() {
225            input.clear();
226            flush_and_read(&mut input);
227
228            if input.trim().parse::<i32>().is_err() {
229                show_error_message(err_msg, "Please enter a valid positive number (32 bits).");
230            }
231        }
232    }
233
234    input.trim().parse().unwrap()
235}
236
237/// # ARGUMENTS #
238/// 'msg' (Option<&str>) - an optional message which will be printed at
239/// the same line as the input prompt. Must be set to Some("...") or None.
240///
241/// 'err_msg' (Option<&str>) - an optional error message which will be printed
242/// if the user inputs an invalid value. Must be set to Some("...") or None.
243///
244/// # DESCRIPTION #
245/// Prompts the user to type a real number with double precision (f64) which will then be returned.
246/// Both '.' and ',' are accepted as separators for the decimal part (Ex: 12.3 and 45,67).
247/// If the user writes an invalid value, they will be prompted to try again.
248///
249/// Provides an information message on the same line as the prompt if Some("...")
250/// is provided, and just the prompt if None is provided.
251///
252/// If err_msg is set to None, a default message will be shown.
253///
254/// # RETURNS #
255/// A floating point value of type f64 provided by the user.
256///
257/// # EXAMPLES #
258/// ```
259/// use quick_input::read_f64;
260/// let user_f64_with_msg = read_f64(Some("Please input a number with decimals: "), Some("Please input a valid number."));
261///
262/// let user_f64: f64 = read_f64(None, None);
263/// ```
264pub fn read_f64(msg: Option<&str>, err_msg: Option<&str>) -> f64 {
265    let mut input = String::new();
266
267    if msg.is_some() {
268        while input.replace(',', ".").trim().parse::<f64>().is_err() {
269            input.clear();
270            print!("{}", msg.unwrap());
271            flush_and_read(&mut input);
272
273            if input.replace(',', ".").trim().parse::<f64>().is_err() {
274                show_error_message(err_msg, "Please enter a valid real number (64 bits).");
275            }
276        }
277    } else {
278        while input.trim().parse::<f64>().is_err() {
279            input.clear();
280            flush_and_read(&mut input);
281
282            if input.replace(',', ".").trim().parse::<f64>().is_err() {
283                show_error_message(err_msg, "Please enter a valid real number (64 bits).");
284            }
285        }
286    }
287
288    input.replace(',', ".").trim().parse().unwrap()
289}
290
291/// # ARGUMENTS #
292/// 'msg' (Option<&str>) - an optional message which will be printed at
293/// the same line as the input prompt. Must be set to Some("...") or None.
294///
295/// # DESCRIPTION #
296/// Prompts the user to type a character (char) which will then be returned.
297///
298/// Provides an information message on the same line as the prompt if Some("...")
299/// is provided, and just the prompt if None is provided.
300///
301/// # RETURNS #
302/// A single character (char) provided by the user.
303///
304/// # EXAMPLES #
305/// ```
306/// use quick_input::read_char;
307/// let user_char_with_msg = read_char(Some("Please input a character: "));
308///
309/// let user_char: char = read_char(None);
310/// ```
311pub fn read_char(msg: Option<&str>) -> char {
312    let mut input = String::from(".");
313
314    if msg.is_some() {
315        input.clear();
316        print!("{}", msg.unwrap());
317        flush_and_read(&mut input);
318    } else {
319        input.clear();
320        flush_and_read(&mut input);
321    }
322
323    input.trim().chars().next().unwrap()
324}
325
326/// # ARGUMENTS #
327/// 'msg' (Option<&str>) - an optional message which will be printed at
328/// the same line as the input prompt. Must be set to Some("...") or None.
329///
330/// 'err_msg' (Option<&str>) - an optional error message which will be printed
331/// if the user inputs an invalid value. Must be set to Some("...") or None.
332///
333/// # DESCRIPTION #
334/// Prompts the user to type a boolean value (bool) manually, which will then be returned.
335/// This function is not case-sensitive, so values like True or fAlSe will still work.
336/// In case the user writes an invalid value, they will be prompted to try again.
337///
338/// Provides an information message on the same line as the prompt if Some("...")
339/// is provided, and just the prompt if None is provided.
340///
341/// If err_msg is set to None, a default message will be shown.
342///
343/// # RETURNS #
344/// A boolean value (bool) provided by the user.
345///
346/// # EXAMPLES #
347/// ```
348/// use quick_input::read_bool;
349/// let user_bool_with_msg = read_bool(Some("Please input a boolean value: "), Some("Please input true or false."));
350///
351/// let user_bool: bool = read_bool(None, None);
352/// ```
353pub fn read_bool(msg: Option<&str>, err_msg: Option<&str>) -> bool {
354    let mut input = String::new();
355
356    if msg.is_some() {
357        while input.trim().parse::<bool>().is_err() {
358            input.clear();
359            print!("{}", msg.unwrap());
360            flush_and_read(&mut input);
361
362            input = input.trim().to_lowercase();
363
364            if input.parse::<bool>().is_err() {
365                show_error_message(err_msg, "Please enter a valid boolean value (true / false).");
366            }
367        }
368    } else {
369        while input.trim().parse::<bool>().is_err() {
370            input.clear();
371            flush_and_read(&mut input);
372
373            input = input.trim().to_lowercase();
374
375            println!("{input}");
376
377            if input.parse::<bool>().is_err() {
378                show_error_message(err_msg, "Please enter a valid boolean value (true / false).");
379            }
380        }
381    }
382
383    input.trim().parse::<bool>().unwrap()
384}
385
386// ----- EXTRA ----- //
387
388/// # ARGUMENTS #
389/// 'msg' (Option<&str>) - an optional message which will be printed at
390/// the same line as the input prompt. Must be set to Some("...") or None.
391///
392/// # DESCRIPTION #
393/// Prompts the user to type a string of text which will then be returned.
394///
395/// Provides an information message on the same line as the prompt if Some(...)
396/// is provided, and just the prompt if None is provided.
397///
398/// # RETURNS #
399/// A non-trimmed String value provided by the user.
400///
401/// # EXAMPLES #
402/// ```
403/// use quick_input::read_string_untrimmed;
404/// let user_str_with_msg = read_string_untrimmed(Some("Please input some text: "));
405///
406/// let user_str: String = read_string_untrimmed(None);
407/// ```
408pub fn read_string_untrimmed(msg: Option<&str>) -> String {
409    let mut input = String::new();
410
411    if msg.is_some() {
412        print!("{}", msg.unwrap());
413        flush_and_read(&mut input);
414    } else {
415        flush_and_read(&mut input);
416    }
417    input
418}
419
420/// # DESCRIPTION #
421/// Prompts the user to type a string of text which will then be returned.
422/// Useful for prototyping and quick tests.
423///
424/// # RETURNS #
425/// A trimmed String value provided by the user.
426///
427/// # EXAMPLES #
428/// ```
429/// use quick_input::read_string_no_msg;
430///
431/// let user_str: String = read_string_no_msg();
432/// ```
433pub fn read_string_no_msg() -> String {
434    read_string(None)
435}
436
437/// # DESCRIPTION #
438/// Prompts the user to type a character (char) which will then be returned.
439/// Useful for prototyping or quick tests.
440///
441/// # RETURNS #
442/// A single character (char) provided by the user.
443///
444/// # EXAMPLES #
445/// ```
446/// use quick_input::read_char_no_msg;
447///
448/// let user_char: char = read_char_no_msg();
449/// ```
450pub fn read_char_no_msg() -> char {
451    read_char(None)
452}
453
454/// # ARGUMENTS #
455/// 'msg' (Option<&str>) - an optional message which will be printed at
456/// the same line as the input prompt. Must be set to Some("...") or None.
457///
458/// # DESCRIPTION #
459/// Prompts the user to type an integer value (i32) which will then be returned.
460/// In case the user writes an invalid value, they will be prompted to try again.
461///
462/// Provides an information message on the same line as the prompt if Some("...")
463/// is provided, and just the prompt if None is provided.
464///
465/// Useful for prototyping and quick tests.
466///
467/// # RETURNS #
468/// An integer value of type i32 provided by the user.
469///
470/// # EXAMPLES #
471/// ```
472/// use quick_input::read_i32_def_err;
473/// let user_i32_with_msg = read_i32_def_err(Some("Please input a number: "));
474///
475/// let user_i32: i32 = read_i32_def_err(None);
476/// ```
477pub fn read_i32_def_err(msg: Option<&str>) -> i32 {
478    read_i32(msg, None)
479}
480
481/// # ARGUMENTS #
482/// 'msg' (Option<&str>) - an optional message which will be printed at
483/// the same line as the input prompt. Must be set to Some("...") or None.
484///
485/// # DESCRIPTION #
486/// Prompts the user to type a real number with double precision (f64) which will then be returned.
487/// Both '.' and ',' are accepted as separators for the decimal part (Ex: 12.3 and 45,67).
488/// If the user writes an invalid value, they will be prompted to try again.
489///
490/// Provides an information message on the same line as the prompt if Some("...")
491/// is provided, and just the prompt if None is provided.
492///
493/// Useful for prototyping and quick tests.
494///
495/// # RETURNS #
496/// A floating point value of type f64 provided by the user.
497///
498/// # EXAMPLES #
499/// ```
500/// use quick_input::read_f64_def_err;
501/// let user_f64_with_msg = read_f64_def_err(Some("Please input a number with decimals: "));
502///
503/// let user_f64: f64 = read_f64_def_err(None);
504/// ```
505pub fn read_f64_def_err(msg: Option<&str>) -> f64 {
506    read_f64(msg, None)
507}
508
509/// # ARGUMENTS #
510/// 'msg' (Option<&str>) - an optional message which will be printed at
511/// the same line as the input prompt. Must be set to Some("...") or None.
512///
513/// # DESCRIPTION #
514/// Prompts the user to type an integer value (u32) which will then be returned.
515/// If user writes an invalid value, they will be prompted to try again.
516///
517/// Provides an information message on the same line as the prompt if Some("...")
518/// is provided, and just the prompt if None is provided.
519///
520/// Useful for prototyping and quick tests.
521///
522/// # RETURNS #
523/// An integer value of type u32 provided by the user.
524///
525/// # EXAMPLES #
526/// ```
527/// use quick_input::read_u32_def_err;
528/// let user_u32_with_msg = read_u32_def_err(Some("Please input a number: "));
529///
530/// let user_u32: u32 = read_u32_def_err(None);
531/// ```
532pub fn read_u32_def_err(msg: Option<&str>) -> u32 {
533    read_u32(msg, None)
534}
535
536/// # ARGUMENTS #
537/// 'msg' (Option<&str>) - an optional message which will be printed at
538/// the same line as the input prompt. Must be set to Some("...") or None.
539///
540/// 'err_msg' (Option<&str>) - an optional error message which will be printed
541/// if the user inputs an invalid value. Must be set to Some("...") or None.
542///
543/// # DESCRIPTION #
544/// Prompts the user to type a real number with single precision (f32) which will then be returned.
545/// Both '.' and ',' are accepted as separators for the decimal part (Ex: 12.3 and 45,67).
546/// If the user writes an invalid value, they will be prompted to try again.
547///
548/// Provides an information message on the same line as the prompt if Some("...")
549/// is provided, and just the prompt if None is provided.
550///
551/// If err_msg is set to None, a default message will be shown.
552///
553/// # RETURNS #
554/// A floating point value of type f32 provided by the user.
555///
556/// # EXAMPLES #
557/// ```
558/// use quick_input::read_f32;
559/// let user_f32_with_msg = read_f32(Some("Please input a number with decimals: "), Some("Please input a valid number."));
560///
561/// let user_f32: f32 = read_f32(None, None);
562/// ```
563pub fn read_f32(msg: Option<&str>, err_msg: Option<&str>) -> f32 {
564    let mut input = String::new();
565
566    if msg.is_some() {
567        while input.replace(',', ".").trim().parse::<f32>().is_err() {
568            input.clear();
569            print!("{}", msg.unwrap());
570            flush_and_read(&mut input);
571
572            if input.replace(',', ".").trim().parse::<f32>().is_err() {
573                show_error_message(err_msg, "Please enter a valid real number (32 bits).");
574            }
575        }
576    } else {
577        while input.trim().parse::<f32>().is_err() {
578            input.clear();
579            flush_and_read(&mut input);
580
581            if input.replace(',', ".").trim().parse::<f32>().is_err() {
582                show_error_message(err_msg, "Please enter a valid real number (32 bits).");
583            }
584        }
585    }
586
587    input.replace(',', ".").trim().parse().unwrap()
588}
589
590/// # ARGUMENTS #
591/// 'msg' (Option<&str>) - an optional message which will be printed at
592/// the same line as the input prompt. Must be set to Some("...") or None.
593///
594/// 'err_msg' (Option<&str>) - an optional error message which will be printed
595/// if the user inputs an invalid value. Must be set to Some("...") or None.
596///
597/// # DESCRIPTION #
598/// Prompts the user to type an integer value (i8) which will then be returned.
599/// In case the user writes an invalid value, they will be prompted to try again.
600///
601/// Provides an information message on the same line as the prompt if Some("...")
602/// is provided, and just the prompt if None is provided.
603///
604/// If err_msg is set to None, a default message will be shown.
605///
606/// # RETURNS #
607/// An integer value of type i8 provided by the user.
608///
609/// # EXAMPLES #
610/// ```
611/// use quick_input::read_i8;
612/// let user_i8_with_msg = read_i8(Some("Please input a number: "),Some("Please input a valid number."));
613///
614/// let user_i8: i8 = read_i8(None, None);
615/// ```
616pub fn read_i8(msg: Option<&str>, err_msg: Option<&str>) -> i8 {
617    let mut input = String::new();
618
619    if msg.is_some() {
620        while input.trim().parse::<i8>().is_err() {
621            input.clear();
622            print!("{}", msg.unwrap());
623            flush_and_read(&mut input);
624
625            if input.trim().parse::<i8>().is_err() {
626                show_error_message(err_msg, "Please enter a valid number (8 bits).");
627            }
628        }
629    } else {
630        while input.trim().parse::<i8>().is_err() {
631            input.clear();
632            flush_and_read(&mut input);
633
634            if input.trim().parse::<i8>().is_err() {
635                show_error_message(err_msg, "Please enter a valid number (8 bits).");
636            }
637        }
638    }
639
640    input.trim().parse().unwrap()
641}
642
643/// # ARGUMENTS #
644/// 'msg' (Option<&str>) - an optional message which will be printed at
645/// the same line as the input prompt. Must be set to Some("...") or None.
646///
647/// 'err_msg' (Option<&str>) - an optional error message which will be printed
648/// if the user inputs an invalid value. Must be set to Some("...") or None.
649///
650/// # DESCRIPTION #
651/// Prompts the user to type an integer value (u8) which will then be returned.
652/// In case the user writes an invalid value, they will be prompted to try again.
653///
654/// Provides an information message on the same line as the prompt if Some("...")
655/// is provided, and just the prompt if None is provided.
656///
657/// If err_msg is set to None, a default message will be shown.
658///
659/// # RETURNS #
660/// An integer value of type u8 provided by the user.
661///
662/// # EXAMPLES #
663/// ```
664/// use quick_input::read_u8;
665/// let user_u8_with_msg = read_u8(Some("Please input a number: "), Some("Please input a valid number."));
666///
667/// let user_u8: u8 = read_u8(None, None);
668/// ```
669pub fn read_u8(msg: Option<&str>, err_msg: Option<&str>) -> u8 {
670    let mut input = String::new();
671
672    if msg.is_some() {
673        while input.trim().parse::<u8>().is_err() {
674            input.clear();
675            print!("{}", msg.unwrap());
676            flush_and_read(&mut input);
677
678            if input.trim().parse::<u8>().is_err() {
679                show_error_message(err_msg, "Please enter a valid positive number (8 bits).");
680            }
681        }
682    } else {
683        while input.trim().parse::<u8>().is_err() {
684            input.clear();
685            flush_and_read(&mut input);
686
687            if input.trim().parse::<u8>().is_err() {
688                show_error_message(err_msg, "Please enter a valid positive number (8 bits).");
689            }
690        }
691    }
692
693    input.trim().parse().unwrap()
694}
695
696/// # ARGUMENTS #
697/// 'msg' (Option<&str>) - an optional message which will be printed at
698/// the same line as the input prompt. Must be set to Some("...") or None.
699///
700/// 'err_msg' (Option<&str>) - an optional error message which will be printed
701/// if the user inputs an invalid value. Must be set to Some("...") or None.
702///
703/// # DESCRIPTION #
704/// Prompts the user to type an integer value (i16) which will then be returned.
705/// In case the user writes an invalid value, they will be prompted to try again.
706///
707/// Provides an information message on the same line as the prompt if Some("...")
708/// is provided, and just the prompt if None is provided.
709///
710/// If err_msg is set to None, a default message will be shown.
711///
712/// # RETURNS #
713/// An integer value of type i16 provided by the user.
714///
715/// # EXAMPLES #
716/// ```
717/// use quick_input::read_i16;
718/// let user_i16_with_msg = read_i16(Some("Please input a number: "), Some("Please input a valid number."));
719///
720/// let user_i16: i16 = read_i16(None, None);
721/// ```
722pub fn read_i16(msg: Option<&str>, err_msg: Option<&str>) -> i16 {
723    let mut input = String::new();
724
725    if msg.is_some() {
726        while input.trim().parse::<i16>().is_err() {
727            input.clear();
728            print!("{}", msg.unwrap());
729            flush_and_read(&mut input);
730
731            if input.trim().parse::<i16>().is_err() {
732                show_error_message(err_msg, "Please enter a valid number (16 bits).");
733            }
734        }
735    } else {
736        while input.trim().parse::<i16>().is_err() {
737            input.clear();
738            flush_and_read(&mut input);
739
740            if input.trim().parse::<i16>().is_err() {
741                show_error_message(err_msg, "Please enter a valid number (16 bits).");
742            }
743        }
744    }
745
746    input.trim().parse().unwrap()
747}
748
749/// # ARGUMENTS #
750/// 'msg' (Option<&str>) - an optional message which will be printed at
751/// the same line as the input prompt. Must be set to Some("...") or None.
752///
753/// 'err_msg' (Option<&str>) - an optional error message which will be printed
754/// if the user inputs an invalid value. Must be set to Some("...") or None.
755///
756/// # DESCRIPTION #
757/// Prompts the user to type an integer value (u16) which will then be returned.
758/// In case the user writes an invalid value, they will be prompted to try again.
759///
760/// Provides an information message on the same line as the prompt if Some("...")
761/// is provided, and just the prompt if None is provided.
762///
763/// If err_msg is set to None, a default message will be shown.
764///
765/// # RETURNS #
766/// An integer value of type u16 provided by the user.
767///
768/// # EXAMPLES #
769/// ```
770/// use quick_input::read_u16;
771/// let user_u16_with_msg = read_u16(Some("Please input a number: "), Some("Please input a valid number."));
772///
773/// let user_u16: u16 = read_u16(None, None);
774/// ```
775pub fn read_u16(msg: Option<&str>, err_msg: Option<&str>) -> u16 {
776    let mut input = String::new();
777
778    if msg.is_some() {
779        while input.trim().parse::<u16>().is_err() {
780            input.clear();
781            print!("{}", msg.unwrap());
782            flush_and_read(&mut input);
783
784            if input.trim().parse::<u16>().is_err() {
785                show_error_message(err_msg, "Please enter a valid positive number (16 bits).");
786            }
787        }
788    } else {
789        while input.trim().parse::<u16>().is_err() {
790            input.clear();
791            flush_and_read(&mut input);
792
793            if input.trim().parse::<u16>().is_err() {
794                show_error_message(err_msg, "Please enter a valid positive number (16 bits).");
795            }
796        }
797    }
798
799    input.trim().parse().unwrap()
800}
801
802/// # ARGUMENTS #
803/// 'msg' (Option<&str>) - an optional message which will be printed at
804/// the same line as the input prompt. Must be set to Some("...") or None.
805///
806/// 'err_msg' (Option<&str>) - an optional error message which will be printed
807/// if the user inputs an invalid value. Must be set to Some("...") or None.
808///
809/// # DESCRIPTION #
810/// Prompts the user to type an integer value (i64) which will then be returned.
811/// In case the user writes an invalid value, they will be prompted to try again.
812///
813/// Provides an information message on the same line as the prompt if Some("...")
814/// is provided, and just the prompt if None is provided.
815///
816/// If err_msg is set to None, a default message will be shown.
817///
818/// # RETURNS #
819/// An integer value of type i64 provided by the user.
820///
821/// # EXAMPLES #
822/// ```
823/// use quick_input::read_i64;
824/// let user_i64_with_msg = read_i64(Some("Please input a number: "), Some("Please input a valid number"));
825///
826/// let user_i64: i64 = read_i64(None, None);
827/// ```
828pub fn read_i64(msg: Option<&str>, err_msg: Option<&str>) -> i64 {
829    let mut input = String::new();
830
831    if msg.is_some() {
832        while input.trim().parse::<i64>().is_err() {
833            input.clear();
834            print!("{}", msg.unwrap());
835            flush_and_read(&mut input);
836
837            if input.trim().parse::<i64>().is_err() {
838                show_error_message(err_msg, "Please enter a valid number (64 bits).");
839            }
840        }
841    } else {
842        while input.trim().parse::<i64>().is_err() {
843            input.clear();
844            flush_and_read(&mut input);
845
846            if input.trim().parse::<i64>().is_err() {
847                show_error_message(err_msg, "Please enter a valid number (64 bits).");
848            }
849        }
850    }
851
852    input.trim().parse().unwrap()
853}
854
855/// # ARGUMENTS #
856/// 'msg' (Option<&str>) - an optional message which will be printed at
857/// the same line as the input prompt. Must be set to Some("...") or None.
858///
859/// 'err_msg' (Option<&str>) - an optional error message which will be printed
860/// if the user inputs an invalid value. Must be set to Some("...") or None.
861///
862/// # DESCRIPTION #
863/// Prompts the user to type an integer value (u64) which will then be returned.
864/// In case the user writes an invalid value, they will be prompted to try again.
865///
866/// Provides an information message on the same line as the prompt if Some("...")
867/// is provided, and just the prompt if None is provided.
868///
869/// If err_msg is set to None, a default message will be shown.
870///
871/// # RETURNS #
872/// An integer value of type u64 provided by the user.
873///
874/// # EXAMPLES #
875/// ```
876/// use quick_input::read_u64;
877/// let user_u64_with_msg = read_u64(Some("Please input a number: "), Some("Please input a valid number."));
878///
879/// let user_u64: u64 = read_u64(None, None);
880/// ```
881pub fn read_u64(msg: Option<&str>, err_msg: Option<&str>) -> u64 {
882    let mut input = String::new();
883
884    if msg.is_some() {
885        while input.trim().parse::<u64>().is_err() {
886            input.clear();
887            print!("{}", msg.unwrap());
888            flush_and_read(&mut input);
889
890            if input.trim().parse::<u64>().is_err() {
891                show_error_message(err_msg, "Please enter a valid positive number (64 bits).");
892            }
893        }
894    } else {
895        while input.trim().parse::<u64>().is_err() {
896            input.clear();
897            flush_and_read(&mut input);
898
899            if input.trim().parse::<u64>().is_err() {
900                show_error_message(err_msg, "Please enter a valid positive number (64 bits).");
901            }
902        }
903    }
904
905    input.trim().parse().unwrap()
906}
907
908/// # ARGUMENTS #
909/// 'msg' (Option<&str>) - an optional message which will be printed at
910/// the same line as the input prompt. Must be set to Some("...") or None.
911///
912/// 'err_msg' (Option<&str>) - an optional error message which will be printed
913/// if the user inputs an invalid value. Must be set to Some("...") or None.
914///
915/// # DESCRIPTION #
916/// Prompts the user to type an integer value (i128) which will then be returned.
917/// In case the user writes an invalid value, they will be prompted to try again.
918///
919/// Provides an information message on the same line as the prompt if Some("...")
920/// is provided, and just the prompt if None is provided.
921///
922/// If err_msg is set to None, a default message will be shown.
923///
924/// # RETURNS #
925/// An integer value of type i128 provided by the user.
926///
927/// # EXAMPLES #
928/// ```
929/// use quick_input::read_i128;
930/// let user_i128_with_msg = read_i128(Some("Please input a number: "), Some("Please input a valid number."));
931///
932/// let user_i128: i128 = read_i128(None, None);
933/// ```
934pub fn read_i128(msg: Option<&str>, err_msg: Option<&str>) -> i128 {
935    let mut input = String::new();
936
937    if msg.is_some() {
938        while input.trim().parse::<i128>().is_err() {
939            input.clear();
940            print!("{}", msg.unwrap());
941            flush_and_read(&mut input);
942
943            if input.trim().parse::<i128>().is_err() {
944                show_error_message(err_msg, "Please enter a valid number (128 bits).");
945            }
946        }
947    } else {
948        while input.trim().parse::<i128>().is_err() {
949            input.clear();
950            flush_and_read(&mut input);
951
952            if input.trim().parse::<i128>().is_err() {
953                show_error_message(err_msg, "Please enter a valid number (128 bits).");
954            }
955        }
956    }
957
958    input.trim().parse().unwrap()
959}
960
961/// # ARGUMENTS #
962/// 'msg' (Option<&str>) - an optional message which will be printed at
963/// the same line as the input prompt. Must be set to Some("...") or None.
964///
965/// 'err_msg' (Option<&str>) - an optional error message which will be printed
966/// if the user inputs an invalid value. Must be set to Some("...") or None.
967///
968/// # DESCRIPTION #
969/// Prompts the user to type an integer value (u128) which will then be returned.
970/// In case the user writes an invalid value, they will be prompted to try again.
971///
972/// Provides an information message on the same line as the prompt if Some("...")
973/// is provided, and just the prompt if None is provided.
974///
975/// If err_msg is set to None, a default message will be shown.
976///
977/// # RETURNS #
978/// An integer value of type u128 provided by the user.
979///
980/// # EXAMPLES #
981/// ```
982/// use quick_input::read_u128;
983/// let user_u128_with_msg = read_u128(Some("Please input a number: "), Some("Please input a valid number."));
984///
985/// let user_u128: u128 = read_u128(None, None);
986/// ```
987pub fn read_u128(msg: Option<&str>, err_msg: Option<&str>) -> u128 {
988    let mut input = String::new();
989
990    if msg.is_some() {
991        while input.trim().parse::<u128>().is_err() {
992            input.clear();
993            print!("{}", msg.unwrap());
994            flush_and_read(&mut input);
995
996            if input.trim().parse::<u128>().is_err() {
997                show_error_message(err_msg, "Please enter a valid positive number (128 bits).");
998            }
999        }
1000    } else {
1001        while input.trim().parse::<u128>().is_err() {
1002            input.clear();
1003            flush_and_read(&mut input);
1004
1005            if input.trim().parse::<u128>().is_err() {
1006                show_error_message(err_msg, "Please enter a valid positive number (128 bits).");
1007            }
1008        }
1009    }
1010
1011    input.trim().parse().unwrap()
1012}
1013
1014/// # ARGUMENTS #
1015/// 'msg' (Option<&str>) - an optional message which will be printed at
1016/// the same line as the input prompt. Must be set to Some("...") or None.
1017///
1018/// 'err_msg' (Option<&str>) - an optional error message which will be printed
1019/// if the user inputs an invalid value. Must be set to Some("...") or None.
1020///
1021/// # DESCRIPTION #
1022/// Prompts the user to type an integer value (isize) which will then be returned.
1023/// In case the user writes an invalid value, they will be prompted to try again.
1024///
1025/// Provides an information message on the same line as the prompt if Some("...")
1026/// is provided, and just the prompt if None is provided.
1027///
1028/// If err_msg is set to None, a default message will be shown.
1029///
1030/// # RETURNS #
1031/// An integer value of type isize provided by the user.
1032///
1033/// # EXAMPLES #
1034/// ```
1035/// use quick_input::read_isize;
1036/// let user_isize_with_msg = read_isize(Some("Please input a number: "), Some("Please input a valid number"));
1037///
1038/// let user_isize: isize = read_isize(None, None);
1039/// ```
1040pub fn read_isize(msg: Option<&str>, err_msg: Option<&str>) -> isize {
1041    let mut input = String::new();
1042
1043    if msg.is_some() {
1044        while input.trim().parse::<isize>().is_err() {
1045            input.clear();
1046            print!("{}", msg.unwrap());
1047            flush_and_read(&mut input);
1048
1049            if input.trim().parse::<isize>().is_err() {
1050                show_error_message(err_msg, "Please enter a valid number (32/64 bits).");
1051            }
1052        }
1053    } else {
1054        while input.trim().parse::<isize>().is_err() {
1055            input.clear();
1056            flush_and_read(&mut input);
1057
1058            if input.trim().parse::<isize>().is_err() {
1059                show_error_message(err_msg, "Please enter a valid number (32/64 bits).");
1060            }
1061        }
1062    }
1063
1064    input.trim().parse().unwrap()
1065}
1066
1067/// # ARGUMENTS #
1068/// 'msg' (Option<&str>) - an optional message which will be printed at
1069/// the same line as the input prompt. Must be set to Some("...") or None.
1070///
1071/// 'err_msg' (Option<&str>) - an optional error message which will be printed
1072/// if the user inputs an invalid value. Must be set to Some("...") or None.
1073///
1074/// # DESCRIPTION #
1075/// Prompts the user to type an integer value (usize) which will then be returned.
1076/// In case the user writes an invalid value, they will be prompted to try again.
1077///
1078/// Provides an information message on the same line as the prompt if Some("...")
1079/// is provided, and just the prompt if None is provided.
1080///
1081/// If err_msg is set to None, a default message will be shown.
1082///
1083/// # RETURNS #
1084/// An integer value of type usize provided by the user.
1085///
1086/// # EXAMPLES #
1087/// ```
1088/// use quick_input::read_usize;
1089/// let user_usize_with_msg = read_usize(Some("Please input a number: "), Some("Please input a valid number."));
1090///
1091/// let user_usize: usize = read_usize(None, None);
1092/// ```
1093pub fn read_usize(msg: Option<&str>, err_msg: Option<&str>) -> usize {
1094    let mut input = String::new();
1095
1096    if msg.is_some() {
1097        while input.trim().parse::<usize>().is_err() {
1098            input.clear();
1099            print!("{}", msg.unwrap());
1100            flush_and_read(&mut input);
1101
1102            if input.trim().parse::<usize>().is_err() {
1103                show_error_message(err_msg, "Please enter a valid positive number (32/64 bits).");
1104            }
1105        }
1106    } else {
1107        while input.trim().parse::<usize>().is_err() {
1108            input.clear();
1109            flush_and_read(&mut input);
1110
1111            if input.trim().parse::<usize>().is_err() {
1112                show_error_message(err_msg, "Please enter a valid positive number (32/64 bits).");
1113            }
1114        }
1115    }
1116
1117    input.trim().parse().unwrap()
1118}
1119
1120
1121// ----- PRIVATE METHODS ----- //
1122
1123/// # Arguments #
1124/// 'input' (&mut String) - Mutable reference to the variable containing
1125/// an empty String, which is returned at the end of all read_* methods.
1126///
1127/// # Description #
1128/// Private method used to force the print!() macro to show the &str message provided
1129/// on the same line as the input prompt.
1130///
1131/// This function also obtains the value typed by the user and assings it
1132/// to the "input" variable through the mutable reference provided.
1133fn flush_and_read(input: &mut String) {
1134    io::stdout().flush().unwrap();
1135    io::stdin()
1136        .read_line(input)
1137        .expect("Unable to read from stdin.");
1138}
1139
1140/// # Arguments #
1141/// 'err_msg' (Option<&str>) - Custom error message which will be displayed in case
1142/// the user provides an invalid value. Must be set to Some("...") or None.
1143///
1144/// 'def_err_msg' (&str) - Default error message that will be shown if the user provides
1145/// an invalid value and the provided error message (err_msg) is set to None.
1146///
1147/// # Description #
1148/// Private function used to display a custom error message if the users provides an invalid value.
1149/// This function will display a default error message if the provided custom error message is set to None.
1150fn show_error_message(err_msg: Option<&str>, def_err_msg: &str) {
1151    if err_msg.is_some() {
1152        println!("{}", err_msg.unwrap());
1153        println!("---");
1154    } else {
1155        println!("{def_err_msg}");
1156        println!("---");
1157    }
1158}
1159
1160
1161#[cfg(test)]
1162mod tests {}