dust-mail 0.4.0

A multi protocol email client
use std::{error, fmt::Display, result};

#[cfg(feature = "autoconfig")]
use autoconfig::error::Error as AutoconfigError;
#[cfg(feature = "autodiscover")]
use ms_autodiscover::error::Error as AutodiscoverError;

use dns_mail_discover::error::Error as DnsDiscoverError;

#[derive(Debug)]
pub enum ErrorKind {
    InvalidEmailAddress,
    InvalidConfig,
    NotFound(Vec<Error>),
    DnsDiscover(DnsDiscoverError),
    #[cfg(feature = "autoconfig")]
    Autoconfig(AutoconfigError),
    #[cfg(feature = "autodiscover")]
    Autodiscover(AutodiscoverError),
}

#[derive(Debug)]
pub struct Error {
    message: String,
    kind: ErrorKind,
}

impl Error {
    pub fn new<M: Into<String>>(kind: ErrorKind, message: M) -> Self {
        Self {
            message: message.into(),
            kind,
        }
    }

    pub fn kind(&self) -> &ErrorKind {
        &self.kind
    }
}

impl error::Error for Error {}

impl Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Error: {}", self.message)
    }
}

#[cfg(feature = "autoconfig")]
impl From<AutoconfigError> for Error {
    fn from(autoconfig_error: AutoconfigError) -> Self {
        Error::new(
            ErrorKind::Autoconfig(autoconfig_error),
            "Failed to retrieve config using autoconfig protocol",
        )
    }
}

#[cfg(feature = "autodiscover")]
impl From<AutodiscoverError> for Error {
    fn from(error: AutodiscoverError) -> Self {
        Error::new(
            ErrorKind::Autodiscover(error),
            "Failed to retrieve config using autodiscover protocol",
        )
    }
}

impl From<DnsDiscoverError> for Error {
    fn from(error: DnsDiscoverError) -> Self {
        Error::new(
            ErrorKind::DnsDiscover(error),
            "Failed to retrieve config using dns mail discover protocol",
        )
    }
}

macro_rules! err {
    ($kind:expr, $($arg:tt)*) => {{
		use crate::discover::error::Error;

        let kind = $kind;
        let message = format!($($arg)*);
        return Err(Error::new( kind, message ));
    }};
}

pub(crate) use err;

pub type Result<T> = result::Result<T, Error>;