diff options
author | Jamie Murphy <hello@itsjamie.dev> | 2023-02-11 23:02:33 -0800 |
---|---|---|
committer | Jamie Murphy <hello@itsjamie.dev> | 2023-02-12 07:14:41 +0000 |
commit | 1c2b5f0b327e95c18ccb2322c79c8a5987c3c888 (patch) | |
tree | babd4974d17d1227e3e3789c277c8754103cb23e | |
parent | 68c617e5f8aba7ff3b3d8b81394fa9121cf0a1c0 (diff) | |
download | gnome-todo-1c2b5f0b327e95c18ccb2322c79c8a5987c3c888.tar.gz |
task: Setup Task for being used with Diesel
Implement the Queryable trait, as well as fix some properties to match
the database
-rw-r--r-- | src/engine/task.rs | 116 |
1 files changed, 91 insertions, 25 deletions
diff --git a/src/engine/task.rs b/src/engine/task.rs index 3a14a17c..7f987262 100644 --- a/src/engine/task.rs +++ b/src/engine/task.rs @@ -1,10 +1,12 @@ +use chrono::NaiveDateTime; +use diesel::{sqlite::Sqlite, Queryable}; use gtk::{ glib::{self, Object}, prelude::*, subclass::prelude::*, }; -use crate::utils::Iso8601; +use crate::{schema, utils::Iso8601}; /// The task's priority. /// For more details please view RFC 5545, section 3.8.1.9 @@ -45,18 +47,18 @@ mod imp { pub struct Task { // summary, RFC 5545, 3.8.1.12 #[property(get, set)] - pub title: RefCell<String>, + pub title: RefCell<Option<String>>, // description, RFC 5545, 3.8.1.5 #[property(get, set)] - pub description: RefCell<String>, + pub description: RefCell<Option<String>>, // due, RFC 5545, 3.8.2.3 - #[property(get = Self::due_date, set = Self::set_due_date, type = String)] - pub due_date: Cell<NaiveDateTime>, + #[property(get = Self::due_date, set = Self::set_due_date, type = Option<String>)] + pub due_date: Cell<Option<NaiveDateTime>>, // completed, RFC 5545, 3.8.2.1 - #[property(get = Self::completed, set = Self::set_completed, type = String)] - pub completed: Cell<NaiveDateTime>, + #[property(get = Self::completed, set = Self::set_completed, type = Option<String>)] + pub completed: Cell<Option<NaiveDateTime>>, // priority, RFC 5545, 3.8.1.9 - #[property(get, set)] + #[property(get, set, default = 9)] // so apparently this macro doesn't like default = 9 pub priority: Cell<i32>, // created, RFC 5545, 3.8.7.1 #[property(get = Self::created, set = Self::set_created, type = String)] @@ -92,26 +94,26 @@ mod imp { } impl Task { - fn due_date(&self) -> String { - self.due_date.get().to_iso8601() + fn due_date(&self) -> Option<String> { + self.due_date.get().map(|s| s.to_iso8601()) } fn set_due_date(&self, value: String) { - self.due_date.replace( - NaiveDateTime::parse_from_iso8601(&value) - .expect("The value needs to be in a format recognizable by ISO8601"), - ); + self.due_date + .replace(Some(NaiveDateTime::parse_from_iso8601(&value).expect( + "The value needs to be in a format recognizable by ISO8601", + ))); } - fn completed(&self) -> String { - self.completed.get().to_iso8601() + fn completed(&self) -> Option<String> { + self.completed.get().map(|s| s.to_iso8601()) } fn set_completed(&self, value: String) { - self.completed.replace( - NaiveDateTime::parse_from_iso8601(&value) - .expect("The value needs to be in a format recognizable by ISO8601"), - ); + self.completed + .replace(Some(NaiveDateTime::parse_from_iso8601(&value).expect( + "The value needs to be in a format recognizable by ISO8601", + ))); } fn created(&self) -> String { @@ -142,12 +144,46 @@ glib::wrapper! { pub struct Task(ObjectSubclass<imp::Task>); } -impl Task { - #![allow(clippy::new_without_default)] - +impl Default for Task { /// Create a new Task - pub fn new() -> Self { - Object::new::<Self>() + /// The `created`, `last-modified`, and `modification-count` properties + /// are preset using this method and do not need to be set again. Use `new` + /// to create a Task with no defaults + fn default() -> Self { + let current_time = chrono::Utc::now().naive_utc().to_iso8601(); + Object::builder() + .property("priority", 9) // so we'll add the priority here + .property("created", current_time.clone()) + .property("last-modified", current_time) + .property("modification-count", 0) + .build() + } +} + +impl Task { + #![allow(clippy::too_many_arguments)] + + /// Create a new Task with values from a database + pub fn new( + title: Option<String>, + description: Option<String>, + due_date: Option<NaiveDateTime>, + completed: Option<NaiveDateTime>, + priority: Option<i32>, + created: NaiveDateTime, + last_modified: NaiveDateTime, + modification_count: i32, + ) -> Self { + Object::builder() + .property("title", title) + .property("description", description) + .property("due_date", due_date.map(|s| s.to_iso8601())) + .property("completed", completed.map(|s| s.to_iso8601())) + .property("priority", priority.unwrap_or(9)) + .property("created", created.to_iso8601()) + .property("last_modified", last_modified.to_iso8601()) + .property("modification_count", modification_count) + .build() } /// Create a UID for the Task. @@ -160,3 +196,33 @@ impl Task { format!("{date}@ENDEAVOUR") } } + +impl Queryable<schema::tasks::SqlType, Sqlite> for Task { + type Row = ( + String, // id + Option<String>, // title + Option<String>, // description + Option<String>, // due_date + Option<String>, // completed + Option<i32>, // priority + String, // created + String, // last_modified + i32, // modification_count + Option<i32>, // list + ); + + fn build(row: Self::Row) -> diesel::deserialize::Result<Self> { + Ok(Self::new( + row.1, + row.2, + row.3 + .map(|s| NaiveDateTime::parse_from_iso8601(&s).expect("Expected NaiveDateTime")), + row.4 + .map(|s| NaiveDateTime::parse_from_iso8601(&s).expect("Expected NaiveDateTime")), + row.5, + NaiveDateTime::parse_from_iso8601(&row.6).expect("Expected NaiveDateTime"), + NaiveDateTime::parse_from_iso8601(&row.7).expect("Expected NaiveDateTime"), + row.8, + )) + } +} |