From 7a90f7f4cdfc53b65d30df806de0a26ca6b86b8c Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Sun, 29 Apr 2018 13:29:50 +0200 Subject: Move event to it's own module --- src/event.rs | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/event.rs (limited to 'src/event.rs') diff --git a/src/event.rs b/src/event.rs new file mode 100644 index 0000000..904e550 --- /dev/null +++ b/src/event.rs @@ -0,0 +1,123 @@ +use std::cmp::Ordering; +use std::fmt; +use std::str::FromStr; + +use chrono; +use chrono::prelude::{DateTime, TimeZone}; +use chrono_tz::{Tz, UTC}; + +use ics::IcsError; + + +#[derive(Debug)] +pub struct Event { + pub start: Date, + pub end: Date, + pub summary: String, + pub location: String, + pub description: String, + pub status: Status, +} + +#[derive(Debug)] +pub enum Date { + Time(DateTime), + AllDay(chrono::Date), +} + +#[derive(Debug)] +pub enum Status { + Confirmed, + Tentative, + Canceled, +} + + +impl Event { + pub fn new() -> Event { + return Event { + summary: "".to_string(), + location: "".to_string(), + description: "".to_string(), + status: Status::Confirmed, + start: Date::Time(UTC.timestamp(0, 0)), + end: Date::Time(UTC.timestamp(0, 0)), + }; + } +} + +impl fmt::Display for Event { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}: {}", self.start, self.summary)?; + if !self.location.is_empty() { + write!(f, " ({})", self.location)?; + } + if !self.description.is_empty() { + write!(f, "\n\t{}", self.description)?; + } + Ok(()) + } +} + +impl Date { + pub fn cmp(&self, other: &Self) -> Ordering { + match *self { + Date::Time(t1) => { + match *other { + Date::Time(t2) => t1.cmp(&t2), + Date::AllDay(d) => cmp_date_time(&d, &t1).reverse(), + } + } + Date::AllDay(d1) => { + match *other { + Date::Time(t) => cmp_date_time(&d1, &t), + Date::AllDay(d2) => d1.cmp(&d2), + } + } + } + } + + pub fn parse(date: String, time_zone: String) -> Result { + let tz: Tz = time_zone.parse().unwrap_or(UTC); + let date = match date.find("T") { + Some(_) => { + let time = tz.datetime_from_str(&date, "%Y%m%dT%H%M%S").unwrap_or( + UTC.timestamp( + 0, + 0, + ), + ); + Date::Time(time) + } + None => { + Date::AllDay(tz.ymd( + i32::from_str(&date[0..4])?, + u32::from_str(&date[4..6])?, + u32::from_str(&date[6..8])?, + )) + } + }; + Ok(date) + } +} + +impl FromStr for Status { + type Err = IcsError; + + fn from_str(s: &str) -> Result { + match s { + "CONFIRMED" => Ok(Status::Confirmed), + "TENTATIVE" => Ok(Status::Tentative), + "CANCELED" => Ok(Status::Canceled), + _ => Err(IcsError::StatusError), + } + } +} + +fn cmp_date_time(date: &chrono::Date, time: &DateTime) -> Ordering { + let d2 = time.date(); + if date.eq(&d2) { + return Ordering::Less; + } + date.cmp(&d2) +} -- cgit v1.2.3