rs_fsrs/
scheduler.rs

1use chrono::{DateTime, Utc};
2
3use crate::models::State::*;
4use crate::Seed;
5use crate::{
6    models::{RecordLog, SchedulingInfo},
7    Card, Parameters, Rating, ReviewLog,
8};
9
10#[derive(Debug, Clone)]
11pub struct Scheduler {
12    pub parameters: Parameters,
13    pub last: Card,
14    pub current: Card,
15    pub now: DateTime<Utc>,
16    pub next: RecordLog,
17}
18
19impl Scheduler {
20    pub fn new(parameters: Parameters, card: Card, now: DateTime<Utc>) -> Self {
21        let mut current_card: Card = card.clone();
22        current_card.elapsed_days = match card.state {
23            New => 0,
24            _ => (now - card.last_review).num_days(),
25        };
26        current_card.last_review = now;
27        current_card.reps += 1;
28        let mut scheduler = Self {
29            parameters,
30            last: card,
31            current: current_card,
32            now,
33            next: RecordLog::new(),
34        };
35        scheduler.init_seed();
36
37        scheduler
38    }
39
40    pub const fn build_log(&self, rating: Rating) -> ReviewLog {
41        ReviewLog {
42            rating,
43            state: self.current.state,
44            elapsed_days: self.current.elapsed_days,
45            scheduled_days: self.current.scheduled_days,
46            reviewed_date: self.now,
47        }
48    }
49
50    fn init_seed(&mut self) {
51        let time = self.now.timestamp_millis();
52        let reps = self.current.reps;
53        let mul = self.current.difficulty * self.current.stability;
54        self.parameters.seed = Seed::new(format!("{}_{}_{}", time, reps, mul));
55    }
56}
57
58pub trait ImplScheduler {
59    fn preview(&mut self) -> RecordLog {
60        Rating::iter()
61            .map(|&rating| (rating, self.review(rating)))
62            .collect()
63    }
64    fn review(&mut self, rating: Rating) -> SchedulingInfo;
65}