use chrono::{DateTime, Utc}; use http::uri::Uri; use serde::{Deserialize, Serialize}; use std::fmt; use uuid::Uuid; #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy, Eq)] #[serde(rename_all = "lowercase")] pub enum Recurrence { Daily, Weekly, Monthly, Yearly, } impl fmt::Display for Recurrence { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", format!("{:?}", self).to_lowercase()) } } #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy, Eq)] #[serde(rename_all = "lowercase")] pub enum Status { Pending, Completed, Recurring, Deleted, } impl fmt::Display for Status { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", format!("{:?}", self).to_lowercase()) } } #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy, Eq)] pub enum Priority { H, M, L, } impl fmt::Display for Priority { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) } } #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Eq)] pub struct Bookmark { #[serde(with = "uri")] pub uri: Uri, #[serde(default, skip_serializing_if = "Option::is_none")] pub content: Option, } #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Eq)] pub struct BookmarkContent { pub title: String, pub content_preview: Option, } pub mod uri { use http::uri::Uri; use serde::{self, Deserialize, Deserializer, Serializer}; pub fn serialize(uri: &Uri, serializer: S) -> Result where S: Serializer, { let uri_str = uri.to_string(); serializer.serialize_str(&uri_str) } pub fn deserialize<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; s.parse::().map_err(serde::de::Error::custom) } } #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Eq)] pub struct ContextswitchData { pub bookmarks: Vec, } #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Eq)] pub struct TaskId(pub Uuid); impl fmt::Display for TaskId { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) } } #[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] pub struct Task { pub id: TaskId, #[serde(with = "tw_date_format")] pub entry: DateTime, #[serde(with = "tw_date_format")] pub modified: DateTime, pub status: Status, pub description: String, pub urgency: f64, #[serde( default, skip_serializing_if = "Option::is_none", with = "opt_tw_date_format" )] pub due: Option>, #[serde( default, skip_serializing_if = "Option::is_none", with = "opt_tw_date_format" )] pub start: Option>, #[serde( default, skip_serializing_if = "Option::is_none", with = "opt_tw_date_format" )] pub end: Option>, #[serde( default, skip_serializing_if = "Option::is_none", with = "opt_tw_date_format" )] pub wait: Option>, #[serde(default, skip_serializing_if = "Option::is_none")] pub parent: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub project: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub priority: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub recur: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub tags: Option>, #[serde(default, skip_serializing_if = "Option::is_none")] pub contextswitch: Option, } #[derive(Deserialize, Serialize)] pub struct NewTask { pub definition: String, } pub mod tw_date_format { use chrono::{DateTime, TimeZone, Utc}; use serde::{self, Deserialize, Deserializer, Serializer}; const FORMAT: &str = "%Y%m%dT%H%M%SZ"; pub fn serialize(date: &DateTime, serializer: S) -> Result where S: Serializer, { let s = format!("{}", date.format(FORMAT)); serializer.serialize_str(&s) } pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; Utc.datetime_from_str(&s, FORMAT) .map_err(serde::de::Error::custom) } } pub mod opt_tw_date_format { use chrono::{DateTime, TimeZone, Utc}; use serde::{self, Deserialize, Deserializer, Serializer}; const FORMAT: &str = "%Y%m%dT%H%M%SZ"; pub fn serialize(date: &Option>, serializer: S) -> Result where S: Serializer, { if let Some(ref d) = *date { return serializer.serialize_str(&d.format(FORMAT).to_string()); } serializer.serialize_none() } pub fn deserialize<'de, D>(deserializer: D) -> Result>, D::Error> where D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; Utc.datetime_from_str(&s, FORMAT) .map(Some) .map_err(serde::de::Error::custom) } }