sm_2/
card.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::time::{SystemTime, UNIX_EPOCH};
4
5#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
6pub struct Card {
7    pub card_id: u128,
8    pub n: u32,
9    pub ef: f32,
10    pub i: u32,
11    pub due: DateTime<Utc>,
12    pub needs_extra_review: bool,
13}
14
15impl Default for Card {
16    fn default() -> Self {
17        Self {
18            card_id: now_millis(),
19            n: 0,
20            ef: 2.5,
21            i: 0,
22            due: Utc::now(),
23            needs_extra_review: false,
24        }
25    }
26}
27
28impl Card {
29    pub fn to_json(&self) -> Result<String, serde_json::Error> {
30        serde_json::to_string(self)
31    }
32
33    pub fn from_json(json: &str) -> Result<Card, serde_json::Error> {
34        serde_json::from_str(json)
35    }
36}
37
38fn now_millis() -> u128 {
39    SystemTime::now()
40        .duration_since(UNIX_EPOCH)
41        .expect("SystemTime::now() is before UNIX_EPOCH")
42        .as_millis()
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48    use chrono::Duration;
49
50    #[test]
51    fn create_card_with_default_values() {
52        let card = Card::default();
53
54        assert!(card.card_id > 0);
55
56        assert_eq!(card.n, 0);
57        assert_eq!(card.ef, 2.5);
58        assert_eq!(card.i, 0);
59
60        let now = Utc::now();
61        assert!(now >= card.due);
62        assert!(now - card.due <= Duration::milliseconds(10));
63
64        assert!(!card.needs_extra_review);
65    }
66}