1pub mod component;
35
36use crate::parser::ParserError;
38use std::cell::RefCell;
39use std::io::BufRead;
40
41use crate::line::LineReader;
43use crate::parser::Component;
44use crate::property::PropertyParser;
45
46pub struct VcardParser<B> {
48 line_parser: RefCell<PropertyParser<B>>,
49}
50
51impl<B: BufRead> VcardParser<B> {
52 pub fn new(reader: B) -> VcardParser<B> {
54 let line_reader = LineReader::new(reader);
55 let line_parser = PropertyParser::new(line_reader);
56
57 VcardParser {
58 line_parser: RefCell::new(line_parser),
59 }
60 }
61
62 fn check_header(&mut self) -> Result<Option<()>, ParserError> {
64 let line = match self.line_parser.borrow_mut().next() {
65 Some(val) => val.map_err(|e| ParserError::PropertyError(e))?,
66 None => return Ok(None),
67 };
68
69 if line.name.to_uppercase() != "BEGIN"
70 || line.value.is_none()
71 || line.value.unwrap().to_uppercase() != "VCARD"
72 || line.params != None
73 {
74 return Err(ParserError::MissingHeader.into());
75 }
76
77 Ok(Some(()))
78 }
79}
80
81impl<B: BufRead> Iterator for VcardParser<B> {
82 type Item = Result<component::VcardContact, ParserError>;
83
84 fn next(&mut self) -> Option<Result<component::VcardContact, ParserError>> {
85 match self.check_header() {
86 Ok(res) => {
87 if res == None {
88 return None;
89 }
90 }
91 Err(err) => return Some(Err(err)),
92 };
93
94 let mut contact = component::VcardContact::new();
95 let result = match contact.parse(&self.line_parser) {
96 Ok(_) => Ok(contact),
97 Err(err) => Err(err),
98 };
99
100 Some(result)
101 }
102}