Skip to content
Snippets Groups Projects
loader.rs 2.8 KiB
Newer Older
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 {}

Louis's avatar
Louis committed
#[cfg(feature = "json_loader")]
mod json_loader {
	use bevy::asset::io::Reader;
Louis's avatar
Louis committed
	use bevy::asset::{AssetLoader, AsyncReadExt, LoadContext};
Louis's avatar
Louis committed

	use crate::definitions::AnimationSet;
	use crate::loader::LoaderError;

	pub struct AnimationLoader;
	impl AssetLoader for AnimationLoader {
		type Asset = AnimationSet;
		type Settings = ();
		type Error = LoaderError;
Louis's avatar
Louis committed

Louis's avatar
Louis committed
		async fn load<'a>(
Louis's avatar
Louis committed
			&'a self,
Louis's avatar
Louis committed
			reader: &'a mut Reader<'_>,
			_settings: &'a Self::Settings,
Louis's avatar
Louis committed
			_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)
Louis's avatar
Louis committed
		}

		fn extensions(&self) -> &[&str] {
			static EXTENSIONS: &[&str] = &["anim.json"];
			EXTENSIONS
		}
	}
}

#[cfg(feature = "toml_loader")]
mod toml_loader {
	use bevy::asset::io::Reader;
Louis's avatar
Louis committed
	use bevy::asset::{AssetLoader, AsyncReadExt, LoadContext};
Louis's avatar
Louis committed

	use crate::definitions::AnimationSet;
	use crate::loader::LoaderError;

	pub struct AnimationLoader;
	impl AssetLoader for AnimationLoader {
		type Asset = AnimationSet;
		type Settings = ();
		type Error = LoaderError;
Louis's avatar
Louis committed

Louis's avatar
Louis committed
		async fn load<'a>(
Louis's avatar
Louis committed
			&'a self,
Louis's avatar
Louis committed
			reader: &'a mut Reader<'_>,
			_settings: &'a Self::Settings,
Louis's avatar
Louis committed
			_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)
Louis's avatar
Louis committed
		}

		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;