1use serde::{de, ser};
2use std::{convert::Infallible, error, fmt, io, result, sync::Arc};
3
4use crate::Signature;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum MaxDepthExceeded {
9 Structure,
11 Array,
13 Container,
15}
16
17impl fmt::Display for MaxDepthExceeded {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 match self {
20 Self::Structure => write!(
21 f,
22 "Maximum allowed depth for structures in encoding was exceeded"
23 ),
24 Self::Array => write!(
25 f,
26 "Maximum allowed depth for arrays in encoding was exceeded"
27 ),
28 Self::Container => write!(
29 f,
30 "Maximum allowed depth for containers in encoding was exceeded"
31 ),
32 }
33 }
34}
35
36#[derive(Debug)]
38#[non_exhaustive]
39pub enum Error {
40 Message(String),
42
43 InputOutput(Arc<io::Error>),
45 IncorrectType,
47 Utf8(std::str::Utf8Error),
49 PaddingNot0(u8),
51 UnknownFd,
53 MissingFramingOffset,
55 IncompatibleFormat(Signature, crate::serialized::Format),
57 SignatureMismatch(Signature, String),
60 OutOfBounds,
62 MaxDepthExceeded(MaxDepthExceeded),
64 SignatureParse(crate::signature::Error),
66 EmptyStructure,
68 InvalidObjectPath,
70}
71
72impl PartialEq for Error {
73 fn eq(&self, other: &Self) -> bool {
74 match (self, other) {
75 (Error::Message(msg), Error::Message(other)) => msg == other,
76 (Error::IncorrectType, Error::IncorrectType) => true,
78 (Error::Utf8(msg), Error::Utf8(other)) => msg == other,
79 (Error::PaddingNot0(p), Error::PaddingNot0(other)) => p == other,
80 (Error::UnknownFd, Error::UnknownFd) => true,
81 (Error::MaxDepthExceeded(max1), Error::MaxDepthExceeded(max2)) => max1 == max2,
82 (Error::MissingFramingOffset, Error::MissingFramingOffset) => true,
83 (
84 Error::IncompatibleFormat(sig1, format1),
85 Error::IncompatibleFormat(sig2, format2),
86 ) => sig1 == sig2 && format1 == format2,
87 (
88 Error::SignatureMismatch(provided1, expected1),
89 Error::SignatureMismatch(provided2, expected2),
90 ) => provided1 == provided2 && expected1 == expected2,
91 (Error::OutOfBounds, Error::OutOfBounds) => true,
92 (Error::SignatureParse(e1), Error::SignatureParse(e2)) => e1 == e2,
93 (Error::EmptyStructure, Error::EmptyStructure) => true,
94 (Error::InvalidObjectPath, Error::InvalidObjectPath) => true,
95 (_, _) => false,
96 }
97 }
98}
99
100impl error::Error for Error {
101 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
102 match self {
103 Error::InputOutput(e) => Some(e),
104 Error::Utf8(e) => Some(e),
105 _ => None,
106 }
107 }
108}
109
110impl fmt::Display for Error {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 match self {
113 Error::Message(s) => write!(f, "{s}"),
114 Error::InputOutput(e) => e.fmt(f),
115 Error::IncorrectType => write!(f, "incorrect type"),
116 Error::Utf8(e) => write!(f, "{e}"),
117 Error::PaddingNot0(b) => write!(f, "Unexpected non-0 padding byte `{b}`"),
118 Error::UnknownFd => write!(f, "File descriptor not in the given FD index"),
119 Error::MissingFramingOffset => write!(
120 f,
121 "Missing framing offset at the end of GVariant-encoded container"
122 ),
123 Error::IncompatibleFormat(sig, format) => {
124 write!(f, "Type `{sig}` is not compatible with `{format}` format",)
125 }
126 Error::SignatureMismatch(provided, expected) => write!(
127 f,
128 "Signature mismatch: got `{provided}`, expected {expected}",
129 ),
130 Error::OutOfBounds => write!(
131 f,
132 "Out of bounds range specified",
134 ),
135 Error::MaxDepthExceeded(max) => write!(f, "{max}"),
136 Error::SignatureParse(e) => write!(f, "{e}"),
137 Error::EmptyStructure => write!(f, "Attempted to create an empty structure"),
138 Error::InvalidObjectPath => write!(f, "Invalid object path"),
139 }
140 }
141}
142
143impl Clone for Error {
144 fn clone(&self) -> Self {
145 match self {
146 Error::Message(s) => Error::Message(s.clone()),
147 Error::InputOutput(e) => Error::InputOutput(e.clone()),
148 Error::IncorrectType => Error::IncorrectType,
149 Error::Utf8(e) => Error::Utf8(*e),
150 Error::PaddingNot0(b) => Error::PaddingNot0(*b),
151 Error::UnknownFd => Error::UnknownFd,
152 Error::MissingFramingOffset => Error::MissingFramingOffset,
153 Error::IncompatibleFormat(sig, format) => {
154 Error::IncompatibleFormat(sig.clone(), *format)
155 }
156 Error::SignatureMismatch(provided, expected) => {
157 Error::SignatureMismatch(provided.clone(), expected.clone())
158 }
159 Error::OutOfBounds => Error::OutOfBounds,
160 Error::MaxDepthExceeded(max) => Error::MaxDepthExceeded(*max),
161 Error::SignatureParse(e) => Error::SignatureParse(*e),
162 Error::EmptyStructure => Error::EmptyStructure,
163 Error::InvalidObjectPath => Error::InvalidObjectPath,
164 }
165 }
166}
167
168impl From<Infallible> for Error {
169 fn from(i: Infallible) -> Self {
170 match i {}
171 }
172}
173
174impl de::Error for Error {
175 fn custom<T>(msg: T) -> Error
178 where
179 T: fmt::Display,
180 {
181 Error::Message(msg.to_string())
182 }
183}
184
185impl ser::Error for Error {
186 fn custom<T>(msg: T) -> Error
187 where
188 T: fmt::Display,
189 {
190 Error::Message(msg.to_string())
191 }
192}
193
194impl From<io::Error> for Error {
195 fn from(val: io::Error) -> Self {
196 Error::InputOutput(Arc::new(val))
197 }
198}
199
200pub type Result<T> = result::Result<T, Error>;