use std::io;
use enum_as_inner::EnumAsInner;
use thiserror::Error;
use crate::client::op::ResponseCode;
#[cfg(feature = "trust-dns-resolver")]
use crate::resolver::error::ResolveError;
#[allow(clippy::large_enum_variant)]
#[derive(Debug, EnumAsInner, Error)]
#[non_exhaustive]
pub enum LookupError {
#[error("The name exists, but not for the record requested")]
NameExists,
#[error("Error performing lookup: {0}")]
ResponseCode(ResponseCode),
#[cfg(feature = "trust-dns-resolver")]
#[cfg_attr(docsrs, doc(cfg(feature = "resolver")))]
#[error("Forward resolution error: {0}")]
ResolveError(#[from] ResolveError),
#[cfg(feature = "trust-dns-recursor")]
#[cfg_attr(docsrs, doc(cfg(feature = "recursor")))]
#[error("Recursive resolution error: {0}")]
RecursiveError(#[from] trust_dns_recursor::Error),
#[error("io error: {0}")]
Io(io::Error),
}
impl LookupError {
pub fn for_name_exists() -> Self {
Self::NameExists
}
pub fn is_nx_domain(&self) -> bool {
matches!(*self, Self::ResponseCode(ResponseCode::NXDomain))
}
pub fn is_refused(&self) -> bool {
matches!(*self, Self::ResponseCode(ResponseCode::Refused))
}
}
impl From<ResponseCode> for LookupError {
fn from(code: ResponseCode) -> Self {
debug_assert!(code != ResponseCode::NoError);
Self::ResponseCode(code)
}
}
impl From<io::Error> for LookupError {
fn from(e: io::Error) -> Self {
Self::Io(e)
}
}
impl From<LookupError> for io::Error {
fn from(e: LookupError) -> Self {
Self::new(io::ErrorKind::Other, Box::new(e))
}
}
pub type LookupResult<T> = Result<T, LookupError>;