Skip to main content

22_store_custom_asset/
22_store_custom_asset.rs

1use keket::{
2    database::{AssetDatabase, inspector::AssetInspector},
3    fetch::file::FileAssetFetch,
4    protocol::bundle::BundleAssetProtocol,
5    store::file::FileAssetStore,
6};
7use serde::{Deserialize, Serialize};
8use std::error::Error;
9
10#[derive(Debug, Serialize, Deserialize)]
11#[allow(dead_code)]
12struct Person {
13    name: String,
14    age: u8,
15}
16
17fn main() -> Result<(), Box<dyn Error>> {
18    /* ANCHOR: main */
19    let mut database = AssetDatabase::default()
20        .with_protocol(BundleAssetProtocol::new(
21            "json",
22            (
23                |bytes: Vec<u8>| {
24                    let asset = serde_json::from_slice::<Person>(&bytes)?;
25                    Ok((asset,).into())
26                },
27                // Additionally to decoding asset we can also encode it back to bytes.
28                // This is useful for saving assets to storage.
29                |inspector: AssetInspector| {
30                    let asset = inspector.access::<&Person>();
31                    let bytes = serde_json::to_vec(asset)?;
32                    Ok(bytes.into())
33                },
34            ),
35        ))
36        .with_fetch(FileAssetFetch::default().with_root("resources"))
37        .with_store(FileAssetStore::default().with_root("resources"));
38
39    let _ = std::fs::remove_file("./resources/saved.json");
40
41    let before = database.spawn(
42        "json://saved.json",
43        (Person {
44            name: "Alice".to_owned(),
45            age: 42,
46        },),
47    )?;
48    println!("Before: {:?}", before.access::<&Person>(&database));
49    before.store(&mut database)?;
50
51    while database.is_busy() {
52        database.maintain()?;
53    }
54
55    before.delete(&mut database);
56    assert!(!before.does_exists(&database));
57
58    // Load the asset from storage, we get previously saved asset content.
59    let after = database.ensure("json://saved.json")?;
60    println!("After: {:?}", after.access::<&Person>(&database));
61    /* ANCHOR_END: main */
62
63    Ok(())
64}