Cleanup and format

This commit is contained in:
micialware committed 2026-08-29 22:02:01 +03:00
1 parent af6cf10765
commit d5a2a575fe
9 files changed
+63 -72

No files matched your search

+11 -15
View File
@@ -1,5 +1,5 @@
use crate::app::AppState; use crate::app::AppState;
use crate::core::srs::OrderModule::{WorstWordsSRS, FSRS, RandomSRS, SemiRandomSRS}; use crate::core::srs::OrderModule::{Fsrs, RandomSRS, SemiRandomSRS, WorstWordsSRS};
use crate::core::srs::{ use crate::core::srs::{
FsrsModule, OrderMode, OrderModule, RandomSRSModule, SRSModule, SemiRandomSRSModule, FsrsModule, OrderMode, OrderModule, RandomSRSModule, SRSModule, SemiRandomSRSModule,
WordOpenMode, WorstWordsSRSModule, WordOpenMode, WorstWordsSRSModule,
@@ -48,7 +48,7 @@ impl DeckData {
words, words,
current_word_index: None, current_word_index: None,
state: state_for, state: state_for,
order_module: FSRS(FsrsModule::new()), order_module: Fsrs(FsrsModule::new()),
open_mode: settings.open_mode, open_mode: settings.open_mode,
settings: settings.clone(), settings: settings.clone(),
}) })
@@ -75,7 +75,7 @@ impl DeckData {
} }
module.next(self.set.as_slice()) module.next(self.set.as_slice())
} }
FSRS(ref mut module) => { Fsrs(ref mut module) => {
if !module.initialized { if !module.initialized {
module.init(self.set.as_slice()) module.init(self.set.as_slice())
} }
@@ -103,22 +103,18 @@ impl DeckData {
WorstWordsSRS(ref mut module) => { WorstWordsSRS(ref mut module) => {
module.open(status, index, word); module.open(status, index, word);
} }
FSRS(ref mut module) => { Fsrs(ref mut module) => {
module.open(status, index, word); module.open(status, index, word);
} }
} }
if let FSRS(ref fsrs) = self.order_module { if let Fsrs(ref fsrs) = self.order_module
if fsrs.finished() { && fsrs.finished()
self.order_module = match self.open_mode { {
OrderMode::Default => { self.order_module = match self.open_mode {
SemiRandomSRS(SemiRandomSRSModule::new()) OrderMode::Default => SemiRandomSRS(SemiRandomSRSModule::new()),
} OrderMode::TrainWorstFirst => WorstWordsSRS(WorstWordsSRSModule::new()),
OrderMode::TrainWorstFirst => { OrderMode::FullRandom => RandomSRS(RandomSRSModule::new()),
WorstWordsSRS(WorstWordsSRSModule::new())
}
OrderMode::FullRandom => RandomSRS(RandomSRSModule::new()),
}
} }
} }
update_stat_score(word, &self.state.lock().connection)?; update_stat_score(word, &self.state.lock().connection)?;
+42 -21
View File
@@ -1,10 +1,10 @@
use crate::data::entities::CardStatistics; use crate::data::entities::CardStatistics;
use chrono::Local; use chrono::{Local, TimeDelta};
use fsrs::FSRS; use fsrs::FSRS;
use rand::distr::weighted::WeightedIndex; use rand::distr::weighted::WeightedIndex;
use rand::prelude::ThreadRng; use rand::prelude::ThreadRng;
use rand::prelude::{Distribution, SliceRandom}; use rand::prelude::{Distribution, SliceRandom};
use rand::rng; use rand::{RngExt, rng};
const MAX_HISTORY_LEN: usize = 20; const MAX_HISTORY_LEN: usize = 20;
const MAX_HISTORY_LEN_PART: f32 = 0.33; const MAX_HISTORY_LEN_PART: f32 = 0.33;
@@ -28,7 +28,7 @@ pub enum OrderModule {
SemiRandomSRS(SemiRandomSRSModule), SemiRandomSRS(SemiRandomSRSModule),
RandomSRS(RandomSRSModule), RandomSRS(RandomSRSModule),
WorstWordsSRS(WorstWordsSRSModule), WorstWordsSRS(WorstWordsSRSModule),
FSRS(FsrsModule), Fsrs(FsrsModule),
} }
pub trait SRSModule { pub trait SRSModule {
fn next(&mut self, set: &[CardStatistics]) -> usize; fn next(&mut self, set: &[CardStatistics]) -> usize;
@@ -183,12 +183,12 @@ pub struct FsrsModule {
queue: Vec<usize>, queue: Vec<usize>,
rng: ThreadRng, rng: ThreadRng,
fsrs: FSRS, fsrs: FSRS,
pub(crate) initialized: bool pub(crate) initialized: bool,
} }
impl SRSModule for FsrsModule { impl SRSModule for FsrsModule {
fn next(&mut self, set: &[CardStatistics]) -> usize { fn next(&mut self, _: &[CardStatistics]) -> usize {
if self.solved.len() == self.current_group.len() { if self.current_group.is_empty() {
self.fill_partial_pool(); self.fill_partial_pool();
} }
@@ -197,7 +197,7 @@ impl SRSModule for FsrsModule {
self.queue.shuffle(&mut self.rng); self.queue.shuffle(&mut self.rng);
} }
self.queue.pop().expect("empty queue") self.queue.pop().unwrap_or(0)
} }
fn open(&mut self, status: WordOpenMode, index: usize, updated_word: &mut CardStatistics) { fn open(&mut self, status: WordOpenMode, index: usize, updated_word: &mut CardStatistics) {
@@ -205,8 +205,31 @@ impl SRSModule for FsrsModule {
let delta = today - updated_word.fsrs_opened; let delta = today - updated_word.fsrs_opened;
let delta_days = delta.num_days(); let delta_days = delta.num_days();
if updated_word.fsrs_open_day != today{ let memory = self
.fsrs
.next_states(updated_word.fsrs_memory, 0.9, delta_days as u32)
.expect("Wrong next stage calculation");
let next = match status {
WordOpenMode::Easy => memory.easy,
WordOpenMode::Ok => memory.good,
WordOpenMode::Hard => memory.hard,
WordOpenMode::None => memory.again,
};
let mut next_day = today + TimeDelta::days(next.interval.round() as i64);
if (next_day - today).num_days() >= 5 {
let offset = ((rng().random::<f32>() - 0.5) * 3.0).round() as i32;
next_day += TimeDelta::days(offset as i64);
}
updated_word.fsrs_memory = Some(next.memory);
updated_word.fsrs_open_day = next_day;
updated_word.fsrs_opened = updated_word.last_open.date_naive();
if updated_word.fsrs_open_day != today {
self.solved.push(index); self.solved.push(index);
let index = self.current_group.iter().position(|x| *x == index).unwrap();
self.current_group.remove(index);
} }
} }
@@ -226,8 +249,8 @@ impl SRSModule for FsrsModule {
} }
impl FsrsModule { impl FsrsModule {
pub fn new() -> Self{ pub fn new() -> Self {
Self{ Self {
today_set: vec![], today_set: vec![],
current_group: vec![], current_group: vec![],
queue: vec![], queue: vec![],
@@ -238,21 +261,19 @@ impl FsrsModule {
} }
} }
fn fill_partial_pool(&mut self) { fn fill_partial_pool(&mut self) {
self.current_group.clear(); self.current_group.extend(
self.current_group self.today_set
.extend(self.today_set.iter().take(PARTIAL_POOL_SIZE)); .iter()
self.current_group.iter().for_each(|_| { .filter(|x| !self.solved.contains(*x))
self.today_set.remove(0); .take(PARTIAL_POOL_SIZE),
}); );
self.queue.clear(); self.queue.clear();
self.queue self.queue.extend(self.current_group.clone());
.extend(self.current_group.clone());
self.solved.clear();
} }
fn fill_queue(&mut self) { fn fill_queue(&mut self) {
self.queue.clear(); self.queue.extend(self.current_group.clone());
self.queue.extend(self.current_group.iter().filter(|c| !self.today_set.contains(*c)));
} }
pub fn finished(&self) -> bool { pub fn finished(&self) -> bool {
+2 -26
View File
@@ -1,10 +1,9 @@
use crate::app::AppState; use crate::app::AppState;
use crate::core::srs::{FADE_PER_DAY, MAX_SCORE, OrderMode, WordOpenMode}; use crate::core::srs::{FADE_PER_DAY, MAX_SCORE, OrderMode, WordOpenMode};
use crate::data::{INVALID_ID, Id}; use crate::data::{INVALID_ID, Id};
use chrono::{DateTime, Local, NaiveDate, Utc}; use chrono::{DateTime, NaiveDate, Utc};
use fsrs::{FSRS, MemoryState}; use fsrs::MemoryState;
use log::info; use log::info;
use rand::{RngExt, random, rng};
use rayon::prelude::*; use rayon::prelude::*;
use rhai::{Engine, Scope}; use rhai::{Engine, Scope};
use std::collections::HashMap; use std::collections::HashMap;
@@ -162,29 +161,6 @@ impl CardStatistics {
self.last_open = Utc::now(); self.last_open = Utc::now();
} }
pub fn update_fsrs(&mut self, status: WordOpenMode, by_fsrs: bool, fsrs: FSRS)
{
let today = Local::now().date_naive().to_epoch_days();
let written = self.fsrs_opened.to_epoch_days();
let memory = fsrs
.next_states(self.fsrs_memory, 0.9, (today - written) as u32)
.expect("Wrong next stage calculation");
let next = match status {
WordOpenMode::Easy => memory.easy,
WordOpenMode::Ok => memory.good,
WordOpenMode::Hard => memory.hard,
WordOpenMode::None => memory.again,
};
let mut next_day = today + next.interval.round() as i32;
if next_day - today >= 5 {
let offset = ((rng().random::<f32>() - 0.5) * 3.0).round() as i32;
next_day += offset;
}
self.fsrs_memory = Some(next.memory);
self.fsrs_open_day = NaiveDate::from_epoch_days(next_day).unwrap();
self.fsrs_opened = self.last_open.date_naive();
}
pub fn calculated_score(&self) -> f32 { pub fn calculated_score(&self) -> f32 {
let time = Utc::now() - self.last_open; let time = Utc::now() - self.last_open;
let days = time.num_days(); let days = time.num_days();
-1
View File
@@ -4,7 +4,6 @@ use crate::notification::{MaybeError, NotificationData};
use chrono::NaiveDate; use chrono::NaiveDate;
use fsrs::MemoryState; use fsrs::MemoryState;
use log::info; use log::info;
use reqwest::get;
use rusqlite::{Connection, params}; use rusqlite::{Connection, params};
use std::time::Instant; use std::time::Instant;
-4
View File
@@ -1,11 +1,7 @@
use crate::core::srs::OrderMode; use crate::core::srs::OrderMode;
use crate::data::Id;
use crate::data::entities::DeckSettings; use crate::data::entities::DeckSettings;
use crate::notification::NotificationData::{DbLoadError, DbSaveError}; use crate::notification::NotificationData::{DbLoadError, DbSaveError};
use crate::notification::{MaybeError, NotificationData}; use crate::notification::{MaybeError, NotificationData};
use chrono::{Datelike, Local, NaiveDate};
use fsrs::Card;
use iced::futures::StreamExt;
use rusqlite::Connection; use rusqlite::Connection;
pub fn load_sets(connection: &Connection) -> Result<Vec<DeckSettings>, NotificationData> { pub fn load_sets(connection: &Connection) -> Result<Vec<DeckSettings>, NotificationData> {
+5 -2
View File
@@ -5,13 +5,16 @@ use crate::fs::*;
use crate::notification::NotificationData::PermissionDenied; use crate::notification::NotificationData::PermissionDenied;
use crate::notification::{MaybeError, NotificationData}; use crate::notification::{MaybeError, NotificationData};
use chrono::{DateTime, NaiveDate}; use chrono::{DateTime, NaiveDate};
use rusqlite::Connection;
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::Write; use std::io::Write;
use std::io::{BufRead, BufReader}; use std::io::{BufRead, BufReader};
use std::path::PathBuf; use std::path::PathBuf;
use rusqlite::Connection;
pub fn get_open_count_of_set(id: Id, connection: &Connection) -> Result<Vec<(NaiveDate, u32)>, NotificationData>{ pub fn get_open_count_of_set(
id: Id,
connection: &Connection,
) -> Result<Vec<(NaiveDate, u32)>, NotificationData> {
todo!() todo!()
} }
+1 -1
View File
@@ -1,5 +1,5 @@
pub(crate) mod decks;
pub(crate) mod card_states; pub(crate) mod card_states;
pub(crate) mod decks;
pub(crate) mod history; pub(crate) mod history;
pub(crate) mod import; pub(crate) mod import;
pub(crate) mod settings; pub(crate) mod settings;
+1 -1
View File
@@ -1,7 +1,7 @@
use crate::app::AppState; use crate::app::AppState;
use crate::data::entities::DeckSettings; use crate::data::entities::DeckSettings;
use crate::data_provider::decks::{delete_set, update_deck};
use crate::data_provider::card_states::{delete_stats, load_stats_of_deck}; use crate::data_provider::card_states::{delete_stats, load_stats_of_deck};
use crate::data_provider::decks::{delete_set, update_deck};
use crate::navigation::Page::PreviousPage; use crate::navigation::Page::PreviousPage;
use crate::navigation::{NavigatedPage, Page, RootMessage}; use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::notification::MaybeError; use crate::notification::MaybeError;
+1 -1
View File
@@ -2,8 +2,8 @@ use crate::app::AppState;
use crate::core::srs::{AppendMode, OrderMode}; use crate::core::srs::{AppendMode, OrderMode};
use crate::data::Id; use crate::data::Id;
use crate::data::entities::{CardStatistics, DeckSettings}; use crate::data::entities::{CardStatistics, DeckSettings};
use crate::data_provider::decks::update_deck;
use crate::data_provider::card_states::{add_stat_list, load_stats_of_deck}; use crate::data_provider::card_states::{add_stat_list, load_stats_of_deck};
use crate::data_provider::decks::update_deck;
use crate::navigation::Page::{History, PreviousPage, Repetition, RepetitionSettings}; use crate::navigation::Page::{History, PreviousPage, Repetition, RepetitionSettings};
use crate::navigation::{NavigatedPage, Page, RootMessage}; use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::notification::{MaybeError, NotificationRequest}; use crate::notification::{MaybeError, NotificationRequest};