use std::convert::From;
use std::error::Error;
use std::fmt;
use std::io;
use std::num::{ParseFloatError, ParseIntError};
pub type ObjResult<T> = Result<T, ObjError>;
#[derive(Debug)]
pub enum ObjError {
Io(io::Error),
ParseInt(ParseIntError),
ParseFloat(ParseFloatError),
Load(LoadError),
}
macro_rules! implmnt {
($name:ident, $error:path) => {
impl From<$error> for ObjError {
fn from(err: $error) -> Self {
ObjError::$name(err)
}
}
};
}
impl fmt::Display for ObjError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ObjError::Io(ref e) => e.fmt(f),
ObjError::ParseInt(ref e) => e.fmt(f),
ObjError::ParseFloat(ref e) => e.fmt(f),
ObjError::Load(ref e) => e.fmt(f),
}
}
}
impl Error for ObjError {
fn cause(&self) -> Option<&dyn Error> {
match *self {
ObjError::Io(ref err) => Some(err),
ObjError::ParseInt(ref err) => Some(err),
ObjError::ParseFloat(ref err) => Some(err),
ObjError::Load(ref err) => Some(err),
}
}
}
implmnt!(Io, io::Error);
implmnt!(ParseInt, ParseIntError);
implmnt!(ParseFloat, ParseFloatError);
implmnt!(Load, LoadError);
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct LoadError {
kind: LoadErrorKind,
message: &'static str,
}
impl LoadError {
pub fn kind(&self) -> &LoadErrorKind {
&self.kind
}
}
#[derive(Copy, PartialEq, Eq, Clone, Debug)]
pub enum LoadErrorKind {
UnexpectedStatement,
WrongNumberOfArguments,
WrongTypeOfArguments,
UntriangulatedModel,
InsufficientData,
IndexOutOfRange,
}
impl LoadError {
pub fn new(kind: LoadErrorKind, message: &'static str) -> Self {
LoadError { kind, message }
}
}
impl Error for LoadError {}
impl fmt::Display for LoadError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use LoadErrorKind::*;
let msg = match self.kind {
UnexpectedStatement => "Met unexpected statement",
WrongNumberOfArguments => "Received wrong number of arguments",
WrongTypeOfArguments => "Received unexpected type of arguments",
UntriangulatedModel => "Model should be triangulated first to be loaded properly",
InsufficientData => "Model cannot be transformed into requested form",
IndexOutOfRange => "Received index value out of range",
};
write!(fmt, "{}: {}", msg, self.message)
}
}
macro_rules! make_error {
($kind:ident, $message:expr) => {
return Err(::std::convert::From::from($crate::error::LoadError::new(
$crate::error::LoadErrorKind::$kind,
$message,
)));
};
}