Skip to main content

tokio_dbus/
error.rs

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
16/// Result alias using an [`Error`] as the error type by default.
17pub type Result<T, E = Error> = core::result::Result<T, E>;
18
19/// An error raised by this crate.
20#[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    /// Test if the error indicates that the operation would block.
32    #[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}