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}