Added possibility to load multiple .toml files at once

master
Wynd 2025-06-16 00:05:35 +03:00
parent 4d984cd2e3
commit 41d1ac5389
6 changed files with 63 additions and 19 deletions

2
.gitignore vendored
View File

@ -6,4 +6,4 @@
# These are backup files generated by rustfmt # These are backup files generated by rustfmt
**/*.rs.bk **/*.rs.bk
questions.toml questions*.toml

View File

@ -2,7 +2,7 @@
name = "flashcards" name = "flashcards"
version = "0.1.0" version = "0.1.0"
authors = ["Wynd <wyndmaster@gmail.com>"] authors = ["Wynd <wyndmaster@gmail.com>"]
edition = "2021" edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -14,8 +14,12 @@ style = []
# Additional JavaScript files # Additional JavaScript files
script = [] script = []
[web.resource.dev] [web.resource.dev]
# Javascript code file # Javascript code file
# serve: [dev-server] only # serve: [dev-server] only
script = [] script = []
[bundle]
identifier = "xyz.pixelatedw.flashcards"
publisher = "PixelatedW"

View File

@ -0,0 +1,2 @@
[toolchain]
channel = "1.85"

View File

@ -1,4 +1,4 @@
use std::{sync::LazyLock, time::Duration}; use std::{env, sync::OnceLock, time::Duration};
use dioxus::{ use dioxus::{
desktop::{Config, LogicalSize, WindowBuilder}, desktop::{Config, LogicalSize, WindowBuilder},
@ -9,16 +9,48 @@ use rand::seq::SliceRandom;
mod models; mod models;
const DEFAULT_FILE: &str = "questions.toml";
const MAIN_CSS: Asset = asset!("/assets/main.css"); const MAIN_CSS: Asset = asset!("/assets/main.css");
pub static QUESTIONS: LazyLock<Questions> = LazyLock::new(|| { pub static QUESTIONS: OnceLock<Questions> = OnceLock::new();
let questions_str = std::fs::read_to_string("questions.toml").unwrap();
let questions: Questions = toml::from_str(&questions_str).unwrap();
questions
});
fn get_questions() -> Vec<Question> { fn get_questions() -> Questions {
let mut questions = QUESTIONS.questions.clone(); QUESTIONS
.get_or_init(|| {
let args: Vec<String> = env::args().collect();
let file_name = args.get(1).map(|x| x.as_str()).unwrap_or(DEFAULT_FILE);
let questions_str = std::fs::read_to_string(file_name)
.unwrap_or_else(|_| panic!("Could not read from file {file_name}"));
let mut questions: Questions =
toml::from_str(&questions_str).expect("Could not decode the given file as TOML");
if args.len() > 2 {
for i in 2..args.len() {
let file_name = args.get(i).map(|x| x.as_str());
let Some(file_name) = file_name else {
continue;
};
let Ok(questions_str) = std::fs::read_to_string(file_name) else {
continue;
};
let Ok(other_questions) = toml::from_str(&questions_str) else {
continue;
};
questions += other_questions;
}
}
questions
})
.clone()
}
fn get_rand_questions() -> Vec<Question> {
let mut questions = get_questions().questions;
let mut rng = rand::rng(); let mut rng = rand::rng();
// Randomize the answers // Randomize the answers
@ -55,7 +87,7 @@ fn App() -> Element {
#[component] #[component]
pub fn QuestionForm() -> Element { pub fn QuestionForm() -> Element {
let mut questions = use_signal(get_questions); let mut questions = use_signal(get_rand_questions);
let mut current = use_signal(move || questions.remove(0)); let mut current = use_signal(move || questions.remove(0));
let total_correct = use_memo(move || { let total_correct = use_memo(move || {
@ -82,7 +114,7 @@ pub fn QuestionForm() -> Element {
correctly_checked.saturating_sub(incorrectly_checked) correctly_checked.saturating_sub(incorrectly_checked)
}); });
let total_questions = QUESTIONS.len(); let total_questions = get_questions().len();
let current_question = use_memo(move || questions().len()); let current_question = use_memo(move || questions().len());
let left_questions = use_memo(move || total_questions - current_question()); let left_questions = use_memo(move || total_questions - current_question());
let mut correct_questions = use_signal(|| 0); let mut correct_questions = use_signal(|| 0);
@ -116,7 +148,7 @@ pub fn QuestionForm() -> Element {
*wrong_questions_lock += 1; *wrong_questions_lock += 1;
} }
} else { } else {
questions.set(get_questions()); questions.set(get_rand_questions());
current.set(questions.remove(0)); current.set(questions.remove(0));
*correct_questions_lock = 0; *correct_questions_lock = 0;

View File

@ -1,12 +1,18 @@
use std::ops::{Deref, DerefMut}; use std::ops::{AddAssign, Deref, DerefMut};
use serde::Deserialize; use serde::Deserialize;
#[derive(Debug, Deserialize)] #[derive(Debug, Clone, Deserialize)]
pub struct Questions { pub struct Questions {
pub questions: Vec<Question>, pub questions: Vec<Question>,
} }
impl AddAssign for Questions {
fn add_assign(&mut self, rhs: Self) {
self.extend(rhs.questions)
}
}
impl Deref for Questions { impl Deref for Questions {
type Target = Vec<Question>; type Target = Vec<Question>;