1pub mod ical;
10pub mod vcard;
11
12use std::cell::RefCell;
14use std::io::BufRead;
15
16use crate::property::{Property, PropertyError, PropertyParser};
18
19#[derive(Debug, Error)]
20pub enum ParserError {
21 #[error("invalid component")]
22 InvalidComponent,
23 #[error("incomplete object")]
24 NotComplete,
25 #[error("missing header")]
26 MissingHeader,
27 #[error("property error: {0}")]
28 PropertyError(#[from] PropertyError),
29}
30
31pub trait Component {
36 fn add_sub_component<B: BufRead>(
38 &mut self,
39 value: &str,
40 line_parser: &RefCell<PropertyParser<B>>,
41 ) -> Result<(), ParserError>;
42
43 fn add_property(&mut self, property: Property);
45
46 fn parse<B: BufRead>(
48 &mut self,
49 line_parser: &RefCell<PropertyParser<B>>,
50 ) -> Result<(), ParserError> {
51 loop {
52 let line: Property;
53
54 {
55 line = match line_parser.borrow_mut().next() {
56 Some(val) => val.map_err(|e| ParserError::PropertyError(e))?,
57 None => return Err(ParserError::NotComplete.into()),
58 };
59 }
60
61 match line.name.to_uppercase().as_str() {
62 "END" => break,
63 "BEGIN" => match line.value {
64 Some(v) => self.add_sub_component(v.as_str(), line_parser)?,
65 None => return Err(ParserError::NotComplete.into()),
66 },
67
68 _ => self.add_property(line),
69 };
70 }
71
72 Ok(())
73 }
74}