Skip to main content

24_future_store/
24_future_store.rs

1use keket::{
2    database::{AssetDatabase, path::AssetPathStatic},
3    fetch::file::FileAssetFetch,
4    protocol::text::TextAssetProtocol,
5    store::future::FutureAssetStore,
6};
7use std::{error::Error, path::PathBuf};
8
9#[tokio::main]
10async fn main() -> Result<(), Box<dyn Error>> {
11    /* ANCHOR: main */
12    let mut database = AssetDatabase::default()
13        .with_protocol(TextAssetProtocol)
14        .with_fetch(FileAssetFetch::default().with_root("resources"))
15        .with_store(FutureAssetStore::new(tokio_save_file));
16
17    let _ = tokio::fs::remove_file("./resources/saved2.txt").await;
18
19    // Spawn a new asset.
20    let before = database.spawn("text://saved2.txt", ("Abra cadabra!".to_owned(),))?;
21    println!("Before: {}", before.access::<&String>(&database));
22    // Request the asset to be stored using active asset store engine.
23    before.store(&mut database)?;
24
25    // Wait until the asset is stored.
26    while database.is_busy() {
27        database.maintain()?;
28        tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
29    }
30
31    // Delete spawned asset from database just to show it will load from storage.
32    before.delete(&mut database);
33    assert!(!before.does_exists(&database));
34
35    // Load the asset from storage, we get previously saved asset content.
36    let after = database.ensure("text://saved2.txt")?;
37    println!("After: {}", after.access::<&String>(&database));
38    /* ANCHOR_END: main */
39
40    Ok(())
41}
42
43/* ANCHOR: async_save_file */
44async fn tokio_save_file(path: AssetPathStatic, bytes: Vec<u8>) -> Result<(), Box<dyn Error>> {
45    let file_path = PathBuf::from("resources").join(path.path());
46
47    tokio::fs::create_dir_all(file_path.parent().unwrap()).await?;
48    tokio::fs::write(&file_path, bytes).await?;
49
50    Ok(())
51}
52/* ANCHOR_END: async_save_file */