use std::error::Error as StdError;
use std::fmt;
use std::io;
use std::io::ErrorKind::InvalidInput;
use std::result::Result as StdResult;
#[cfg(feature = "serde")]
use serde;
pub type Result<T> = StdResult<T, Error>;
#[derive(Debug)]
pub enum Error {
IoError(io::Error),
#[cfg(feature = "serde")]
Serde(String),
InvalidTypeId(u8),
HeterogeneousList,
NoRootCompound,
InvalidUtf8,
IncompleteNbtValue,
TagMismatch(u8, u8),
UnexpectedField(String),
NonBooleanByte(i8),
UnrepresentableType(&'static str),
NonStringMapKey,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Error::IoError(ref e) => e.fmt(f),
#[cfg(feature = "serde")]
&Error::Serde(ref msg) => write!(f, "{}", msg),
&Error::InvalidTypeId(t) => write!(f, "invalid NBT tag byte: '{}'", t),
Error::HeterogeneousList => write!(f, "values in NBT Lists must be homogeneous"),
Error::NoRootCompound => write!(f, "the root value must be Compound-like (tag = 0x0a)"),
Error::InvalidUtf8 => write!(f, "a string is not valid UTF-8"),
Error::IncompleteNbtValue => write!(f, "data does not represent a complete NbtValue"),
&Error::TagMismatch(a, b) => {
write!(f, "encountered NBT tag '{}' but expected '{}'", a, b)
}
&Error::NonBooleanByte(b) => {
write!(f, "encountered a byte value '{}' inside a boolean", b)
}
&Error::UnexpectedField(ref name) => {
write!(f, "encountered an unexpected field '{}'", name)
}
&Error::UnrepresentableType(ref name) => write!(
f,
"encountered type '{}', which has no meaningful NBT representation",
name
),
Error::NonStringMapKey => write!(f, "encountered a non-string map key"),
}
}
}
impl StdError for Error {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match *self {
Error::IoError(ref e) => e.source(),
_ => None,
}
}
}
impl PartialEq<Error> for Error {
fn eq(&self, other: &Error) -> bool {
use Error::{
HeterogeneousList, IncompleteNbtValue, InvalidTypeId, InvalidUtf8, IoError,
NoRootCompound, NonBooleanByte, TagMismatch, UnexpectedField, UnrepresentableType,
};
match (self, other) {
(&IoError(_), &IoError(_)) => true,
#[cfg(feature = "serde")]
(&Error::Serde(_), &Error::Serde(_)) => true,
(&InvalidTypeId(a), &InvalidTypeId(b)) => a == b,
(&HeterogeneousList, &HeterogeneousList) => true,
(&NoRootCompound, &NoRootCompound) => true,
(&InvalidUtf8, &InvalidUtf8) => true,
(&IncompleteNbtValue, &IncompleteNbtValue) => true,
(&TagMismatch(a, b), &TagMismatch(c, d)) => a == c && b == d,
(&UnexpectedField(ref a), &UnexpectedField(ref b)) => a == b,
(&NonBooleanByte(a), &NonBooleanByte(b)) => a == b,
(&UnrepresentableType(ref a), &UnrepresentableType(ref b)) => a == b,
_ => false,
}
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
use std::io::ErrorKind;
if e.kind() == ErrorKind::UnexpectedEof {
return Error::IncompleteNbtValue;
}
Error::IoError(e)
}
}
impl From<cesu8::Cesu8DecodingError> for Error {
fn from(_: cesu8::Cesu8DecodingError) -> Error {
Error::InvalidUtf8
}
}
impl From<Error> for io::Error {
fn from(e: Error) -> io::Error {
match e {
Error::IoError(e) => e,
other => io::Error::new(InvalidInput, other),
}
}
}
#[cfg(feature = "serde")]
impl serde::ser::Error for Error {
fn custom<T: fmt::Display>(msg: T) -> Error {
Error::Serde(msg.to_string())
}
}
#[cfg(feature = "serde")]
impl serde::de::Error for Error {
fn custom<T: fmt::Display>(msg: T) -> Error {
Error::Serde(msg.to_string())
}
}