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