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 {}