1use std::error::Error as StdError;
2use std::fmt;
3use std::io;
4use std::io::ErrorKind::InvalidInput;
5use std::result::Result as StdResult;
6
7#[cfg(feature = "serde")]
8use serde;
9
10pub type Result<T> = StdResult<T, Error>;
13
14#[derive(Debug)]
20pub enum Error {
21 IoError(io::Error),
23 #[cfg(feature = "serde")]
25 Serde(String),
26 InvalidTypeId(u8),
29 HeterogeneousList,
31 NoRootCompound,
34 InvalidUtf8,
37 IncompleteNbtValue,
40 TagMismatch(u8, u8),
43 UnexpectedField(String),
46 NonBooleanByte(i8),
48 UnrepresentableType(&'static str),
51 NonStringMapKey,
54}
55
56impl fmt::Display for Error {
57 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58 match self {
59 &Error::IoError(ref e) => e.fmt(f),
60 #[cfg(feature = "serde")]
61 &Error::Serde(ref msg) => write!(f, "{}", msg),
62 &Error::InvalidTypeId(t) => write!(f, "invalid NBT tag byte: '{}'", t),
63 Error::HeterogeneousList => write!(f, "values in NBT Lists must be homogeneous"),
64 Error::NoRootCompound => write!(f, "the root value must be Compound-like (tag = 0x0a)"),
65 Error::InvalidUtf8 => write!(f, "a string is not valid UTF-8"),
66 Error::IncompleteNbtValue => write!(f, "data does not represent a complete NbtValue"),
67 &Error::TagMismatch(a, b) => {
68 write!(f, "encountered NBT tag '{}' but expected '{}'", a, b)
69 }
70 &Error::NonBooleanByte(b) => {
71 write!(f, "encountered a byte value '{}' inside a boolean", b)
72 }
73 &Error::UnexpectedField(ref name) => {
74 write!(f, "encountered an unexpected field '{}'", name)
75 }
76 &Error::UnrepresentableType(ref name) => write!(
77 f,
78 "encountered type '{}', which has no meaningful NBT representation",
79 name
80 ),
81 Error::NonStringMapKey => write!(f, "encountered a non-string map key"),
82 }
83 }
84}
85
86impl StdError for Error {
87 fn source(&self) -> Option<&(dyn StdError + 'static)> {
88 match *self {
89 Error::IoError(ref e) => e.source(),
90 _ => None,
91 }
92 }
93}
94
95impl PartialEq<Error> for Error {
97 fn eq(&self, other: &Error) -> bool {
98 use Error::{
99 HeterogeneousList, IncompleteNbtValue, InvalidTypeId, InvalidUtf8, IoError,
100 NoRootCompound, NonBooleanByte, TagMismatch, UnexpectedField, UnrepresentableType,
101 };
102
103 match (self, other) {
104 (&IoError(_), &IoError(_)) => true,
105 #[cfg(feature = "serde")]
106 (&Error::Serde(_), &Error::Serde(_)) => true,
107 (&InvalidTypeId(a), &InvalidTypeId(b)) => a == b,
108 (&HeterogeneousList, &HeterogeneousList) => true,
109 (&NoRootCompound, &NoRootCompound) => true,
110 (&InvalidUtf8, &InvalidUtf8) => true,
111 (&IncompleteNbtValue, &IncompleteNbtValue) => true,
112 (&TagMismatch(a, b), &TagMismatch(c, d)) => a == c && b == d,
113 (&UnexpectedField(ref a), &UnexpectedField(ref b)) => a == b,
114 (&NonBooleanByte(a), &NonBooleanByte(b)) => a == b,
115 (&UnrepresentableType(ref a), &UnrepresentableType(ref b)) => a == b,
116 _ => false,
117 }
118 }
119}
120
121impl From<io::Error> for Error {
122 fn from(e: io::Error) -> Error {
123 use std::io::ErrorKind;
124
125 if e.kind() == ErrorKind::UnexpectedEof {
126 return Error::IncompleteNbtValue;
127 }
128 Error::IoError(e)
129 }
130}
131
132impl From<cesu8::Cesu8DecodingError> for Error {
133 fn from(_: cesu8::Cesu8DecodingError) -> Error {
134 Error::InvalidUtf8
135 }
136}
137
138impl From<Error> for io::Error {
139 fn from(e: Error) -> io::Error {
140 match e {
141 Error::IoError(e) => e,
142 other => io::Error::new(InvalidInput, other),
143 }
144 }
145}
146
147#[cfg(feature = "serde")]
148impl serde::ser::Error for Error {
149 fn custom<T: fmt::Display>(msg: T) -> Error {
150 Error::Serde(msg.to_string())
151 }
152}
153
154#[cfg(feature = "serde")]
155impl serde::de::Error for Error {
156 fn custom<T: fmt::Display>(msg: T) -> Error {
157 Error::Serde(msg.to_string())
158 }
159}