use std::any::TypeId;
use std::fmt;
use std::path::PathBuf;
#[derive(Debug)]
pub enum AssetError {
NotFound {
path: String,
},
IoError {
path: PathBuf,
source: std::io::Error,
},
NoLoader {
type_id: TypeId,
type_name: Option<&'static str>,
},
NoLoaderForExtension {
extension: String,
},
LoaderError {
path: String,
message: String,
},
InvalidHandle {
reason: String,
},
TypeMismatch {
expected: &'static str,
actual: TypeId,
},
NotReady {
path: String,
},
Other {
message: String,
},
}
impl fmt::Display for AssetError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AssetError::NotFound { path } => {
write!(f, "Asset not found: {}", path)
}
AssetError::IoError { path, source } => {
write!(f, "IO error loading '{}': {}", path.display(), source)
}
AssetError::NoLoader { type_name, .. } => {
if let Some(name) = type_name {
write!(f, "No loader registered for asset type: {}", name)
} else {
write!(f, "No loader registered for asset type")
}
}
AssetError::NoLoaderForExtension { extension } => {
write!(f, "No loader registered for extension: .{}", extension)
}
AssetError::LoaderError { path, message } => {
write!(f, "Failed to load '{}': {}", path, message)
}
AssetError::InvalidHandle { reason } => {
write!(f, "Invalid asset handle: {}", reason)
}
AssetError::TypeMismatch { expected, .. } => {
write!(f, "Type mismatch: expected {}", expected)
}
AssetError::NotReady { path } => {
write!(f, "Asset not ready: {}", path)
}
AssetError::Other { message } => {
write!(f, "Asset error: {}", message)
}
}
}
}
impl std::error::Error for AssetError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
AssetError::IoError { source, .. } => Some(source),
_ => None,
}
}
}
impl From<std::io::Error> for AssetError {
fn from(err: std::io::Error) -> Self {
AssetError::IoError {
path: PathBuf::new(),
source: err,
}
}
}
pub type AssetResult<T> = Result<T, AssetError>;