Skip to main content

16_extract_from_asset/
16_extract_from_asset.rs

1use keket::{
2    database::AssetDatabase,
3    fetch::{
4        extract::{ExtractAssetFetch, from_asset_extractor},
5        file::FileAssetFetch,
6    },
7    protocol::{bytes::BytesAssetProtocol, text::TextAssetProtocol},
8};
9use std::{error::Error, io::Cursor, io::Read};
10use zip::ZipArchive;
11
12fn main() -> Result<(), Box<dyn Error>> {
13    /* ANCHOR: main */
14    let mut database = AssetDatabase::default()
15        .with_protocol(TextAssetProtocol)
16        .with_protocol(BytesAssetProtocol)
17        // We start with regular fetch engine.
18        .with_fetch(FileAssetFetch::default().with_root("resources"));
19
20    // Start loading package ZIP bytes.
21    database.ensure("bytes://package.zip")?;
22
23    // Maintain database while busy.
24    while database.is_busy() {
25        database.maintain()?;
26    }
27
28    // Then we push extraction asset fetch to fetch engine stack. From now on
29    // any future asset request will be extracted from loaded ZIP archive.
30    database.push_fetch(ExtractAssetFetch::new(from_asset_extractor(
31        "bytes://package.zip",
32        |bytes: &Vec<u8>, path| {
33            let mut archive = ZipArchive::new(Cursor::new(bytes))?;
34            let mut file = archive.by_name(path.path())?;
35            let mut result = vec![];
36            file.read_to_end(&mut result)?;
37            Ok(result)
38        },
39    )));
40
41    // Extract some assets from ZIP asset.
42    let lorem = database.ensure("text://lorem.txt")?;
43    let trash = database.ensure("bytes://trash.bin")?;
44
45    // Run maintenance to process extracted asset bytes.
46    database.maintain()?;
47
48    println!("Lorem Ipsum: {}", lorem.access::<&String>(&database));
49    println!("Bytes: {:?}", trash.access::<&Vec<u8>>(&database));
50    /* ANCHOR_END: main */
51
52    Ok(())
53}