use std::error::Error; use std::fmt::{Debug, Display, Formatter}; #[derive(Debug)] pub enum LoaderError { #[cfg(feature = "json_loader")] Json(serde_json::Error), #[cfg(feature = "toml_loader")] Toml(toml::de::Error), Custom(String), } impl Display for LoaderError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Self::Custom(message) => Display::fmt(message, f), #[cfg(feature = "json_loader")] Self::Json(err) => Display::fmt(err, f), #[cfg(feature = "toml_loader")] Self::Toml(err) => Display::fmt(err, f), } } } impl Error for LoaderError {} #[cfg(feature = "json_loader")] mod json_loader { use bevy::asset::io::Reader; use bevy::asset::{AssetLoader, AsyncReadExt, LoadContext}; use crate::definitions::AnimationSet; use crate::loader::LoaderError; pub struct AnimationLoader; impl AssetLoader for AnimationLoader { type Asset = AnimationSet; type Settings = (); type Error = LoaderError; async fn load<'a>( &'a self, reader: &'a mut Reader<'_>, _settings: &'a Self::Settings, _load_context: &'a mut LoadContext<'_>, ) -> Result<Self::Asset, Self::Error> { let mut bytes = Vec::new(); reader .read_to_end(&mut bytes) .await .expect("Failed to read all bytes"); serde_json::from_slice(bytes.as_slice()).map_err(LoaderError::Json) } fn extensions(&self) -> &[&str] { static EXTENSIONS: &[&str] = &["anim.json"]; EXTENSIONS } } } #[cfg(feature = "toml_loader")] mod toml_loader { use bevy::asset::io::Reader; use bevy::asset::{AssetLoader, AsyncReadExt, LoadContext}; use crate::definitions::AnimationSet; use crate::loader::LoaderError; pub struct AnimationLoader; impl AssetLoader for AnimationLoader { type Asset = AnimationSet; type Settings = (); type Error = LoaderError; async fn load<'a>( &'a self, reader: &'a mut Reader<'_>, _settings: &'a Self::Settings, _load_context: &'a mut LoadContext<'_>, ) -> Result<Self::Asset, Self::Error> { let mut bytes = String::new(); reader .read_to_string(&mut bytes) .await .expect("Failed to read all bytes"); toml::from_str(bytes.as_str()).map_err(LoaderError::Toml) } fn extensions(&self) -> &[&str] { static EXTENSIONS: &[&str] = &["anim.toml"]; EXTENSIONS } } } mod _plugin { use bevy::app::{App, Plugin}; use bevy::asset::AssetApp; pub struct AnimationLoadersPlugin; impl Plugin for AnimationLoadersPlugin { fn build(&self, app: &mut App) { #[cfg(any(feature = "json_loader", feature = "toml_loader"))] app.init_asset::<crate::definitions::AnimationSet>(); #[cfg(feature = "json_loader")] app.register_asset_loader(super::json_loader::AnimationLoader); #[cfg(feature = "toml_loader")] app.register_asset_loader(super::toml_loader::AnimationLoader); } } } pub use _plugin::AnimationLoadersPlugin;