fable/src/utilities/questions.rs
2025-04-17 15:53:45 -06:00

97 lines
3.0 KiB
Rust

use inquire::{MultiSelect, Select, Text};
use crossterm::terminal;
use super::printers::{clear_console, inform_delay, print_boxed, StatementType};
const DELAY_SECONDS: u64 = 1;
pub fn ask_mcq_delayed(question: &str, options: &[&str]) -> Option<String> {
print_boxed(question, StatementType::Question);
inform_delay(DELAY_SECONDS);
std::thread::sleep(std::time::Duration::from_secs(DELAY_SECONDS));
ask_mcq(question, options)
}
/// Print a quiz question in an attractive format and get the user's choice
pub fn ask_mcq(question: &str, options: &[&str]) -> Option<String> {
clear_console();
// Calculate vertical centering
let rows = terminal::size().map(|(_, height)| height as usize).unwrap_or(0) - options.len() - 2;
print_boxed(&format!("{}", question), StatementType::Question);
for _ in 0..(rows/2) {
println!();
}
let ans = Select::new("Your response:", options.to_vec())
.prompt();
match ans {
Ok(choice) => Some(String::from(choice)),
Err(_) => None,
}
}
/// Print a quiz question in an attractive format and get the user's choices
pub fn ask_multi_select(question: &str, options: &[&str]) -> Option<Vec<String>> {
clear_console();
// Calculate vertical centering
let rows = terminal::size().map(|(_, height)| height as usize).unwrap_or(0) - options.len() - 2;
print_boxed(&format!("{}", question), StatementType::Question);
for _ in 0..(rows/2) {
println!();
}
let ans = MultiSelect::new("Select all applicable answers with SPACEBAR, then press RETURN to submit:", options.to_vec())
.prompt();
match ans {
Ok(choices) => Some(choices.into_iter().map(String::from).collect()),
Err(_) => None,
}
}
/// Print a question in an attractive format and get the user's text input
pub fn ask_plaintext(question: &str) -> Option<String> {
clear_console();
// Calculate vertical centering
let rows = terminal::size().map(|(_, height)| height as usize).unwrap_or(0) - 3;
print_boxed(&format!("{}", question), StatementType::Question);
for _ in 0..(rows/2) {
println!();
}
let ans = Text::new("Please provide your input:")
.prompt();
match ans {
Ok(choice) => Some(choice),
Err(_) => None,
}
}
pub fn ask_name() -> String {
let name = ask_plaintext("What is your name?").unwrap_or_else(|| {
let default_name = super::generators::generate_name();
print_boxed(&format!("Failed to get name. I'll give you a random one: {}.", default_name), StatementType::IncorrectFeedback);
default_name
});
if name .is_empty() {
let default_name = super::generators::generate_name();
print_boxed(&format!("You didn't provide a name. I'll give you a random one: {}.", default_name), StatementType::IncorrectFeedback);
return default_name;
}
print_boxed(&format!("Welcome, {}! Thanks for joining me.", name), StatementType::Default);
name
}