1use serde::{de, ser};
2use static_assertions::assert_impl_all;
3use std::{convert::Infallible, error, fmt, result, sync::Arc};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum MaxDepthExceeded {
8 Structure,
10 Array,
12 Container,
14}
15
16impl fmt::Display for MaxDepthExceeded {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 match self {
19 Self::Structure => write!(
20 f,
21 "Maximum allowed depth for structures in encoding was exceeded"
22 ),
23 Self::Array => write!(
24 f,
25 "Maximum allowed depth for arrays in encoding was exceeded"
26 ),
27 Self::Container => write!(
28 f,
29 "Maximum allowed depth for containers in encoding was exceeded"
30 ),
31 }
32 }
33}
34
35#[derive(Debug)]
37#[non_exhaustive]
38pub enum Error {
39 Message(String),
41
42 #[deprecated(note = "Use `Error::InputOutput` instead")]
44 Io(std::io::Error),
45 InputOutput(Arc<std::io::Error>),
47 IncorrectType,
49 Utf8(std::str::Utf8Error),
51 PaddingNot0(u8),
53 UnknownFd,
55 MissingFramingOffset,
57 IncompatibleFormat(crate::Signature<'static>, crate::EncodingFormat),
59 SignatureMismatch(crate::Signature<'static>, String),
62 OutOfBounds,
64 MaxDepthExceeded(MaxDepthExceeded),
66}
67
68assert_impl_all!(Error: Send, Sync, Unpin);
69
70impl PartialEq for Error {
71 fn eq(&self, other: &Self) -> bool {
72 match (self, other) {
73 (Error::Message(msg), Error::Message(other)) => msg == other,
74 (Error::IncorrectType, Error::IncorrectType) => true,
76 (Error::Utf8(msg), Error::Utf8(other)) => msg == other,
77 (Error::PaddingNot0(p), Error::PaddingNot0(other)) => p == other,
78 (Error::UnknownFd, Error::UnknownFd) => true,
79 (Error::MaxDepthExceeded(max1), Error::MaxDepthExceeded(max2)) => max1 == max2,
80 (_, _) => false,
81 }
82 }
83}
84
85impl error::Error for Error {
86 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
87 match self {
88 #[allow(deprecated)]
89 Error::Io(e) => Some(e),
90 Error::InputOutput(e) => Some(e),
91 Error::Utf8(e) => Some(e),
92 _ => None,
93 }
94 }
95}
96
97impl fmt::Display for Error {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 match self {
100 Error::Message(s) => write!(f, "{s}"),
101 #[allow(deprecated)]
102 Error::Io(e) => e.fmt(f),
103 Error::InputOutput(e) => e.fmt(f),
104 Error::IncorrectType => write!(f, "incorrect type"),
105 Error::Utf8(e) => write!(f, "{e}"),
106 Error::PaddingNot0(b) => write!(f, "Unexpected non-0 padding byte `{b}`"),
107 Error::UnknownFd => write!(f, "File descriptor not in the given FD index"),
108 Error::MissingFramingOffset => write!(
109 f,
110 "Missing framing offset at the end of GVariant-encoded container"
111 ),
112 Error::IncompatibleFormat(sig, format) => {
113 write!(f, "Type `{sig}` is not compatible with `{format}` format",)
114 }
115 Error::SignatureMismatch(provided, expected) => write!(
116 f,
117 "Signature mismatch: got `{provided}`, expected {expected}",
118 ),
119 Error::OutOfBounds => write!(
120 f,
121 "Out of bounds range specified",
123 ),
124 Error::MaxDepthExceeded(max) => write!(f, "{max}"),
125 }
126 }
127}
128
129impl Clone for Error {
130 fn clone(&self) -> Self {
131 match self {
132 Error::Message(s) => Error::Message(s.clone()),
133 #[allow(deprecated)]
134 Error::Io(e) => Error::Message(e.to_string()),
135 Error::InputOutput(e) => Error::InputOutput(e.clone()),
136 Error::IncorrectType => Error::IncorrectType,
137 Error::Utf8(e) => Error::Utf8(*e),
138 Error::PaddingNot0(b) => Error::PaddingNot0(*b),
139 Error::UnknownFd => Error::UnknownFd,
140 Error::MissingFramingOffset => Error::MissingFramingOffset,
141 Error::IncompatibleFormat(sig, format) => {
142 Error::IncompatibleFormat(sig.clone(), *format)
143 }
144 Error::SignatureMismatch(provided, expected) => {
145 Error::SignatureMismatch(provided.clone(), expected.clone())
146 }
147 Error::OutOfBounds => Error::OutOfBounds,
148 Error::MaxDepthExceeded(max) => Error::MaxDepthExceeded(*max),
149 }
150 }
151}
152
153impl From<Infallible> for Error {
154 fn from(i: Infallible) -> Self {
155 match i {}
156 }
157}
158
159impl de::Error for Error {
160 fn custom<T>(msg: T) -> Error
163 where
164 T: fmt::Display,
165 {
166 Error::Message(msg.to_string())
167 }
168}
169
170impl ser::Error for Error {
171 fn custom<T>(msg: T) -> Error
172 where
173 T: fmt::Display,
174 {
175 Error::Message(msg.to_string())
176 }
177}
178
179pub type Result<T> = result::Result<T, Error>;