1use std::io::ErrorKind;
2
3#[derive(Debug)]
4pub enum Errors {
5 InvalidField(String),
6 InvalidEnum(String),
7 InvalidPacket(String),
8 IOError(std::io::Error),
9 EncryptionError(openssl::error::ErrorStack),
10 CompressionError(std::io::Error),
11 UTF8Error(std::string::FromUtf8Error),
12 NbtStringDecodeError(cesu8::Cesu8DecodingError),
13}
14pub type Result<T> = core::result::Result<T, Errors>;
15impl From<cesu8::Cesu8DecodingError> for Errors {
16 fn from(err: cesu8::Cesu8DecodingError) -> Self {
17 Self::NbtStringDecodeError(err)
18 }
19}
20impl From<std::string::FromUtf8Error> for Errors {
21 fn from(err: std::string::FromUtf8Error) -> Self {
22 Self::UTF8Error(err)
23 }
24}
25impl From<std::io::Error> for Errors {
26 fn from(value: std::io::Error) -> Self {
27 match value.kind() {
28 ErrorKind::InvalidInput => Errors::CompressionError(value),
29 _ => Errors::IOError(value),
30 }
31 }
32}
33impl From<openssl::error::ErrorStack> for Errors {
34 fn from(err: openssl::error::ErrorStack) -> Self {
35 Self::EncryptionError(err)
36 }
37}
38impl std::error::Error for Errors {
39 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
40 match self {
41 Self::IOError(err) => Some(err),
42 Self::NbtStringDecodeError(err) => Some(err),
43 Self::UTF8Error(err) => Some(err),
44 Self::CompressionError(err) => Some(err),
45 Self::EncryptionError(err) => Some(err),
46 _ => None,
47 }
48 }
49 fn description(&self) -> &str {
50 match self {
51 Errors::InvalidField(_) => "The field was invalid",
52 Errors::InvalidEnum(_) => "There was an error decoding an enum variant",
53 Errors::InvalidPacket(_) => "The packet was invalid",
54 Errors::IOError(_) => "There was an error with the IO",
55 Errors::EncryptionError(_) => "There was an error encrypting/decrypting data",
56 Errors::CompressionError(_) => "There was an error (de)compressing data",
57 Errors::UTF8Error(_) => "Some received String wasn't valid UTF-8",
58 Errors::NbtStringDecodeError(_) => "Some received NBT string wasn't valid \"modified UTF-8\" (see Java)",
59 }
60 }
61}
62impl std::fmt::Display for Errors {
63 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
64 write!(f, "{}", match self {
65 Errors::InvalidField(msg) => format!("Invalid field: {}", msg),
66 Errors::InvalidEnum(msg) => format!("Invalid enum: {}", msg),
67 Errors::InvalidPacket(msg) => format!("Invalid packet: {}", msg),
68 Errors::IOError(e) => format!("IO Error: {}", e),
69 Errors::EncryptionError(e) => format!("Encryption error: {}", e),
70 Errors::CompressionError(e) => format!("Compression error: {}", e),
71 Errors::UTF8Error(e) => format!("UTF8 error: {}", e),
72 Errors::NbtStringDecodeError(e) => format!("NbtStringDecode error: {}", e),
73 })
74 }
75}