#![allow(clippy::upper_case_acronyms)]
use core::{cmp, fmt, hash};
#[derive(Clone, Copy, Debug)]
pub enum Rcode {
NoError,
FormErr,
ServFail,
NXDomain,
NotImp,
Refused,
YXDomain,
YXRRSet,
NXRRSet,
NotAuth,
NotZone,
Int(u8),
}
impl Rcode {
pub fn from_int(value: u8) -> Rcode {
use self::Rcode::*;
match value & 0x0F {
0 => NoError,
1 => FormErr,
2 => ServFail,
3 => NXDomain,
4 => NotImp,
5 => Refused,
6 => YXDomain,
7 => YXRRSet,
8 => NXRRSet,
9 => NotAuth,
10 => NotZone,
value => Int(value),
}
}
pub fn to_int(self) -> u8 {
use self::Rcode::*;
match self {
NoError => 0,
FormErr => 1,
ServFail => 2,
NXDomain => 3,
NotImp => 4,
Refused => 5,
YXDomain => 6,
YXRRSet => 7,
NXRRSet => 8,
NotAuth => 9,
NotZone => 10,
Int(value) => value & 0x0F,
}
}
}
impl From<u8> for Rcode {
fn from(value: u8) -> Rcode {
Rcode::from_int(value)
}
}
impl From<Rcode> for u8 {
fn from(value: Rcode) -> u8 {
value.to_int()
}
}
impl fmt::Display for Rcode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Rcode::*;
match *self {
NoError => "NOERROR".fmt(f),
FormErr => "FORMERR".fmt(f),
ServFail => "SERVFAIL".fmt(f),
NXDomain => "NXDOMAIN".fmt(f),
NotImp => "NOTIMP".fmt(f),
Refused => "REFUSED".fmt(f),
YXDomain => "YXDOMAIN".fmt(f),
YXRRSet => "YXRRSET".fmt(f),
NXRRSet => "NXRRSET".fmt(f),
NotAuth => "NOAUTH".fmt(f),
NotZone => "NOTZONE".fmt(f),
Int(i) => match Rcode::from_int(i) {
Rcode::Int(i) => i.fmt(f),
value => value.fmt(f),
},
}
}
}
impl cmp::PartialEq for Rcode {
fn eq(&self, other: &Rcode) -> bool {
self.to_int() == other.to_int()
}
}
impl cmp::PartialEq<u8> for Rcode {
fn eq(&self, other: &u8) -> bool {
self.to_int() == *other
}
}
impl cmp::PartialEq<Rcode> for u8 {
fn eq(&self, other: &Rcode) -> bool {
*self == other.to_int()
}
}
impl cmp::Eq for Rcode {}
impl cmp::PartialOrd for Rcode {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
self.to_int().partial_cmp(&other.to_int())
}
}
impl cmp::PartialOrd<u8> for Rcode {
fn partial_cmp(&self, other: &u8) -> Option<cmp::Ordering> {
self.to_int().partial_cmp(other)
}
}
impl cmp::PartialOrd<Rcode> for u8 {
fn partial_cmp(&self, other: &Rcode) -> Option<cmp::Ordering> {
self.partial_cmp(&other.to_int())
}
}
impl cmp::Ord for Rcode {
fn cmp(&self, other: &Rcode) -> cmp::Ordering {
self.to_int().cmp(&other.to_int())
}
}
impl hash::Hash for Rcode {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.to_int().hash(state)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for Rcode {
fn serialize<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
self.to_int().serialize(serializer)
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Rcode {
fn deserialize<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
u8::deserialize(deserializer).map(Rcode::from_int)
}
}
#[derive(Clone, Copy, Debug)]
pub enum OptRcode {
NoError,
FormErr,
ServFail,
NXDomain,
NotImp,
Refused,
YXDomain,
YXRRSet,
NXRRSet,
NotAuth,
NotZone,
BadVers,
BadCookie,
Int(u16),
}
impl OptRcode {
pub fn from_int(value: u16) -> OptRcode {
use self::OptRcode::*;
match value & 0x0FFF {
0 => NoError,
1 => FormErr,
2 => ServFail,
3 => NXDomain,
4 => NotImp,
5 => Refused,
6 => YXDomain,
7 => YXRRSet,
8 => NXRRSet,
9 => NotAuth,
10 => NotZone,
16 => BadVers,
23 => BadCookie,
value => Int(value),
}
}
pub fn to_int(self) -> u16 {
use self::OptRcode::*;
match self {
NoError => 0,
FormErr => 1,
ServFail => 2,
NXDomain => 3,
NotImp => 4,
Refused => 5,
YXDomain => 6,
YXRRSet => 7,
NXRRSet => 8,
NotAuth => 9,
NotZone => 10,
BadVers => 16,
BadCookie => 23,
Int(value) => value & 0x0F,
}
}
pub fn from_parts(rcode: Rcode, ext: u8) -> OptRcode {
OptRcode::from_int(u16::from(ext) << 4 | u16::from(rcode.to_int()))
}
pub fn to_parts(self) -> (Rcode, u8) {
let res = self.to_int();
(Rcode::from_int(res as u8), (res >> 8) as u8)
}
pub fn rcode(self) -> Rcode {
self.to_parts().0
}
pub fn ext(self) -> u8 {
self.to_parts().1
}
}
impl From<u16> for OptRcode {
fn from(value: u16) -> OptRcode {
OptRcode::from_int(value)
}
}
impl From<OptRcode> for u16 {
fn from(value: OptRcode) -> u16 {
value.to_int()
}
}
impl From<Rcode> for OptRcode {
fn from(value: Rcode) -> OptRcode {
OptRcode::from_parts(value, 0)
}
}
impl fmt::Display for OptRcode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::OptRcode::*;
match *self {
NoError => "NOERROR".fmt(f),
FormErr => "FORMERR".fmt(f),
ServFail => "SERVFAIL".fmt(f),
NXDomain => "NXDOMAIN".fmt(f),
NotImp => "NOTIMP".fmt(f),
Refused => "REFUSED".fmt(f),
YXDomain => "YXDOMAIN".fmt(f),
YXRRSet => "YXRRSET".fmt(f),
NXRRSet => "NXRRSET".fmt(f),
NotAuth => "NOAUTH".fmt(f),
NotZone => "NOTZONE".fmt(f),
BadVers => "BADVER".fmt(f),
BadCookie => "BADCOOKIE".fmt(f),
Int(i) => match OptRcode::from_int(i) {
Int(i) => i.fmt(f),
value => value.fmt(f),
},
}
}
}
int_enum! {
=>
TsigRcode, u16;
(NoError => 0, b"NOERROR")
(FormErr => 1, b"FORMERR")
(ServFail => 2, b"SERVFAIL")
(NXDomain => 3, b"NXDOMAIN")
(NotImp => 4, b"NOTIMPL")
(Refused => 5, b"REFUSED")
(YXDomain => 6, b"YXDOMAIN")
(YXRRSet => 7, b"YXRRSET")
(NXRRSet => 8, b"NXRRSET")
(NotAuth => 9, b"NOTAUTH")
(NotZone => 10, b"NOTZONE")
(BadSig => 16, b"BADSIG")
(BadKey => 17, b"BADKEY")
(BadTime => 18, b"BADTIME")
(BadMode => 19, b"BADMODE")
(BadName => 20, b"BADNAME")
(BadAlg => 21, b"BADALG")
(BadTrunc => 22, b"BADTRUNC")
(BadCookie => 23, b"BADCOOKIE")
}
impl From<Rcode> for TsigRcode {
fn from(value: Rcode) -> TsigRcode {
TsigRcode::from_int(u16::from(value.to_int()))
}
}
impl From<OptRcode> for TsigRcode {
fn from(value: OptRcode) -> TsigRcode {
TsigRcode::from_int(value.to_int())
}
}
int_enum_str_with_decimal!(TsigRcode, u16, "unknown TSIG error");