use clap::{Arg, ArgMatches, Command}; use rand::seq::SliceRandom; use rand::thread_rng; use serde::Deserialize; use std::fs::File; use std::io::{self, Read}; #[derive(Deserialize, Debug, Clone)] struct Question { question: String, options: Vec, answer: String, } fn get_matches() -> ArgMatches { Command::new("RustyCards") .version("1.0") .author("mzums mzuums@gmail.com") .about("A flashcard/quiz terminal app") .arg( Arg::new("file") .short('f') .long("file") .default_value("data/questions.json") .help("The file containing questions in JSON format"), ) .arg( Arg::new("shuffle") .short('s') .long("shuffle") .help("Randomize the order of questions") .action(clap::ArgAction::SetTrue), ) .get_matches() } fn get_questions(matches: &ArgMatches) -> Result, Box> { let file_path = matches.get_one::("file").unwrap(); let mut file = File::open(file_path)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; let questions: Vec = serde_json::from_str(&contents)?; Ok(questions) } fn display_question(question: &Question, idx: usize) { println!("Question {}: {}", idx + 1, question.question); for (j, option) in question.options.iter().enumerate() { println!(" {}) {}", j + 1, option); } } fn handle_input(answer: &str, score: i32) -> i32 { let mut guess = String::new(); io::stdin() .read_line(&mut guess) .expect("Please enter a valid answer"); let guess = guess.trim(); if guess == answer { println!("Correct!\n"); score + 1 } else { println!("The correct answer was {}\n", answer); score } } fn main() { let mut score = 0; let matches = get_matches(); let questions = match get_questions(&matches) { Ok(questions) => questions, Err(err) => { eprintln!("Error loading questions: {}", err); return; } }; let mut rng = thread_rng(); let mut shuffled_questions = questions.clone(); if matches.get_flag("shuffle") { shuffled_questions.shuffle(&mut rng); } for (i, question) in shuffled_questions.iter_mut().enumerate() { display_question(&question, i); score = handle_input(&question.answer, score); } println!("Your score was {score}/{}", questions.len()); }