use std::{
io::{Read, Seek},
str::FromStr,
};
use zip::ZipArchive;
use crate::{
error::PassError,
resource::{self, Resource},
Package, Pass,
};
impl Package {
pub fn read<R: Read + Seek>(reader: R) -> Result<Self, PassError> {
let mut zip = ZipArchive::new(reader)?;
let mut pass: Option<Pass> = None;
let mut resources = Vec::<Resource>::new();
for i in 0..zip.len() {
let mut file = zip.by_index(i)?;
let filename = file.name();
if filename == "pass.json" {
let mut buf = String::new();
file.read_to_string(&mut buf)?;
pass = Some(Pass::from_json(&buf)?);
continue;
}
if let Ok(t) = resource::Type::from_str(filename) {
let mut resource = Resource::new(t);
std::io::copy(&mut file, &mut resource)?;
resources.push(resource);
}
}
if let Some(pass) = pass {
Ok(Self {
pass,
resources,
sign_config: None,
})
} else {
Err(PassError::MissingJson)
}
}
}