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>;