Skip to main content

02_zip/
02_zip.rs

1use keket::{
2    database::{AssetDatabase, path::AssetPath},
3    fetch::container::{ContainerAssetFetch, ContainerPartialFetch},
4    protocol::text::TextAssetProtocol,
5};
6use std::{error::Error, fs::File, io::Read};
7use zip::ZipArchive;
8
9fn main() -> Result<(), Box<dyn Error>> {
10    /* ANCHOR: main */
11    let mut database = AssetDatabase::default()
12        .with_protocol(TextAssetProtocol)
13        // Container asset fetch allows to use partial asset fetch object
14        // that can take asset path and returns bytes from some container.
15        .with_fetch(ContainerAssetFetch::new(ZipContainerPartialFetch::new(
16            ZipArchive::new(File::open("./resources/package.zip")?)?,
17        )));
18
19    let lorem = database.ensure("text://lorem.txt")?;
20    println!("Lorem Ipsum: {}", lorem.access::<&String>(&database));
21    /* ANCHOR_END: main */
22
23    Ok(())
24}
25
26/* ANCHOR: zip */
27// Here we show how to make ZIP archive file reader.
28struct ZipContainerPartialFetch {
29    archive: ZipArchive<File>,
30}
31
32impl ZipContainerPartialFetch {
33    pub fn new(archive: ZipArchive<File>) -> Self {
34        Self { archive }
35    }
36}
37
38impl ContainerPartialFetch for ZipContainerPartialFetch {
39    // We use input path and try to unpack file under that path from ZIP archive.
40    fn load_bytes(&mut self, path: AssetPath) -> Result<Vec<u8>, Box<dyn Error>> {
41        let mut file = self
42            .archive
43            .by_name(path.path())
44            .map_err(|error| format!("Could not read zip file: `{}` - {}", path.path(), error))?;
45        let mut bytes = vec![];
46        file.read_to_end(&mut bytes)?;
47        Ok(bytes)
48    }
49}
50/* ANCHOR_END: zip */