bevy_basisu_saver 0.4.0

A bevy asset processor to transform images to basisu ktx2 textures
Documentation
use bevy::{
    asset::{AsyncWriteExt, saver::AssetSaver},
    image::Image,
    reflect::TypePath,
};
use bevy_basisu_loader::{BasisuLoader, BasisuLoaderSettings};
use serde::{Deserialize, Serialize};
use thiserror::Error;

use basisu_c_sys::extra::{BasisuEncodeError, BasisuEncoder, BasisuEncoderParams};

#[derive(TypePath)]
pub struct BasisuTextureSaver;

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct BasisuTextureSaverSettings {
    pub params: BasisuEncoderParams,
}

impl Default for BasisuTextureSaverSettings {
    fn default() -> Self {
        Self {
            params: BasisuEncoderParams::new_with_srgb_defaults(
                basisu_c_sys::BasisTextureFormat::XuastcLdr4x4,
            ),
        }
    }
}

#[derive(Debug, Error)]
#[non_exhaustive]
pub enum BasisuTextureSaverError {
    #[error(transparent)]
    Io(#[from] std::io::Error),
    #[error(transparent)]
    BasisuEncodeError(#[from] BasisuEncodeError),
}

impl AssetSaver for BasisuTextureSaver {
    type Asset = Image;
    type Settings = BasisuTextureSaverSettings;
    type OutputLoader = BasisuLoader;
    type Error = BasisuTextureSaverError;

    async fn save(
        &self,
        writer: &mut bevy::asset::io::Writer,
        asset: bevy::asset::saver::SavedAsset<'_, Self::Asset>,
        settings: &Self::Settings,
    ) -> Result<<Self::OutputLoader as bevy::asset::AssetLoader>::Settings, Self::Error> {
        let mut encoder = BasisuEncoder::new();
        encoder.set_image(basisu_c_sys::extra::SourceImage {
            data: asset.data.as_deref().unwrap_or(&[]),
            texture_descriptor: &asset.texture_descriptor,
            texture_view_descriptor: &asset.texture_view_descriptor,
        })?;
        let result = encoder.compress(settings.params)?;
        writer.write_all(&result).await?;

        Ok(BasisuLoaderSettings {
            asset_usage: asset.asset_usage,
            sampler: asset.sampler.clone(),
            ..Default::default()
        })
    }
}