use std::borrow::Cow;
use tracing::error;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ErrorKind {
Discovery,
Request,
InvalidParameter,
JsonResponse,
#[cfg(feature = "stream")]
StreamResponse,
Sender,
Events,
}
impl ErrorKind {
pub(crate) const fn description(self) -> &'static str {
match self {
Self::Discovery => "Discovery",
Self::Request => "Request",
Self::InvalidParameter => "Invalid Parameter",
Self::JsonResponse => "Json Response",
#[cfg(feature = "stream")]
Self::StreamResponse => "Stream Response",
Self::Sender => "Response Sender",
Self::Events => "Events",
}
}
}
impl std::fmt::Display for ErrorKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.description().fmt(f)
}
}
#[derive(PartialEq)]
pub struct Error {
kind: ErrorKind,
description: Cow<'static, str>,
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.format(f)
}
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.format(f)
}
}
impl Error {
#[inline]
pub fn new(kind: ErrorKind, description: impl Into<Cow<'static, str>>) -> Self {
let description = description.into();
error!("{}", description.as_ref());
Self { kind, description }
}
fn format(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.kind, self.description)
}
}
impl From<reqwest::Error> for Error {
fn from(e: reqwest::Error) -> Self {
Self::new(ErrorKind::Request, e.to_string())
}
}
impl From<mdns_sd::Error> for Error {
fn from(e: mdns_sd::Error) -> Self {
Self::new(ErrorKind::Discovery, e.to_string())
}
}
impl From<rumqttc::v5::ClientError> for Error {
fn from(e: rumqttc::v5::ClientError) -> Self {
Self::new(ErrorKind::Events, e.to_string())
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(self)
}
}
pub type Result<T> = std::result::Result<T, Error>;
#[cfg(test)]
mod tests {
use super::{Error, ErrorKind};
#[test]
fn controller_error() {
let error = Error::new(ErrorKind::Discovery, "Process failed.");
assert_eq!(error.to_string(), r"Discovery: Process failed.");
}
}