1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
mod component;
use std::io::BufRead;
use std::error::Error;
use std::cell::RefCell;
use std::fmt;
use super::{parser, line};
use self::component::{Component, IcalCalendar};
pub struct IcalParser<B> {
line_parser: RefCell<parser::LineParser<B>>,
}
impl<B: BufRead> IcalParser<B> {
pub fn new(reader: B) -> IcalParser<B> {
let line_reader = line::LineReader::new(reader);
let line_parser = parser::LineParser::new(line_reader);
IcalParser { line_parser: RefCell::new(line_parser) }
}
fn check_header(&mut self) -> Result<Option<()>, IcalError> {
let line = match self.line_parser.borrow_mut().next() {
Some(val) => val?,
None => return Ok(None),
};
if line.name != "BEGIN" || line.value != "VCALENDAR" || line.params != None {
return Err(IcalError::MissingCalendarHeader);
}
Ok(Some(()))
}
}
impl<B: BufRead> Iterator for IcalParser<B> {
type Item = Result<IcalCalendar, IcalError>;
fn next(&mut self) -> Option<Result<IcalCalendar, IcalError>> {
match self.check_header() {
Ok(res) => {
if res == None {
return None;
}
}
Err(err) => return Some(Err(err)),
};
let mut calendar = IcalCalendar::new();
let result = match calendar.parse(&self.line_parser) {
Ok(_) => Ok(calendar),
Err(err) => Err(err),
};
Some(result)
}
}
#[derive(Debug)]
pub enum IcalError {
Parse(parser::ParseError),
EndOfFile,
MissingCalendarHeader,
NotImplemented,
NotComplete,
InvalidComponent(String),
}
impl Error for IcalError {
fn description(&self) -> &str {
match *self {
IcalError::MissingCalendarHeader => "Missing VCALENDAR header.",
IcalError::EndOfFile => "End of file.",
IcalError::NotImplemented => "Element parsing not implemented yet.",
IcalError::NotComplete => "Calendar component is not complete.",
IcalError::InvalidComponent(_) => "Contains an invalid component.",
IcalError::Parse(ref err) => err.description(),
}
}
fn cause(&self) -> Option<&Error> {
match *self {
IcalError::Parse(ref err) => Some(err),
_ => None,
}
}
}
impl fmt::Display for IcalError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl From<parser::ParseError> for IcalError {
fn from(err: parser::ParseError) -> IcalError {
IcalError::Parse(err)
}
}