use std::fmt;
use std::fmt::{Display, Formatter};
#[derive(Debug, Eq, PartialEq, PartialOrd, Copy, Clone, Hash)]
#[allow(dead_code)]
pub enum ResponseCode {
NoError,
FormErr,
ServFail,
NXDomain,
NotImp,
Refused,
YXDomain,
YXRRSet,
NXRRSet,
NotAuth,
NotZone,
BADVERS,
BADSIG,
BADKEY,
BADTIME,
BADMODE,
BADNAME,
BADALG,
BADTRUNC,
BADCOOKIE,
Unknown(u16),
}
impl ResponseCode {
pub fn low(self) -> u8 {
(u16::from(self) & 0x000F) as u8
}
pub fn high(self) -> u8 {
((u16::from(self) & 0x0FF0) >> 4) as u8
}
pub fn from_low(low: u8) -> Self {
((u16::from(low)) & 0x000F).into()
}
pub fn from(high: u8, low: u8) -> Self {
((u16::from(high) << 4) | ((u16::from(low)) & 0x000F)).into()
}
pub fn to_str(self) -> &'static str {
match self {
Self::NoError => "No Error",
Self::FormErr => "Form Error", Self::ServFail => "Server Failure", Self::NXDomain => "Non-Existent Domain", Self::NotImp => "Not Implemented", Self::Refused => "Query Refused", Self::YXDomain => "Name should not exist", Self::YXRRSet => "RR Set should not exist", Self::NXRRSet => "RR Set does not exist", Self::NotAuth => "Not authorized", Self::NotZone => "Name not in zone", Self::BADVERS => "Bad option verions", Self::BADSIG => "TSIG Failure", Self::BADKEY => "Key not recognized", Self::BADTIME => "Signature out of time window", Self::BADMODE => "Bad TKEY mode", Self::BADNAME => "Duplicate key name", Self::BADALG => "Algorithm not supported", Self::BADTRUNC => "Bad truncation", Self::BADCOOKIE => "Bad server cookie", Self::Unknown(_) => "Unknown response code",
}
}
}
impl Default for ResponseCode {
fn default() -> Self {
Self::NoError
}
}
impl Display for ResponseCode {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str(self.to_str())
}
}
impl From<ResponseCode> for u16 {
fn from(rt: ResponseCode) -> Self {
match rt {
ResponseCode::NoError => 0, ResponseCode::FormErr => 1, ResponseCode::ServFail => 2, ResponseCode::NXDomain => 3, ResponseCode::NotImp => 4, ResponseCode::Refused => 5, ResponseCode::YXDomain => 6, ResponseCode::YXRRSet => 7, ResponseCode::NXRRSet => 8, ResponseCode::NotAuth => 9, ResponseCode::NotZone => 10, ResponseCode::BADVERS | ResponseCode::BADSIG => 16,
ResponseCode::BADKEY => 17, ResponseCode::BADTIME => 18, ResponseCode::BADMODE => 19, ResponseCode::BADNAME => 20, ResponseCode::BADALG => 21, ResponseCode::BADTRUNC => 22, ResponseCode::BADCOOKIE => 23,
ResponseCode::Unknown(code) => code,
}
}
}
impl From<u16> for ResponseCode {
#[allow(clippy::unimplemented)]
fn from(value: u16) -> Self {
match value {
0 => Self::NoError, 1 => Self::FormErr, 2 => Self::ServFail, 3 => Self::NXDomain, 4 => Self::NotImp, 5 => Self::Refused, 6 => Self::YXDomain, 7 => Self::YXRRSet, 8 => Self::NXRRSet, 9 => Self::NotAuth, 10 => Self::NotZone, 16 => Self::BADSIG, 17 => Self::BADKEY, 18 => Self::BADTIME, 19 => Self::BADMODE, 20 => Self::BADNAME, 21 => Self::BADALG, 22 => Self::BADTRUNC, 23 => Self::BADCOOKIE, code => Self::Unknown(code),
}
}
}