diff --git a/src/models/task.rs b/src/models/task.rs index 7b4d7cc..a925b6e 100644 --- a/src/models/task.rs +++ b/src/models/task.rs @@ -1,10 +1,12 @@ -use chrono::NaiveDateTime; use crate::models::category::Category; +use crate::models::subtask::Subtask; use crate::schema::tasks; +use crate::utils::reverse_ord_option::ReverseOrdOption; +use chrono::NaiveDateTime; use diesel::prelude::*; use serde::{Deserialize, Serialize}; +use std::cmp::Ordering; use validator::Validate; -use crate::models::subtask::Subtask; const TITLE_LENGTH_MIN: u64 = 1; const TITLE_LENGTH_MAX: u64 = 255; @@ -52,6 +54,40 @@ impl Task { } } +impl Eq for Task {} + +impl PartialOrd for Task { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Task { + fn cmp(&self, other: &Self) -> Ordering { + match (&self.category, &other.category) { + (Category::Inbox, Category::Inbox) => self.created_at.cmp(&other.created_at), + ( + Category::Calendar { date: self_date, time: self_time, .. }, + Category::Calendar { date: other_date, time: other_time, .. } + ) => self_date.cmp(other_date) + .then(ReverseOrdOption::from( + &self_time.as_ref().map(|calendar_time| calendar_time.time()) + ).cmp(&ReverseOrdOption::from( + &other_time.as_ref().map(|calendar_time| calendar_time.time()) + ))) + .then(ReverseOrdOption::from(&self.deadline()).cmp( + &ReverseOrdOption::from(&other.deadline()) + )) + .then(self.created_at.cmp(&other.created_at)), + (Category::Done, Category::Done) | (Category::Trash, Category::Trash) + => self.updated_at.cmp(&other.updated_at).reverse(), + (_, _) => ReverseOrdOption::from(&self.deadline()).cmp( + &ReverseOrdOption::from(&other.deadline()) + ).then(self.created_at.cmp(&other.created_at)), + } + } +} + #[derive(Serialize, Deserialize, PartialEq, Clone, Debug)] pub struct TaskWithSubtasks { task: Task, @@ -72,6 +108,20 @@ impl TaskWithSubtasks { } } +impl Eq for TaskWithSubtasks {} + +impl PartialOrd for TaskWithSubtasks { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for TaskWithSubtasks { + fn cmp(&self, other: &Self) -> Ordering { + self.task().cmp(other.task()) + } +} + #[derive(Insertable, Serialize, Deserialize, Validate, Clone, Debug)] #[diesel(table_name = tasks)] pub struct NewTask {