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