From 26ddc4889560ea1e63e7fec674fbd87bb394acfb Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Sun, 29 Apr 2018 20:10:43 +0200 Subject: Add Events type --- src/errors.rs | 21 +++++++++++++++++ src/event.rs | 14 ++++++------ src/events.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++ src/ics.rs | 73 ----------------------------------------------------------- src/main.rs | 17 +++++++++----- 5 files changed, 95 insertions(+), 86 deletions(-) create mode 100644 src/errors.rs create mode 100644 src/events.rs delete mode 100644 src/ics.rs diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..d526bae --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,21 @@ +use std::num::ParseIntError; +use ical::parser; + +#[derive(Debug)] +pub enum EventError { + IcalError(parser::errors::Error), + IntError(ParseIntError), + StatusError, +} + +impl From for EventError { + fn from(err: parser::errors::Error) -> EventError { + EventError::IcalError(err) + } +} + +impl From for EventError { + fn from(err: ParseIntError) -> EventError { + EventError::IntError(err) + } +} diff --git a/src/event.rs b/src/event.rs index 904e550..92b91ed 100644 --- a/src/event.rs +++ b/src/event.rs @@ -3,10 +3,10 @@ use std::fmt; use std::str::FromStr; use chrono; -use chrono::prelude::{DateTime, TimeZone}; +use chrono::TimeZone; use chrono_tz::{Tz, UTC}; -use ics::IcsError; +use errors::EventError; #[derive(Debug)] @@ -21,7 +21,7 @@ pub struct Event { #[derive(Debug)] pub enum Date { - Time(DateTime), + Time(chrono::DateTime), AllDay(chrono::Date), } @@ -77,7 +77,7 @@ impl Date { } } - pub fn parse(date: String, time_zone: String) -> Result { + 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(_) => { @@ -102,19 +102,19 @@ impl Date { } impl FromStr for Status { - type Err = IcsError; + type Err = EventError; fn from_str(s: &str) -> Result { match s { "CONFIRMED" => Ok(Status::Confirmed), "TENTATIVE" => Ok(Status::Tentative), "CANCELED" => Ok(Status::Canceled), - _ => Err(IcsError::StatusError), + _ => Err(EventError::StatusError), } } } -fn cmp_date_time(date: &chrono::Date, time: &DateTime) -> Ordering { +fn cmp_date_time(date: &chrono::Date, time: &chrono::DateTime) -> Ordering { let d2 = time.date(); if date.eq(&d2) { return Ordering::Less; diff --git a/src/events.rs b/src/events.rs new file mode 100644 index 0000000..a78a286 --- /dev/null +++ b/src/events.rs @@ -0,0 +1,56 @@ +use std::io::BufRead; +use std::fmt; +use ical::IcalParser; + +use event::{Event, Date}; +use errors::EventError; + +pub struct Events { + single: Vec, +} + +impl Events { + pub fn parse(buf: B) -> Result { + let reader = IcalParser::new(buf); + let mut single = Vec::new(); + + for line in reader { + for ev in line?.events { + let mut event = Event::new(); + for property in ev.properties { + let value = property.value.unwrap_or("".to_string()); + let mut time_zone = "".to_string(); + + for (param, value) in property.params.unwrap_or(vec![]) { + if param == "TZID" && value.len() > 0 { + time_zone = value[0].clone(); + } + } + + match property.name.as_ref() { + "SUMMARY" => event.summary = value, + "LOCATION" => event.location = value, + "DESCRIPTION" => event.description = value, + "STATUS" => event.status = value.parse()?, + "DTSTART" => event.start = Date::parse(&value, &time_zone)?, + "DTEND" => event.end = Date::parse(&value, &time_zone)?, + _ => (), + }; + } + single.push(event); + } + } + + single.sort_by(|a, b| a.start.cmp(&b.start)); + Ok(Events { single }) + } +} + +impl fmt::Display for Events { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for event in &self.single { + writeln!(f, "{}", event)?; + } + Ok(()) + } +} diff --git a/src/ics.rs b/src/ics.rs deleted file mode 100644 index 0726ba1..0000000 --- a/src/ics.rs +++ /dev/null @@ -1,73 +0,0 @@ -use std::io; -use std::io::BufReader; -use std::fs::File; -use std::path::Path; -use std::num::ParseIntError; - -use ical::parser; -use ical::IcalParser; - -use event::{Event, Date}; - - -pub fn parse>(ics: P) -> Result, IcsError> { - let buf = BufReader::new(File::open(ics)?); - let reader = IcalParser::new(buf); - let mut events = Vec::new(); - - for line in reader { - for ev in line?.events { - let mut event = Event::new(); - for property in ev.properties { - let value = property.value.unwrap_or("".to_string()); - let mut time_zone = "".to_string(); - - for (param, value) in property.params.unwrap_or(vec![]) { - if param == "TZID" && value.len() > 0 { - time_zone = value[0].clone(); - } - } - - match property.name.as_ref() { - "SUMMARY" => event.summary = value, - "LOCATION" => event.location = value, - "DESCRIPTION" => event.description = value, - "STATUS" => event.status = value.parse()?, - "DTSTART" => event.start = Date::parse(value, time_zone)?, - "DTEND" => event.end = Date::parse(value, time_zone)?, - _ => (), - }; - } - events.push(event); - } - } - - events.sort_by(|a, b| a.start.cmp(&b.start)); - Ok(events) -} - -#[derive(Debug)] -pub enum IcsError { - IoError(io::Error), - IcalError(parser::errors::Error), - IntError(ParseIntError), - StatusError, -} - -impl From for IcsError { - fn from(err: io::Error) -> IcsError { - IcsError::IoError(err) - } -} - -impl From for IcsError { - fn from(err: parser::errors::Error) -> IcsError { - IcsError::IcalError(err) - } -} - -impl From for IcsError { - fn from(err: ParseIntError) -> IcsError { - IcsError::IntError(err) - } -} diff --git a/src/main.rs b/src/main.rs index f51f763..c923232 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,14 +2,19 @@ extern crate ical; extern crate chrono; extern crate chrono_tz; -use std::env; -mod ics; mod event; +mod events; +mod errors; + +use std::env; +use std::io::BufReader; +use std::fs::File; +use events::Events; fn main() { let args: Vec<_> = env::args().collect(); - let events = ics::parse(&args[1]).unwrap(); - for event in events { - println!("{}", event); - } + let file = File::open(&args[1]).unwrap(); + let buf = BufReader::new(file); + let events = Events::parse(buf).unwrap(); + println!("{}", events); } -- cgit v1.2.3