use std::io::Read;
use self::{resource::Resource, sign::SignConfig};
use crate::{error::PassError, Pass};
pub mod manifest;
pub(super) mod pass_writer;
pub mod read;
pub mod resource;
pub mod sign;
pub mod write;
#[derive(Debug)]
pub struct Package {
pub pass: Pass,
pub resources: Vec<Resource>,
pub sign_config: Option<SignConfig>,
}
impl Package {
#[must_use]
pub fn new(pass: Pass) -> Self {
Self {
pass,
resources: vec![],
sign_config: None,
}
}
pub fn add_certificates(&mut self, config: SignConfig) {
self.sign_config = Some(config);
}
pub fn add_resource<R: Read>(
&mut self,
image_type: resource::Type,
mut reader: R,
) -> Result<(), PassError> {
let mut resource = Resource::new(image_type);
std::io::copy(&mut reader, &mut resource)?;
self.resources.push(resource);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::pass::{PassBuilder, PassConfig};
use std::io::Read;
#[test]
fn make_package() {
let pass = PassBuilder::new(PassConfig {
organization_name: "Apple inc.".into(),
description: "Example pass".into(),
pass_type_identifier: "com.example.pass".into(),
team_identifier: "AA00AA0A0A".into(),
serial_number: "ABCDEFG1234567890".into(),
})
.logo_text("Test pass".into())
.build();
let _package = Package::new(pass);
}
#[test]
fn write_package() {
let pass = PassBuilder::new(PassConfig {
organization_name: "Apple inc.".into(),
description: "Example pass".into(),
pass_type_identifier: "com.example.pass".into(),
team_identifier: "AA00AA0A0A".into(),
serial_number: "ABCDEFG1234567890".into(),
})
.logo_text("Test pass".into())
.build();
let expected_pass_json = pass.to_json().unwrap();
let mut package = Package::new(pass);
let mut buf = Vec::new();
let writer = std::io::Cursor::new(&mut buf);
package.write(writer).unwrap();
let reader = std::io::Cursor::new(&mut buf);
let mut zip = zip::ZipArchive::new(reader).unwrap();
for i in 0..zip.len() {
let file = zip.by_index(i).unwrap();
println!("file[{}]: {}", i, file.name());
}
let mut packaged_pass_json = String::new();
let _ = zip
.by_name("pass.json")
.unwrap()
.read_to_string(&mut packaged_pass_json);
assert_eq!(expected_pass_json, packaged_pass_json);
}
#[test]
fn read_package() {
let pass = PassBuilder::new(PassConfig {
organization_name: "Apple inc.".into(),
description: "Example pass".into(),
pass_type_identifier: "com.example.pass".into(),
team_identifier: "AA00AA0A0A".into(),
serial_number: "ABCDEFG1234567890".into(),
})
.logo_text("Test pass".into())
.build();
let expected_json = pass.to_json().unwrap();
let mut package = Package::new(pass);
let data = [0u8; 2048];
package
.add_resource(resource::Type::Icon(resource::Version::Standard), &data[..])
.unwrap();
package
.add_resource(resource::Type::Logo(resource::Version::Size3X), &data[..])
.unwrap();
let mut buf = Vec::new();
let writer = std::io::Cursor::new(&mut buf);
package.write(writer).unwrap();
let reader = std::io::Cursor::new(&mut buf[..]);
let package_read = Package::read(reader).unwrap();
let read_json = package_read.pass.to_json().unwrap();
assert_eq!(expected_json, read_json);
println!("{:?}", package.resources);
assert_eq!(2, package.resources.len());
assert_eq!("icon.png", package.resources.first().unwrap().filename());
assert_eq!("logo@3x.png", package.resources.get(1).unwrap().filename());
}
}