aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/errors.rs21
-rw-r--r--src/event.rs14
-rw-r--r--src/events.rs56
-rw-r--r--src/ics.rs73
-rw-r--r--src/main.rs17
5 files changed, 95 insertions, 86 deletions
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<parser::errors::Error> for EventError {
+ fn from(err: parser::errors::Error) -> EventError {
+ EventError::IcalError(err)
+ }
+}
+
+impl From<ParseIntError> 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<Tz>),
+ Time(chrono::DateTime<Tz>),
AllDay(chrono::Date<Tz>),
}
@@ -77,7 +77,7 @@ impl Date {
}
}
- pub fn parse(date: String, time_zone: String) -> Result<Self, IcsError> {
+ pub fn parse(date: &String, time_zone: &String) -> Result<Self, EventError> {
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<Self, Self::Err> {
match s {
"CONFIRMED" => Ok(Status::Confirmed),
"TENTATIVE" => Ok(Status::Tentative),
"CANCELED" => Ok(Status::Canceled),
- _ => Err(IcsError::StatusError),
+ _ => Err(EventError::StatusError),
}
}
}
-fn cmp_date_time<T: TimeZone>(date: &chrono::Date<T>, time: &DateTime<T>) -> Ordering {
+fn cmp_date_time<T: TimeZone>(date: &chrono::Date<T>, time: &chrono::DateTime<T>) -> 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<Event>,
+}
+
+impl Events {
+ pub fn parse<B: BufRead>(buf: B) -> Result<Self, EventError> {
+ 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<P: AsRef<Path>>(ics: P) -> Result<Vec<Event>, 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<io::Error> for IcsError {
- fn from(err: io::Error) -> IcsError {
- IcsError::IoError(err)
- }
-}
-
-impl From<parser::errors::Error> for IcsError {
- fn from(err: parser::errors::Error) -> IcsError {
- IcsError::IcalError(err)
- }
-}
-
-impl From<ParseIntError> 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);
}