use std::{fmt, sync::Arc};
use crate::{
Error, Result, fdo,
message::{Header, Message},
names::ErrorName,
};
pub trait DBusError {
fn create_reply(&self, msg: &Header<'_>) -> Result<Message>;
fn name(&self) -> ErrorName<'_>;
fn description(&self) -> Option<&str>;
}
pub type BoxDBusError = Box<dyn DBusError + Send + Sync>;
impl fmt::Display for dyn DBusError + Send + Sync {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let description = self.description().unwrap_or("no description");
write!(f, "{}: {description}", self.name())
}
}
impl fmt::Debug for dyn DBusError + Send + Sync {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DBusError")
.field("name", &self.name())
.field("description", &self.description())
.finish()
}
}
impl<E> DBusError for Box<E>
where
E: DBusError + ?Sized,
{
fn create_reply(&self, msg: &Header<'_>) -> Result<Message> {
(**self).create_reply(msg)
}
fn name(&self) -> ErrorName<'_> {
(**self).name()
}
fn description(&self) -> Option<&str> {
(**self).description()
}
}
impl<E> DBusError for Arc<E>
where
E: DBusError + ?Sized,
{
fn create_reply(&self, msg: &Header<'_>) -> Result<Message> {
(**self).create_reply(msg)
}
fn name(&self) -> ErrorName<'_> {
(**self).name()
}
fn description(&self) -> Option<&str> {
(**self).description()
}
}
impl From<fdo::Error> for BoxDBusError {
fn from(e: fdo::Error) -> Self {
Box::new(e)
}
}
impl From<Error> for BoxDBusError {
fn from(e: Error) -> Self {
match e {
Error::FDO(e) => e,
Error::DBus(e) => Box::new(e),
e => Box::new(fdo::Error::from(e)),
}
}
}