use std::convert::From;
use std::error;
use std::fmt;
use std::io;
use std::num;
use std::result;
use std::str;
use std::string;
use chrono::format;
use rustc_serialize::base64;
use xml::reader;
#[derive(Debug)]
pub enum Error {
InvalidMagicBytes,
InvalidTrailer,
VersionNotSupported(Option<String>),
InvalidKeyObject,
InvalidBoolean,
InvalidIntegerSize,
ObjectNotSupported(u8),
UnexpectedXmlEof,
UnexpectedXmlEvent(reader::XmlEvent),
XmlObjectNotSupported(String),
XmlError(reader::Error),
IoError(io::Error),
IntError(num::ParseIntError),
FloatError(num::ParseFloatError),
DateError(format::ParseError),
Base64Error(base64::FromBase64Error),
Utf8Error(str::Utf8Error),
Utf16Error(string::FromUtf16Error),
}
impl From<io::Error> for Error {
fn from(error: io::Error) -> Error {
Error::IoError(error)
}
}
impl From<num::ParseIntError> for Error {
fn from(error: num::ParseIntError) -> Error {
Error::IntError(error)
}
}
impl From<num::ParseFloatError> for Error {
fn from(error: num::ParseFloatError) -> Error {
Error::FloatError(error)
}
}
impl From<format::ParseError> for Error {
fn from(error: format::ParseError) -> Error {
Error::DateError(error)
}
}
impl From<base64::FromBase64Error> for Error {
fn from(error: base64::FromBase64Error) -> Error {
Error::Base64Error(error)
}
}
impl From<str::Utf8Error> for Error {
fn from(error: str::Utf8Error) -> Error {
Error::Utf8Error(error)
}
}
impl From<string::FromUtf8Error> for Error {
fn from(error: string::FromUtf8Error) -> Error {
Error::from(error.utf8_error())
}
}
impl From<string::FromUtf16Error> for Error {
fn from(error: string::FromUtf16Error) -> Error {
Error::Utf16Error(error)
}
}
impl From<reader::Error> for Error {
fn from(error: reader::Error) -> Error {
Error::XmlError(error)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::InvalidMagicBytes => write!(f, "Magic bytes are incorrect"),
Error::InvalidTrailer => write!(f, "Trailer is invalid"),
Error::VersionNotSupported(Some(ref s)) => write!(f, "Version {} not supported", s),
Error::VersionNotSupported(None) => write!(f, "Version not supported"),
Error::InvalidKeyObject => write!(f, "Key object is not a string"),
Error::InvalidBoolean => write!(f, "Boolean object has an invalid value"),
Error::InvalidIntegerSize => write!(f, "Integer size is not supported"),
Error::ObjectNotSupported(ref v) => write!(f, "Object type 0x{:X} is not supported", v),
Error::UnexpectedXmlEof => write!(f, "The XML file ends unexpectedly"),
Error::UnexpectedXmlEvent(ref e) => write!(f, "The XML event {:?} is unexpected", e),
Error::XmlObjectNotSupported(ref s) => {
write!(f, "The XML object {:} is not supported", s)
}
Error::XmlError(ref e) => e.fmt(f),
Error::IoError(ref e) => e.fmt(f),
Error::IntError(ref e) => e.fmt(f),
Error::FloatError(ref e) => e.fmt(f),
Error::DateError(ref e) => e.fmt(f),
Error::Base64Error(ref e) => e.fmt(f),
Error::Utf8Error(ref e) => e.fmt(f),
Error::Utf16Error(ref e) => e.fmt(f),
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::InvalidMagicBytes => "Magic bytes are incorrect",
Error::InvalidTrailer => "Trailer is invalid",
Error::VersionNotSupported(ref _s) => "Version not supported",
Error::InvalidKeyObject => "Key object is not a string",
Error::InvalidBoolean => "Boolean object has an invalid value",
Error::InvalidIntegerSize => "Integer size is not supported",
Error::ObjectNotSupported(ref _v) => "Object type is not supported",
Error::UnexpectedXmlEof => "The XML stream ends unexpectedly",
Error::UnexpectedXmlEvent(ref _e) => "The XML event is unexpected",
Error::XmlObjectNotSupported(ref _s) => "The XML object is not supported",
Error::XmlError(ref e) => e.description(),
Error::IoError(ref e) => e.description(),
Error::IntError(ref e) => e.description(),
Error::FloatError(ref e) => e.description(),
Error::DateError(ref e) => e.description(),
Error::Base64Error(ref e) => e.description(),
Error::Utf8Error(ref e) => e.description(),
Error::Utf16Error(ref e) => e.description(),
}
}
}
pub type Result<T> = result::Result<T, Error>;