1use std::fmt;
2
3use crate::jid::JidError;
4
5#[derive(Debug)]
6pub enum BinaryError {
7 Io(std::io::Error),
8 InvalidToken(u8),
9 InvalidNode,
10 NonStringKey,
11 AttrParse(String),
12 MissingAttr(String),
13 InvalidUtf8(std::str::Utf8Error),
14 Zlib(String),
15 Jid(JidError),
16 UnexpectedEof,
17 EmptyData,
18 LeftoverData(usize),
19 AttrList(Vec<BinaryError>),
20}
21
22impl fmt::Display for BinaryError {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 match self {
25 BinaryError::Io(e) => write!(f, "I/O error: {e}"),
26 BinaryError::InvalidToken(t) => write!(f, "Invalid token read from stream: {t}"),
27 BinaryError::InvalidNode => write!(f, "Invalid node format"),
28 BinaryError::NonStringKey => write!(f, "Attribute key was not a string"),
29 BinaryError::AttrParse(s) => write!(f, "Attribute parsing failed: {s}"),
30 BinaryError::MissingAttr(s) => write!(f, "Missing required attribute: {s}"),
31 BinaryError::InvalidUtf8(e) => write!(f, "Data is not valid UTF-8: {e}"),
32 BinaryError::Zlib(s) => write!(f, "Zlib decompression error: {s}"),
33 BinaryError::Jid(e) => write!(f, "JID parsing error: {e}"),
34 BinaryError::UnexpectedEof => write!(f, "Unexpected end of binary data"),
35 BinaryError::EmptyData => write!(f, "Received empty data where payload was expected"),
36 BinaryError::LeftoverData(n) => write!(f, "Leftover data after decoding: {n} bytes"),
37 BinaryError::AttrList(list) => write!(f, "Multiple attribute parsing errors: {list:?}"),
38 }
39 }
40}
41
42impl std::error::Error for BinaryError {
43 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
44 match self {
45 BinaryError::Io(e) => Some(e),
46 BinaryError::InvalidUtf8(e) => Some(e),
47 BinaryError::Jid(e) => Some(e),
48 _ => None,
49 }
50 }
51}
52
53impl From<std::io::Error> for BinaryError {
54 fn from(err: std::io::Error) -> Self {
55 BinaryError::Io(err)
56 }
57}
58impl From<std::str::Utf8Error> for BinaryError {
59 fn from(err: std::str::Utf8Error) -> Self {
60 BinaryError::InvalidUtf8(err)
61 }
62}
63impl From<JidError> for BinaryError {
64 fn from(err: JidError) -> Self {
65 BinaryError::Jid(err)
66 }
67}
68impl Clone for BinaryError {
69 fn clone(&self) -> Self {
70 match self {
71 BinaryError::Io(e) => BinaryError::Io(std::io::Error::new(e.kind(), e.to_string())),
72 BinaryError::InvalidToken(u) => BinaryError::InvalidToken(*u),
73 BinaryError::InvalidNode => BinaryError::InvalidNode,
74 BinaryError::NonStringKey => BinaryError::NonStringKey,
75 BinaryError::AttrParse(s) => BinaryError::AttrParse(s.clone()),
76 BinaryError::MissingAttr(s) => BinaryError::MissingAttr(s.clone()),
77 BinaryError::InvalidUtf8(e) => BinaryError::InvalidUtf8(*e),
78 BinaryError::Zlib(s) => BinaryError::Zlib(s.clone()),
79 BinaryError::Jid(e) => BinaryError::Jid(JidError::InvalidFormat(e.to_string())),
80 BinaryError::UnexpectedEof => BinaryError::UnexpectedEof,
81 BinaryError::EmptyData => BinaryError::EmptyData,
82 BinaryError::LeftoverData(n) => BinaryError::LeftoverData(*n),
83 BinaryError::AttrList(list) => BinaryError::AttrList(list.clone()),
84 }
85 }
86}
87
88pub type Result<T> = std::result::Result<T, BinaryError>;