dbus_async/
error.rs

1use crate::{command::Command, stream::StreamError};
2use dbus_message_parser::{
3    match_rule::MatchRule,
4    message::Message,
5    value::{Error as ErrorName, Interface, ObjectPath},
6};
7use futures::channel::{mpsc::TrySendError, oneshot::Canceled};
8use std::{
9    fmt::{Display, Formatter, Result as FmtResult},
10    io::{Error as IoError, ErrorKind as IoErrorKind},
11};
12use thiserror::Error;
13
14#[derive(Debug, Error)]
15pub enum DBusError {
16    SendMessage(Message),
17    AddMethodCall(ObjectPath),
18    DeleteMethodCall(Option<ObjectPath>),
19    ListMethodCall(ObjectPath),
20    AddMethodCallInterface(Interface),
21    DeleteMethodCallInterface(Option<Interface>),
22    AddSignal(ObjectPath),
23    DeleteSignal,
24    AddMatchRules(Vec<MatchRule>),
25    DeleteMatchRules,
26    ReceiveMessage(Option<Message>),
27    StreamError(#[from] StreamError),
28    DBusSessionBusAddress,
29    Hello(ErrorName),
30    Close,
31}
32
33impl From<TrySendError<Command>> for DBusError {
34    fn from(e: TrySendError<Command>) -> Self {
35        match e.into_inner() {
36            Command::SendMessage(msg) => DBusError::SendMessage(msg),
37            Command::SendMessageOneshot(msg, _) => DBusError::SendMessage(msg),
38            Command::SendMessageMpcs(msg, _, _) => DBusError::SendMessage(msg),
39            Command::AddMethodCall(object_path, _) => DBusError::AddMethodCall(object_path),
40            Command::DeleteMethodCall(object_path) => {
41                DBusError::DeleteMethodCall(Some(object_path))
42            }
43            Command::DeleteMethodCallSender(_) => DBusError::DeleteMethodCall(None),
44            Command::DeleteMethodCallReceiver(_) => DBusError::DeleteMethodCall(None),
45            Command::ListMethodCall(object_path, _) => DBusError::ListMethodCall(object_path),
46            Command::AddMethodCallInterface(object_path, _) => {
47                DBusError::AddMethodCallInterface(object_path)
48            }
49            Command::DeleteMethodCallInterface(interface) => {
50                DBusError::DeleteMethodCallInterface(Some(interface))
51            }
52            Command::DeleteMethodCallInterfaceSender(_) => {
53                DBusError::DeleteMethodCallInterface(None)
54            }
55            Command::DeleteMethodCallInterfaceReceiver(_) => {
56                DBusError::DeleteMethodCallInterface(None)
57            }
58            Command::AddSignal(object_path, _, _) => DBusError::AddSignal(object_path),
59            Command::DeleteSignalSender(_) => DBusError::DeleteSignal,
60            Command::DeleteSignalReceiver(_) => DBusError::DeleteSignal,
61            Command::AddMatchRules(match_rules, _) => DBusError::AddMatchRules(match_rules),
62            Command::DeleteMatchRulesSender(_) => DBusError::DeleteMatchRules,
63            Command::DeleteMatchRulesReceiver(_) => DBusError::DeleteMatchRules,
64            Command::Close => DBusError::Close,
65        }
66    }
67}
68
69impl From<Canceled> for DBusError {
70    fn from(_: Canceled) -> Self {
71        DBusError::ReceiveMessage(None)
72    }
73}
74
75impl From<DBusError> for IoError {
76    fn from(e: DBusError) -> Self {
77        IoError::new(IoErrorKind::Other, format!("call_hello: {:?}", e))
78    }
79}
80
81impl Display for DBusError {
82    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
83        match self {
84            DBusError::SendMessage(msg) => write!(f, "Could not send message: {:?}", msg),
85            DBusError::AddMethodCall(object_path) => {
86                write!(f, "Could not add channel for method call: {}", object_path)
87            }
88            DBusError::DeleteMethodCall(object_path) => {
89                write!(f, "Could not delete channel for method call")?;
90                if let Some(object_path) = object_path {
91                    write!(f, ": {}", object_path)
92                } else {
93                    Ok(())
94                }
95            }
96            DBusError::ListMethodCall(path) => write!(f, "Could not list method call: {}", path),
97            DBusError::AddMethodCallInterface(interface) => write!(
98                f,
99                "Could not add chanell for method call(interface): {}",
100                interface
101            ),
102            DBusError::DeleteMethodCallInterface(interface) => {
103                write!(f, "Could not delete channel for method call(interface)")?;
104                if let Some(interface) = interface {
105                    write!(f, ": {}", interface)
106                } else {
107                    Ok(())
108                }
109            }
110            DBusError::AddSignal(path) => write!(f, "Could not add channel for signals: {}", path),
111            DBusError::DeleteSignal => write!(f, "Could not delete channel for signals"),
112            DBusError::AddMatchRules(match_rules) => {
113                write!(f, "Could not add channel for matches rules:")?;
114                for match_rule in match_rules.iter() {
115                    write!(f, " {}", match_rule)?;
116                }
117                Ok(())
118            }
119            DBusError::DeleteMatchRules => write!(f, "Could not delete channel for match_rules"),
120            DBusError::ReceiveMessage(msg) => {
121                write!(f, "Could not receive response for message: {:?}", msg)
122            }
123            DBusError::StreamError(e) => write!(f, "Could not create stream: {}", e),
124            DBusError::DBusSessionBusAddress => write!(
125                f,
126                "DBUS_SESSION_BUS_ADDRESS environment variable is not defined"
127            ),
128            DBusError::Hello(e) => write!(f, "Hello: {}", e),
129            DBusError::Close => write!(f, "Could not close DBus"),
130        }
131    }
132}
133
134pub type DBusResult<T> = std::result::Result<T, DBusError>;