bevy_assets_extensions 0.7.1

Extensions for bevy assets, with support of collection as assets and a loader manager.
Documentation
use bevy::{asset::ErasedLoadedAsset, platform::collections::HashMap, prelude::*};
use std::pin::Pin;

use super::{AssetsBundle, BundleEntry};
use crate::prelude::*;

/// Trait for supporting to load from a hash map of bundle entry
pub trait LoadAssetFrom: Asset + Sized {
    /// Load asset from an entry
    fn load_from<'a>(
        key: String,
        entry: BundleEntry,
        load_context: &'a mut bevy::asset::LoadContext<'_>,
    ) -> Pin<Box<dyn Future<Output = Result<Self, Error>> + Send + 'a>>;
}

// Implement LoadAssetFrom for specific Assets

impl LoadAssetFrom for crate::assets::Text {
    fn load_from<'a>(
        key: String,
        entry: BundleEntry,
        load_context: &'a mut bevy::asset::LoadContext<'_>,
    ) -> Pin<Box<dyn Future<Output = Result<Self, Error>> + Send + 'a>> {
        Box::pin(async move {
            match entry {
                BundleEntry::File(path) => {
                    let path = load_context.asset_path().parent().unwrap().resolve(&path)?;
                    Ok(load_context.loader().immediate().load(path).await?.take())
                }
                BundleEntry::Text(content) => Ok(Self::new(content)),
                _ => Err(Error::IncompatibleEntry { key }),
            }
        })
    }
}

#[cfg(feature = "atlas_layout")]
impl LoadAssetFrom for TextureAtlasLayout {
    fn load_from<'a>(
        key: String,
        entry: BundleEntry,
        load_context: &'a mut bevy::asset::LoadContext<'_>,
    ) -> Pin<Box<dyn Future<Output = Result<Self, Error>> + Send + 'a>> {
        Box::pin(async move {
            match entry {
                BundleEntry::File(path) => {
                    let path = load_context.asset_path().parent().unwrap().resolve(&path)?;
                    Ok(load_context.loader().immediate().load(path).await?.take())
                }
                BundleEntry::TextureAtlasLayout(layout) => Ok(layout.into()),
                _ => Err(Error::IncompatibleEntry { key }),
            }
        })
    }
}

impl LoadAssetFrom for AssetsBundle {
    fn load_from<'a>(
        key: String,
        entry: BundleEntry,
        load_context: &'a mut bevy::asset::LoadContext<'_>,
    ) -> Pin<Box<dyn Future<Output = Result<AssetsBundle, Error>> + Send + 'a>> {
        Box::pin(async move {
            match entry {
                BundleEntry::File(path) => {
                    let path = load_context.asset_path().parent().unwrap().resolve(&path)?;
                    Ok(load_context.loader().immediate().load(path).await?.take())
                }
                BundleEntry::Bundle(assets) => {
                    let mut loaded_assets: HashMap<String, ErasedLoadedAsset> = Default::default();

                    for (k, v) in assets.into_iter() {
                        let asset = v.load_asset(&k, load_context).await?;
                        loaded_assets.insert(k, asset);
                    }
                    Ok(AssetsBundle {
                        assets: loaded_assets,
                    })
                }
                _ => Err(Error::IncompatibleEntry { key }),
            }
        })
    }
}