aboutsummaryrefslogtreecommitdiffstats
path: root/src/task.rs
blob: 59aa5020d466c03c1a70faf4db82c7b0a02b7512 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::{
    borrow::{Borrow, Cow},
    collections::HashSet,
    str::FromStr,
};

use chrono::{NaiveDateTime, TimeDelta};
use sqlx::{
    encode::IsNull,
    prelude::FromRow,
    sqlite::{SqliteArgumentValue, SqliteTypeInfo, SqliteValue},
    Decode, Sqlite, Type, TypeInfo, Value, ValueRef,
};

#[derive(FromRow)]
pub struct Task {
    id: Option<i64>,
    pub name: String,
    pub cron: Option<Schedule>,
    pub archived: bool,
    pub description: Option<String>,
    pub categories: HashSet<String>,
}

impl Task {
    pub fn new(
        name: String,
        cron: Option<Schedule>,
        description: Option<String>,
        categories: Option<HashSet<String>>,
    ) -> Self {
        Self {
            id: None,
            name,
            cron,
            archived: false,
            description,
            categories: categories.unwrap_or_else(|| HashSet::new()),
        }
    }

    pub fn id(&self) -> Option<i64> {
        self.id
    }

    pub fn add_id(mut self, id: i64) -> Self {
        self.id = Some(id);
        self
    }
}

pub struct Schedule(cron::Schedule);

impl sqlx::Encode<'_, Sqlite> for Schedule {
    fn encode_by_ref(
        &self,
        buf: &mut <Sqlite as sqlx::Database>::ArgumentBuffer<'_>,
    ) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
        let schedule = &self.0;
        let schedule = schedule.to_string();
        buf.push(SqliteArgumentValue::Text(Cow::Owned(schedule)));

        Ok(IsNull::No)
    }
}

impl sqlx::Decode<'_, Sqlite> for Schedule {
    fn decode(
        value: <Sqlite as sqlx::Database>::ValueRef<'_>,
    ) -> Result<Self, sqlx::error::BoxDynError> {
        let schedule = Decode::<Sqlite>::decode(value)?;
        let schedule = cron::Schedule::from_str(schedule)?;
        Ok(Self(schedule))
    }
}

impl Type<Sqlite> for Schedule {
    fn type_info() -> <Sqlite as sqlx::Database>::TypeInfo {
        <&str as Type<Sqlite>>::type_info()
    }
}

#[repr(transparent)]
pub struct Category(String);

impl Category {
    pub fn new(category: String) -> Self {
        Self(category)
    }
}

pub struct Log(NaiveDateTime);

impl Log {
    pub fn new(datetime: NaiveDateTime) -> Self {
        Self(datetime)
    }
}

pub struct Reminder(TimeDelta);

impl Reminder {
    pub fn new(time_delta: TimeDelta) -> Self {
        Self(time_delta)
    }
}