bevy_mod_stylebuilder 0.1.3

A set of fluent builder utilities for Bevy UI styles.
Documentation
use bevy::{
    asset::{AssetLoader, AsyncReadExt},
    math::{Rect, Vec2},
    sprite::{TextureAtlas, TextureAtlasLayout},
};
use serde::{Deserialize, Serialize};

pub struct TextureAtlasLoader;

#[derive(Debug, Deserialize, Serialize)]
struct TextureAtlasSer {
    texture: String,
    size: Vec2,
    textures: Vec<Rect>,
}

#[derive(Debug, Deserialize, Serialize)]
struct TextureAtlasGridSer {
    texture: String,
    tile_size: Vec2,
    columns: usize,
    rows: usize,
    padding: Option<Vec2>,
    offset: Option<Vec2>,
}

impl AssetLoader for TextureAtlasLoader {
    type Asset = TextureAtlasLayout;
    type Settings = ();
    type Error = anyhow::Error;

    fn load<'a>(
        &'a self,
        reader: &'a mut bevy::asset::io::Reader,
        _settings: &'a Self::Settings,
        load_context: &'a mut bevy::asset::LoadContext,
    ) -> bevy::utils::BoxedFuture<'a, Result<Self::Asset, Self::Error>> {
        if let Some(ext) = load_context.asset_path().get_full_extension() {
            if ext == "atlas.grid.ron" {
                return Box::pin(async move {
                    let mut bytes = Vec::new();
                    reader.read_to_end(&mut bytes).await?;
                    let atlas_ser: TextureAtlasGridSer =
                        ron::de::from_str(&String::from_utf8(bytes)?)?;
                    let texture_path = load_context
                        .asset_path()
                        .resolve_embed(&atlas_ser.texture)?;
                    let texture = load_context.load(&texture_path);
                    let result = TextureAtlas::from_grid(
                        texture,
                        atlas_ser.tile_size,
                        atlas_ser.columns,
                        atlas_ser.rows,
                        atlas_ser.padding,
                        atlas_ser.offset,
                    );
                    Ok(result)
                });
            }
        }

        Box::pin(async move {
            let mut bytes = Vec::new();
            reader.read_to_end(&mut bytes).await?;
            let atlas_ser: TextureAtlasSer = ron::de::from_str(&String::from_utf8(bytes)?)?;
            let texture_path = load_context
                .asset_path()
                .resolve_embed(&atlas_ser.texture)?;
            let texture = load_context.load(&texture_path);
            let mut result = TextureAtlas::new_empty(texture, atlas_ser.size);
            for texture in atlas_ser.textures.iter() {
                result.add_texture(*texture);
            }
            Ok(result)
        })
    }

    fn extensions(&self) -> &[&str] {
        &["atlas.ron", "atlas.grid.ron"]
    }
}