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
**/*.rs.bk
questions.toml
questions*.toml

View File

@ -2,7 +2,7 @@
name = "flashcards"
version = "0.1.0"
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

View File

@ -19,3 +19,7 @@ script = []
# Javascript code file
# serve: [dev-server] only
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::{
desktop::{Config, LogicalSize, WindowBuilder},
@ -9,16 +9,48 @@ use rand::seq::SliceRandom;
mod models;
const DEFAULT_FILE: &str = "questions.toml";
const MAIN_CSS: Asset = asset!("/assets/main.css");
pub static QUESTIONS: LazyLock<Questions> = LazyLock::new(|| {
let questions_str = std::fs::read_to_string("questions.toml").unwrap();
let questions: Questions = toml::from_str(&questions_str).unwrap();
questions
});
pub static QUESTIONS: OnceLock<Questions> = OnceLock::new();
fn get_questions() -> Vec<Question> {
let mut questions = QUESTIONS.questions.clone();
fn get_questions() -> Questions {
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();
// Randomize the answers
@ -55,7 +87,7 @@ fn App() -> Element {
#[component]
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 total_correct = use_memo(move || {
@ -82,7 +114,7 @@ pub fn QuestionForm() -> Element {
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 left_questions = use_memo(move || total_questions - current_question());
let mut correct_questions = use_signal(|| 0);
@ -116,7 +148,7 @@ pub fn QuestionForm() -> Element {
*wrong_questions_lock += 1;
}
} else {
questions.set(get_questions());
questions.set(get_rand_questions());
current.set(questions.remove(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;
#[derive(Debug, Deserialize)]
#[derive(Debug, Clone, Deserialize)]
pub struct Questions {
pub questions: Vec<Question>,
}
impl AddAssign for Questions {
fn add_assign(&mut self, rhs: Self) {
self.extend(rhs.questions)
}
}
impl Deref for Questions {
type Target = Vec<Question>;