aboutsummaryrefslogtreecommitdiffstats
path: root/src/task.rs
blob: ce2e7e6ebe62f6a20e4306732d24f78f9e70fe0f (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::{
    collections::HashSet,
    ops::{Deref, DerefMut},
    str::FromStr,
};

use chrono::{Local, NaiveDateTime, TimeDelta};
use rusqlite::{
    types::{FromSql, FromSqlError, ToSqlOutput, Value},
    ToSql,
};
use uuid::Uuid;

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Task {
    pub(crate) name: String,
    pub(crate) cron: Option<Schedule>,
    pub(crate) archived: bool,
    pub(crate) description: Option<String>,
    pub(crate) categories: HashSet<Category>,
}

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

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Schedule(cron::Schedule);

impl FromSql for Schedule {
    fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
        let schedule = value.as_str()?;
        let schedule =
            cron::Schedule::from_str(schedule).map_err(|e| FromSqlError::Other(Box::new(e)))?;
        Ok(Self(schedule))
    }
}

impl ToSql for Schedule {
    fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
        Ok(rusqlite::types::ToSqlOutput::Owned(
            rusqlite::types::Value::Text(self.0.to_string()),
        ))
    }
}

#[repr(transparent)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Hash)]
pub struct Category(String);

impl ToSql for Category {
    fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
        Ok(ToSqlOutput::Owned(Value::Text(self.0.clone())))
    }
}

impl FromSql for Category {
    fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
        Ok(Self(value.as_str()?.to_string()))
    }
}

impl Deref for Category {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for Category {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

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

#[derive(Debug, Clone, Copy)]
pub struct Log {
    pub(crate) id: Uuid,
    pub(crate) timestamp: NaiveDateTime,
}

impl Log {
    pub fn new(datetime: NaiveDateTime) -> Self {
        Self {
            id: Uuid::new_v4(),
            timestamp: datetime,
        }
    }

    pub fn new_now() -> Self {
        Self {
            id: Uuid::new_v4(),
            timestamp: Local::now().naive_local(),
        }
    }
}

pub struct Reminder(TimeDelta);

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