1
use crate::convert::ToModel;
2
use crate::model::object::ICalObject;
3
use crate::parser::{content_line_first_pass, ical_stream, Error};
4
use std::io::Read;
5

            
6
/// Load iCalendar data from anything readable.
7
///
8
/// This could be a byte array, a file, a network stream, etc. If the file cannot be parsed or
9
/// represented using the core model, an error is returned.
10
/// The content is expected to be a list of iCalendar objects. In most cases, this it is a single
11
/// iCalendar object, containing multiple components.
12
///
13
/// Note that this function does NOT validate the iCalendar data. You should use the validator if
14
/// you want to ensure that the data is reasonably correct. If you plan to ingest the data into
15
/// another system, you should definitely validate the result of this function because the parser
16
/// and model permit a lot of inputs that could confuse other systems.
17
5
pub fn load_ical<R: Read>(mut input: R) -> anyhow::Result<Vec<ICalObject>> {
18
5
    let mut content = Vec::new();
19
5
    input.read_to_end(&mut content)?;
20

            
21
5
    let (rem, content) = content_line_first_pass::<Error>(&content)
22
5
        .map_err(|e| anyhow::anyhow!("First pass failed: {:?}", e))?;
23
5
    if !rem.is_empty() {
24
        return Err(anyhow::anyhow!("Trailing data after first pass"));
25
5
    }
26

            
27
5
    let (rem, stream) = ical_stream::<Error>(&content)
28
5
        .map_err(|e| anyhow::anyhow!("Stream parsing failed: {:?}", e))?;
29
5
    if !rem.is_empty() {
30
        return Err(anyhow::anyhow!("Trailing data after stream"));
31
5
    }
32

            
33
5
    let model = stream.to_model()?;
34

            
35
5
    Ok(model)
36
5
}