#![forbid(unsafe_code)] #[derive(Debug)] pub struct Error { pub message: String, } pub type Result = std::result::Result; impl std::fmt::Display for Error { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { fmt.write_str(&self.message) } } impl From for Error { fn from(e: winit::error::EventLoopError) -> Self { match e { winit::error::EventLoopError::NotSupported(e) => Self::from(e), winit::error::EventLoopError::Os(e) => Self::from(e), winit::error::EventLoopError::RecreationAttempt => Error { message: "There may only ever be a single winit event loop.".to_string() }, winit::error::EventLoopError::ExitFailure(code) => Error { message: format!("Clean unhappy exit with code {} via winit event loop", code) } } } } impl From for Error { fn from(e: winit::error::NotSupportedError) -> Self { Error { message: format!("The winit backend does not support an operation: {}", e.to_string()) } } } impl From for Error { fn from(e: winit::error::OsError) -> Self { Error { message: format!("The OS told winit about an error: {}", e.to_string()) } } } impl From for Error { fn from(e: libloading::Error) -> Self { Error { message: format!("The dynamic object loader reported an error: {}", e.to_string()) } } } impl From> for Error { fn from(e: Box) -> Self { Error { message: format!("The Vulkan loader reported an error: {}", e.to_string()) } } } impl From for Error { fn from(e: vulkanalia::vk::ErrorCode) -> Self { Error { message: format!("Vulkan gave an error code: {}", e.to_string()) } } } impl From for Error { fn from(e: vulkanalia::bytecode::BytecodeError) -> Self { Error { message: match e { vulkanalia::bytecode::BytecodeError::Alloc => "Unable to allocate buffer for SPIR-V bytecode.".to_string(), vulkanalia::bytecode::BytecodeError::Length(length) => format!("Compiled SPIR-V bytecode has length {}, \ which means it's corrupt.", length) } } } } impl From for Error { fn from(e: std::io::Error) -> Self { Error { message: format!("System I/O error: {}", e), } } } impl From for Error { fn from(e: png::DecodingError) -> Self { match e { png::DecodingError::IoError(e) => Self::from(e), png::DecodingError::Format(_) => Error { message: "Texture image is not a valid PNG.".to_string(), }, png::DecodingError::Parameter(e) => Error { message: format!("PNG library misusage: {}", e), }, png::DecodingError::LimitsExceeded => Error { message: "PNG needed too much memory to decode.".to_string(), } } } } pub fn ignore_errors(mut body: impl FnMut() -> Result<()>) -> () { if let Err(e) = body() { eprintln!("Error: {}", e); } } pub enum Acceptable { Accepted(T), Rejected(String), } impl Acceptable { #[allow(unused)] pub fn is_accepted(&self) -> bool { if let Acceptable::Accepted(_) = self { true } else { false } } #[allow(unused)] pub fn is_rejected(&self) -> bool { if let Acceptable::Rejected(_) = self { true } else { false } } #[allow(unused)] pub fn unwrap(self) -> T { if let Acceptable::Accepted(result) = self { result } else { panic!("Unwrapped a rejected Acceptable."); } } pub fn require(self) -> Result { match self { Acceptable::Accepted(value) => Ok(value), Acceptable::Rejected(message) => Err(Error { message }), } } }