use crate::rdata::Record;
use crate::rdata::*;
use crate::Error;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Type {
A = a::Record::TYPE,
NS = ns::Record::TYPE,
MF = mf::Record::TYPE,
CNAME = cname::Record::TYPE,
SOA = soa::Record::TYPE,
MB = mb::Record::TYPE,
MG = mg::Record::TYPE,
MR = mr::Record::TYPE,
NULL = null::Record::TYPE,
WKS = wks::Record::TYPE,
PTR = ptr::Record::TYPE,
HINFO = hinfo::Record::TYPE,
MINFO = minfo::Record::TYPE,
MX = mx::Record::TYPE,
TXT = txt::Record::TYPE,
AAAA = aaaa::Record::TYPE,
SRV = srv::Record::TYPE,
OPT = opt::Record::TYPE,
NSEC = nsec::Record::TYPE,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum QueryType {
A = a::Record::TYPE,
NS = ns::Record::TYPE,
MF = mf::Record::TYPE,
CNAME = cname::Record::TYPE,
SOA = soa::Record::TYPE,
MB = mb::Record::TYPE,
MG = mg::Record::TYPE,
MR = mr::Record::TYPE,
NULL = null::Record::TYPE,
WKS = wks::Record::TYPE,
PTR = ptr::Record::TYPE,
HINFO = hinfo::Record::TYPE,
MINFO = minfo::Record::TYPE,
MX = mx::Record::TYPE,
TXT = txt::Record::TYPE,
AAAA = aaaa::Record::TYPE,
SRV = srv::Record::TYPE,
AXFR = axfr::Record::TYPE,
MAILB = mailb::Record::TYPE,
MAILA = maila::Record::TYPE,
All = all::Record::TYPE,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Class {
IN = 1,
CS = 2,
CH = 3,
HS = 4,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum QueryClass {
IN = 1,
CS = 2,
CH = 3,
HS = 4,
Any = 255,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Opcode {
StandardQuery,
InverseQuery,
ServerStatusRequest,
Reserved(u16),
}
quick_error! {
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(missing_docs)] pub enum ResponseCode {
NoError
FormatError
ServerFailure
NameError
NotImplemented
Refused
Unknown(code: u8)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for ResponseCode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
ResponseCode::NoError => serializer.serialize_str("NoError"),
ResponseCode::FormatError => serializer.serialize_str("FormatError"),
ResponseCode::ServerFailure => serializer.serialize_str("ServerFailure"),
ResponseCode::NameError => serializer.serialize_str("NameError"),
ResponseCode::NotImplemented => serializer.serialize_str("NotImplemented"),
ResponseCode::Refused => serializer.serialize_str("Refused"),
ResponseCode::Unknown(r) => {
let mut s = [b'U', b'n', b'k', b'n', b'o', b'w', b'n', 0, 0, 0];
s[7] = (*r / 100) + b'0';
s[8] = (*r / 10) % 10 + b'0';
s[9] = (*r % 10) + b'0';
serializer.serialize_str(unsafe { std::str::from_utf8_unchecked(s.as_slice()) })
}
}
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for Opcode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
Opcode::StandardQuery => serializer.serialize_str("StandardQuery"),
Opcode::InverseQuery => serializer.serialize_str("InverseQuery"),
Opcode::ServerStatusRequest => serializer.serialize_str("ServerStatusRequest"),
Opcode::Reserved(_) => serializer.serialize_str("Reserved"),
}
}
}
impl From<u16> for Opcode {
fn from(code: u16) -> Opcode {
use self::Opcode::*;
match code {
0 => StandardQuery,
1 => InverseQuery,
2 => ServerStatusRequest,
x => Reserved(x),
}
}
}
impl From<Opcode> for u16 {
fn from(val: Opcode) -> Self {
use self::Opcode::*;
match val {
StandardQuery => 0,
InverseQuery => 1,
ServerStatusRequest => 2,
Reserved(x) => x,
}
}
}
impl From<u8> for ResponseCode {
fn from(code: u8) -> ResponseCode {
use self::ResponseCode::*;
match code {
0 => NoError,
1 => FormatError,
2 => ServerFailure,
3 => NameError,
4 => NotImplemented,
5 => Refused,
_ => Unknown(code),
}
}
}
impl From<ResponseCode> for u8 {
fn from(val: ResponseCode) -> Self {
use self::ResponseCode::*;
match val {
NoError => 0,
FormatError => 1,
ServerFailure => 2,
NameError => 3,
NotImplemented => 4,
Refused => 5,
Unknown(code) => code,
}
}
}
impl QueryType {
pub fn parse(code: u16) -> Result<QueryType, Error> {
use self::QueryType::*;
match code as isize {
a::Record::TYPE => Ok(A),
ns::Record::TYPE => Ok(NS),
mf::Record::TYPE => Ok(MF),
cname::Record::TYPE => Ok(CNAME),
soa::Record::TYPE => Ok(SOA),
mb::Record::TYPE => Ok(MB),
mg::Record::TYPE => Ok(MG),
mr::Record::TYPE => Ok(MR),
null::Record::TYPE => Ok(NULL),
wks::Record::TYPE => Ok(WKS),
ptr::Record::TYPE => Ok(PTR),
hinfo::Record::TYPE => Ok(HINFO),
minfo::Record::TYPE => Ok(MINFO),
mx::Record::TYPE => Ok(MX),
txt::Record::TYPE => Ok(TXT),
aaaa::Record::TYPE => Ok(AAAA),
srv::Record::TYPE => Ok(SRV),
axfr::Record::TYPE => Ok(AXFR),
mailb::Record::TYPE => Ok(MAILB),
maila::Record::TYPE => Ok(MAILA),
all::Record::TYPE => Ok(All),
x => Err(Error::InvalidQueryType(x as u16)),
}
}
}
impl QueryClass {
pub fn parse(code: u16) -> Result<QueryClass, Error> {
use self::QueryClass::*;
match code {
1 => Ok(IN),
2 => Ok(CS),
3 => Ok(CH),
4 => Ok(HS),
255 => Ok(Any),
x => Err(Error::InvalidQueryClass(x)),
}
}
}
impl Type {
pub fn parse(code: u16) -> Result<Type, Error> {
use self::Type::*;
match code as isize {
a::Record::TYPE => Ok(A),
ns::Record::TYPE => Ok(NS),
mf::Record::TYPE => Ok(MF),
cname::Record::TYPE => Ok(CNAME),
soa::Record::TYPE => Ok(SOA),
mb::Record::TYPE => Ok(MB),
mg::Record::TYPE => Ok(MG),
mr::Record::TYPE => Ok(MR),
null::Record::TYPE => Ok(NULL),
wks::Record::TYPE => Ok(WKS),
ptr::Record::TYPE => Ok(PTR),
hinfo::Record::TYPE => Ok(HINFO),
minfo::Record::TYPE => Ok(MINFO),
mx::Record::TYPE => Ok(MX),
txt::Record::TYPE => Ok(TXT),
aaaa::Record::TYPE => Ok(AAAA),
srv::Record::TYPE => Ok(SRV),
opt::Record::TYPE => Ok(OPT),
nsec::Record::TYPE => Ok(NSEC),
x => Err(Error::InvalidType(x as u16)),
}
}
}
impl Class {
pub fn parse(code: u16) -> Result<Class, Error> {
use self::Class::*;
match code {
1 => Ok(IN),
2 => Ok(CS),
3 => Ok(CH),
4 => Ok(HS),
x => Err(Error::InvalidClass(x)),
}
}
}