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
pub mod ical;
pub mod vcard;
use std::cell::RefCell;
use std::io::BufRead;
use crate::property::{Property, PropertyError, PropertyParser};
#[derive(Debug, Error)]
pub enum ParserError {
#[error("invalid component")]
InvalidComponent,
#[error("incomplete object")]
NotComplete,
#[error("missing header")]
MissingHeader,
#[error("property error: {0}")]
PropertyError(#[from] PropertyError),
}
pub trait Component {
fn add_sub_component<B: BufRead>(
&mut self,
value: &str,
line_parser: &RefCell<PropertyParser<B>>,
) -> Result<(), ParserError>;
fn add_property(&mut self, property: Property);
fn parse<B: BufRead>(
&mut self,
line_parser: &RefCell<PropertyParser<B>>,
) -> Result<(), ParserError> {
loop {
let line: Property;
{
line = match line_parser.borrow_mut().next() {
Some(val) => val.map_err(|e| ParserError::PropertyError(e))?,
None => return Err(ParserError::NotComplete.into()),
};
}
match line.name.to_uppercase().as_str() {
"END" => break,
"BEGIN" => match line.value {
Some(v) => self.add_sub_component(v.as_str(), line_parser)?,
None => return Err(ParserError::NotComplete.into()),
},
_ => self.add_property(line),
};
}
Ok(())
}
}