add prompt_char helper function

This commit is contained in:
Carson McManus 2021-08-14 11:10:21 -04:00
parent f38f9b6e52
commit ca86b44640
2 changed files with 89 additions and 11 deletions

View file

@ -125,12 +125,11 @@ fn main() {
let mut manifest: accountmanager::Manifest; let mut manifest: accountmanager::Manifest;
if !path.exists() { if !path.exists() {
error!("Did not find manifest in {}", mafiles_dir); error!("Did not find manifest in {}", mafiles_dir);
print!( match tui::prompt_char(
"Would you like to create a manifest in {} ? [Yn] ", format!("Would you like to create a manifest in {} ?", mafiles_dir).as_str(),
mafiles_dir "Yn",
); ) {
match tui::prompt().to_lowercase().as_str() { 'n' => {
"n" => {
info!("Aborting!"); info!("Aborting!");
return; return;
} }
@ -352,11 +351,10 @@ fn main() {
.join(", ") .join(", ")
); );
print!("Do you want to continue? [yN] "); match tui::prompt_char("Do you want to continue?", "yN") {
match tui::prompt().as_str() { 'y' => {}
"y" => {}
_ => { _ => {
println!("Aborting!"); info!("Aborting!");
return; return;
} }
} }

View file

@ -1,7 +1,7 @@
use log::*; use log::*;
use regex::Regex; use regex::Regex;
use std::collections::HashSet; use std::collections::HashSet;
use std::io::Write; use std::io::{Read, Write};
use steamguard::Confirmation; use steamguard::Confirmation;
use termion::{ use termion::{
event::{Event, Key}, event::{Event, Key},
@ -61,6 +61,46 @@ pub fn prompt_captcha_text(captcha_gid: &String) -> String {
return captcha_text; return captcha_text;
} }
/// Prompt the user for a single character response. Useful for asking yes or no questions.
///
/// `chars` should be all lowercase characters, with at most 1 uppercase character. The uppercase character is the default answer if no answer is provided.
pub fn prompt_char(text: &str, chars: &str) -> char {
return prompt_char_impl(&mut std::io::stdin(), text, chars);
}
fn prompt_char_impl(input: &mut impl Read, text: &str, chars: &str) -> char {
let uppers = chars.replace(char::is_lowercase, "");
if uppers.len() > 1 {
panic!("Invalid chars for prompt_char. Maximum 1 uppercase letter is allowed.");
}
let default_answer: Option<char> = if uppers.len() == 1 {
Some(uppers.chars().collect::<Vec<char>>()[0].to_ascii_lowercase())
} else {
None
};
loop {
print!("{} [{}] ", text, chars);
let answer = input
.read_line()
.expect("Unable to read input")
.unwrap()
.to_ascii_lowercase();
if answer.len() == 0 {
if let Some(a) = default_answer {
return a;
}
} else if answer.len() > 1 {
continue;
}
let answer_char = answer.chars().collect::<Vec<char>>()[0];
if chars.contains(answer_char) {
return answer_char;
}
}
}
/// Returns a tuple of (accepted, denied). Ignored confirmations are not included. /// Returns a tuple of (accepted, denied). Ignored confirmations are not included.
pub fn prompt_confirmation_menu( pub fn prompt_confirmation_menu(
confirmations: Vec<Confirmation>, confirmations: Vec<Confirmation>,
@ -184,3 +224,43 @@ pub fn pause() {
stdout.flush().unwrap(); stdout.flush().unwrap();
std::io::stdin().events().next(); std::io::stdin().events().next();
} }
#[cfg(test)]
mod prompt_char_tests {
use super::*;
#[test]
fn test_gives_answer() {
let inputs = ['y', '\n'].iter().collect::<String>();
let answer = prompt_char_impl(&mut inputs.as_bytes(), "ligma balls", "yn");
assert_eq!(answer, 'y');
}
#[test]
fn test_gives_default() {
let inputs = ['\n'].iter().collect::<String>();
let answer = prompt_char_impl(&mut inputs.as_bytes(), "ligma balls", "Yn");
assert_eq!(answer, 'y');
}
#[test]
fn test_should_not_give_default() {
let inputs = ['n', '\n'].iter().collect::<String>();
let answer = prompt_char_impl(&mut inputs.as_bytes(), "ligma balls", "Yn");
assert_eq!(answer, 'n');
}
#[test]
fn test_should_not_give_invalid() {
let inputs = ['g', '\n', 'n', '\n'].iter().collect::<String>();
let answer = prompt_char_impl(&mut inputs.as_bytes(), "ligma balls", "yn");
assert_eq!(answer, 'n');
}
#[test]
fn test_should_not_give_multichar() {
let inputs = ['y', 'y', '\n', 'n', '\n'].iter().collect::<String>();
let answer = prompt_char_impl(&mut inputs.as_bytes(), "ligma balls", "yn");
assert_eq!(answer, 'n');
}
}