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, pub(crate) archived: bool, pub(crate) description: Option, pub(crate) categories: HashSet, } impl Task { pub fn new( name: String, cron: Option, description: Option, categories: Option>, ) -> 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 { 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> { 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> { Ok(ToSqlOutput::Owned(Value::Text(self.0.clone()))) } } impl FromSql for Category { fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult { 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) } }