1#[cfg(feature = "std")]
2use std::io;
3
4#[cfg(feature = "alloc")]
5use alloc::boxed::Box;
6
7use core::error;
8use core::fmt;
9use core::str::Utf8Error;
10
11#[cfg(feature = "alloc")]
12use crate::Signature;
13use crate::connection::Sasl;
14use crate::{ObjectPathError, SignatureError};
15
16pub type Result<T, E = Error> = core::result::Result<T, E>;
18
19#[derive(Debug)]
21pub struct Error {
22 kind: ErrorKind,
23}
24
25impl Error {
26 #[inline]
27 pub(crate) fn new(kind: ErrorKind) -> Error {
28 Self { kind }
29 }
30
31 #[cfg(feature = "tokio")]
33 #[inline]
34 pub(crate) fn would_block(&self) -> bool {
35 matches!(self.kind, ErrorKind::WouldBlock)
36 }
37}
38
39impl From<SignatureError> for Error {
40 #[inline]
41 fn from(error: SignatureError) -> Self {
42 Self::new(ErrorKind::Signature(error))
43 }
44}
45
46impl From<ObjectPathError> for Error {
47 #[inline]
48 fn from(error: ObjectPathError) -> Self {
49 Self::new(ErrorKind::ObjectPath(error))
50 }
51}
52
53#[cfg(feature = "std")]
54impl From<io::Error> for Error {
55 #[inline]
56 fn from(error: io::Error) -> Self {
57 match error.kind() {
58 io::ErrorKind::WouldBlock => Self::new(ErrorKind::WouldBlock),
59 _ => Self::new(ErrorKind::Io(error)),
60 }
61 }
62}
63
64impl From<Utf8Error> for Error {
65 #[inline]
66 fn from(error: Utf8Error) -> Self {
67 Self::new(ErrorKind::Utf8Error(error))
68 }
69}
70
71impl From<ErrorKind> for Error {
72 #[inline]
73 fn from(kind: ErrorKind) -> Self {
74 Self::new(kind)
75 }
76}
77
78impl fmt::Display for Error {
79 #[inline]
80 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81 match &self.kind {
82 #[cfg(feature = "std")]
83 ErrorKind::Io(..) => write!(f, "I/O error"),
84 ErrorKind::Signature(..) => write!(f, "Signature error"),
85 ErrorKind::ObjectPath(..) => write!(f, "ObjectPath error"),
86 ErrorKind::Utf8Error(..) => write!(f, "UTF-8 error"),
87 #[cfg(not(feature = "libc"))]
88 ErrorKind::UnsupportedAuthUid => {
89 write!(
90 f,
91 "Authentication using the current UID requires the `libc` feature to be enabled"
92 )
93 }
94 ErrorKind::WouldBlock => write!(f, "Would block"),
95 ErrorKind::BufferUnderflow => write!(f, "Buffer underflow"),
96 ErrorKind::MissingBus => write!(f, "Missing bus to connect to"),
97 ErrorKind::InvalidAddress => write!(f, "Invalid d-bus address"),
98 ErrorKind::InvalidSaslState(state) => write!(f, "Invalid sasl state {state}"),
99 ErrorKind::InvalidSasl => write!(f, "Invalid SASL message"),
100 ErrorKind::InvalidSaslResponse => write!(f, "Invalid SASL command"),
101 ErrorKind::InvalidProtocol => write!(f, "Invalid protocol"),
102 ErrorKind::MissingPath => write!(f, "Missing required PATH header"),
103 ErrorKind::MissingMember => write!(f, "Missing required MEMBER header"),
104 ErrorKind::MissingReplySerial => write!(f, "Missing required REPLY_SERIAL header"),
105 ErrorKind::ZeroSerial => write!(f, "Zero in header serial"),
106 ErrorKind::ZeroReplySerial => write!(f, "Zero REPLY_SERIAL header"),
107 ErrorKind::MissingErrorName => write!(f, "Missing required ERROR_NAME header"),
108 ErrorKind::NotNullTerminated => {
109 write!(f, "String is not null terminated")
110 }
111 ErrorKind::ArrayTooLong(length) => {
112 write!(f, "Array of length {length} is too long (max is 67108864)")
113 }
114 ErrorKind::BodyTooLong(length) => {
115 write!(f, "Body of length {length} is too long (max is 134217728)")
116 }
117 ErrorKind::HeaderTooLong(length) => {
118 write!(
119 f,
120 "Header of length {length} is too long (max is 134217728)"
121 )
122 }
123 ErrorKind::MissingMessage => {
124 write!(f, "No message")
125 }
126 #[cfg(feature = "alloc")]
127 ErrorKind::UnsupportedVariant(signature) => {
128 write!(f, "Unsupported variant signature {signature:?}")
129 }
130 #[cfg(not(feature = "alloc"))]
131 ErrorKind::UnsupportedVariantNoAlloc => {
132 write!(f, "Unsupported variant signature")
133 }
134 }
135 }
136}
137
138impl error::Error for Error {
139 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
140 match &self.kind {
141 #[cfg(feature = "std")]
142 ErrorKind::Io(error) => Some(error),
143 ErrorKind::Signature(error) => Some(error),
144 ErrorKind::ObjectPath(error) => Some(error),
145 ErrorKind::Utf8Error(error) => Some(error),
146 _ => None,
147 }
148 }
149}
150
151#[derive(Debug)]
152pub(crate) enum ErrorKind {
153 #[cfg(feature = "std")]
154 Io(io::Error),
155 Signature(SignatureError),
156 ObjectPath(ObjectPathError),
157 Utf8Error(Utf8Error),
158 #[cfg(not(feature = "libc"))]
159 UnsupportedAuthUid,
160 WouldBlock,
161 BufferUnderflow,
162 MissingBus,
163 InvalidAddress,
164 InvalidSaslState(Sasl),
165 InvalidSasl,
166 InvalidSaslResponse,
167 InvalidProtocol,
168 MissingPath,
169 MissingMember,
170 MissingReplySerial,
171 ZeroSerial,
172 ZeroReplySerial,
173 MissingErrorName,
174 NotNullTerminated,
175 ArrayTooLong(u32),
176 BodyTooLong(u32),
177 HeaderTooLong(u32),
178 MissingMessage,
179 #[cfg(feature = "alloc")]
180 UnsupportedVariant(Box<Signature>),
181 #[cfg(not(feature = "alloc"))]
182 UnsupportedVariantNoAlloc,
183}