use std::error::Error;
use std::fmt;
use std::string::FromUtf8Error;
use std::sync::Arc;
#[derive(Debug)]
pub enum GameError {
GraphicsInitializationError,
FilesystemError(String),
ConfigError(String),
EventLoopError(String),
ResourceLoadError(String),
ResourceNotFound(String, Vec<(std::path::PathBuf, GameError)>),
RenderError(String),
RequestDeviceError(wgpu::RequestDeviceError),
AudioError(String),
WindowError(String),
WindowCreationError(Arc<winit::error::OsError>),
#[allow(clippy::upper_case_acronyms)]
IOError(Arc<std::io::Error>),
FontError(glyph_brush::ab_glyph::InvalidFont),
ShaderEncodingError(FromUtf8Error),
VideoError(String),
GamepadError(String),
LyonError(String),
GlyphBrushError(glyph_brush::BrushError),
FontSelectError(String),
BufferAsyncError(wgpu::BufferAsyncError),
LockError,
CustomError(String),
}
impl fmt::Display for GameError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
GameError::ConfigError(ref s) => write!(f, "Config error: {s}"),
GameError::ResourceLoadError(ref s) => write!(f, "Error loading resource: {s}"),
GameError::ResourceNotFound(ref s, ref paths) => {
write!(f, "Resource not found: {s}, searched in paths {paths:?}")
}
GameError::WindowError(ref e) => write!(f, "Window creation error: {e}"),
GameError::CustomError(ref s) => write!(f, "Custom error: {s}"),
GameError::RequestDeviceError(ref e) => {
write!(f, "Failed to request logical device: {e}")
}
GameError::GlyphBrushError(ref e) => write!(f, "Text rendering error: {e}"),
GameError::FontSelectError(ref e) => write!(f, "No such font '{e}'"),
GameError::BufferAsyncError(ref e) => write!(f, "Async buffer map error: {e}"),
_ => write!(f, "GameError {self:?}"),
}
}
}
impl Error for GameError {
fn cause(&self) -> Option<&dyn Error> {
match *self {
GameError::RequestDeviceError(ref e) => Some(e),
GameError::WindowCreationError(ref e) => Some(&**e),
GameError::IOError(ref e) => Some(&**e),
GameError::FontError(ref e) => Some(e),
GameError::GlyphBrushError(ref e) => Some(e),
GameError::BufferAsyncError(ref e) => Some(e),
_ => None,
}
}
}
pub type GameResult<T = ()> = Result<T, GameError>;
impl From<std::io::Error> for GameError {
fn from(e: std::io::Error) -> GameError {
GameError::IOError(Arc::new(e))
}
}
impl From<toml::de::Error> for GameError {
fn from(e: toml::de::Error) -> GameError {
let errstr = format!("TOML decode error: {e}");
GameError::ConfigError(errstr)
}
}
impl From<toml::ser::Error> for GameError {
fn from(e: toml::ser::Error) -> GameError {
let errstr = format!("TOML error (possibly encoding?): {e}");
GameError::ConfigError(errstr)
}
}
impl From<zip::result::ZipError> for GameError {
fn from(e: zip::result::ZipError) -> GameError {
let errstr = format!("Zip error: {e}");
GameError::ResourceLoadError(errstr)
}
}
#[cfg(feature = "audio")]
impl From<rodio::decoder::DecoderError> for GameError {
fn from(e: rodio::decoder::DecoderError) -> GameError {
let errstr = format!("Audio decoder error: {e:?}");
GameError::AudioError(errstr)
}
}
#[cfg(feature = "audio")]
impl From<rodio::PlayError> for GameError {
fn from(e: rodio::PlayError) -> GameError {
let errstr = format!("Audio playing error: {e:?}");
GameError::AudioError(errstr)
}
}
impl From<image::ImageError> for GameError {
fn from(e: image::ImageError) -> GameError {
let errstr = format!("Image load error: {e}");
GameError::ResourceLoadError(errstr)
}
}
impl From<winit::error::OsError> for GameError {
fn from(s: winit::error::OsError) -> GameError {
GameError::WindowCreationError(Arc::new(s))
}
}
#[cfg(feature = "gamepad")]
impl From<gilrs::Error> for GameError {
fn from(s: gilrs::Error) -> GameError {
let errstr = format!("Gamepad error: {s}");
GameError::GamepadError(errstr)
}
}
impl From<lyon::lyon_tessellation::TessellationError> for GameError {
fn from(s: lyon::lyon_tessellation::TessellationError) -> GameError {
let errstr =
format!("Error while tesselating shape (did you give it an infinity or NaN?): {s:?}");
GameError::LyonError(errstr)
}
}
impl From<lyon::lyon_tessellation::geometry_builder::GeometryBuilderError> for GameError {
fn from(s: lyon::lyon_tessellation::geometry_builder::GeometryBuilderError) -> GameError {
let errstr =
format!("Error while building geometry (did you give it too many vertices?): {s:?}");
GameError::LyonError(errstr)
}
}
impl From<wgpu::RequestDeviceError> for GameError {
fn from(s: wgpu::RequestDeviceError) -> GameError {
GameError::RequestDeviceError(s)
}
}
impl From<Arc<winit::error::OsError>> for GameError {
fn from(s: Arc<winit::error::OsError>) -> GameError {
GameError::WindowCreationError(s)
}
}
impl From<Arc<std::io::Error>> for GameError {
fn from(s: Arc<std::io::Error>) -> GameError {
GameError::IOError(s)
}
}
impl From<glyph_brush::ab_glyph::InvalidFont> for GameError {
fn from(s: glyph_brush::ab_glyph::InvalidFont) -> GameError {
GameError::FontError(s)
}
}
impl From<glyph_brush::BrushError> for GameError {
fn from(s: glyph_brush::BrushError) -> GameError {
GameError::GlyphBrushError(s)
}
}
impl From<wgpu::BufferAsyncError> for GameError {
fn from(s: wgpu::BufferAsyncError) -> GameError {
GameError::BufferAsyncError(s)
}
}