extern crate byteorder;
use std::io;
use std::string;
use std::str;
use std::fmt;
use std::error;
pub type Result<T> = ::std::result::Result<T, Error>;
#[derive(Debug, Clone)]
pub struct Error {
pos: u64,
kind: ErrorKind,
}
impl Error {
pub fn new<K: Into<ErrorKind>>(pos: u64, kind: K) -> Self {
Error {
pos: pos,
kind: kind.into(),
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.kind {
ErrorKind::Utf8Error(ref err) => write!(f, "UTF-8 conversion error at pos={}: {}", self.pos, err),
ErrorKind::InvalidMagic => write!(f, "Invalid magic header at pos={}: Non-FBX or corrupted data?", self.pos),
ErrorKind::Io(ref err) => write!(f, "I/O error at pos={}: {}", self.pos, err),
ErrorKind::DataError(ref err) => write!(f, "Invalid data at pos={}: {}", self.pos, err),
ErrorKind::UnexpectedValue(ref err) => write!(f, "Got an unexpected value at pos={}: {}", self.pos, err),
ErrorKind::UnexpectedEof => write!(f, "Unexpected EOF at pos={}", self.pos),
ErrorKind::Unimplemented(ref err) => write!(f, "Unimplemented feature: {}", err),
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
match self.kind {
ErrorKind::Utf8Error(ref err) => err.description(),
ErrorKind::InvalidMagic => "Got an invalid magic header",
ErrorKind::Io(ref err) => err.description(),
ErrorKind::DataError(_) => "Got an invalid data",
ErrorKind::UnexpectedValue(_) => "Invalid value in FBX data",
ErrorKind::UnexpectedEof => "Unexpected EOF",
ErrorKind::Unimplemented(_) => "Attempt to use unimplemented feature",
}
}
fn cause(&self) -> Option<&error::Error> {
match self.kind {
ErrorKind::Utf8Error(ref err) => Some(err as &error::Error),
ErrorKind::Io(ref err) => Some(err as &error::Error),
_ => None,
}
}
}
#[derive(Debug)]
pub enum ErrorKind {
Utf8Error(str::Utf8Error),
InvalidMagic,
Io(io::Error),
DataError(String),
UnexpectedValue(String),
UnexpectedEof,
Unimplemented(String),
}
impl Clone for ErrorKind {
fn clone(&self) -> Self {
use self::ErrorKind::*;
use std::error::Error;
match *self {
Utf8Error(ref e) => Utf8Error(e.clone()),
InvalidMagic => InvalidMagic,
Io(ref e) => Io(io::Error::new(e.kind(), e.description())),
DataError(ref e) => DataError(e.clone()),
UnexpectedValue(ref e) => UnexpectedValue(e.clone()),
UnexpectedEof => UnexpectedEof,
Unimplemented(ref e) => Unimplemented(e.clone()),
}
}
}
impl From<string::FromUtf8Error> for ErrorKind {
fn from(err: string::FromUtf8Error) -> ErrorKind {
ErrorKind::Utf8Error(err.utf8_error())
}
}
impl From<io::Error> for ErrorKind {
fn from(err: io::Error) -> ErrorKind {
ErrorKind::Io(err)
}
}
impl From<byteorder::Error> for ErrorKind {
fn from(err: byteorder::Error) -> ErrorKind {
match err {
byteorder::Error::UnexpectedEOF => ErrorKind::UnexpectedEof,
byteorder::Error::Io(err) => ErrorKind::Io(err),
}
}
}