1use crate::rdata::Record;
2use crate::rdata::*;
3use crate::Error;
4
5#[derive(Debug, PartialEq, Eq, Clone, Copy)]
9pub enum Type {
10 A = a::Record::TYPE,
12 NS = ns::Record::TYPE,
14 MF = mf::Record::TYPE,
16 CNAME = cname::Record::TYPE,
18 SOA = soa::Record::TYPE,
20 MB = mb::Record::TYPE,
22 MG = mg::Record::TYPE,
24 MR = mr::Record::TYPE,
26 NULL = null::Record::TYPE,
28 WKS = wks::Record::TYPE,
30 PTR = ptr::Record::TYPE,
32 HINFO = hinfo::Record::TYPE,
34 MINFO = minfo::Record::TYPE,
36 MX = mx::Record::TYPE,
38 TXT = txt::Record::TYPE,
40 AAAA = aaaa::Record::TYPE,
42 SRV = srv::Record::TYPE,
44 OPT = opt::Record::TYPE,
46 NSEC = nsec::Record::TYPE,
48}
49
50#[derive(Debug, PartialEq, Eq, Clone, Copy)]
54#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
55pub enum QueryType {
56 A = a::Record::TYPE,
58 NS = ns::Record::TYPE,
60 MF = mf::Record::TYPE,
62 CNAME = cname::Record::TYPE,
64 SOA = soa::Record::TYPE,
66 MB = mb::Record::TYPE,
68 MG = mg::Record::TYPE,
70 MR = mr::Record::TYPE,
72 NULL = null::Record::TYPE,
74 WKS = wks::Record::TYPE,
76 PTR = ptr::Record::TYPE,
78 HINFO = hinfo::Record::TYPE,
80 MINFO = minfo::Record::TYPE,
82 MX = mx::Record::TYPE,
84 TXT = txt::Record::TYPE,
86 AAAA = aaaa::Record::TYPE,
88 SRV = srv::Record::TYPE,
90 AXFR = axfr::Record::TYPE,
92 MAILB = mailb::Record::TYPE,
94 MAILA = maila::Record::TYPE,
96 All = all::Record::TYPE,
98}
99
100#[derive(Debug, PartialEq, Eq, Clone, Copy)]
102pub enum Class {
103 IN = 1,
105 CS = 2,
108 CH = 3,
110 HS = 4,
112}
113
114#[derive(Debug, PartialEq, Eq, Clone, Copy)]
116pub enum QueryClass {
117 IN = 1,
119 CS = 2,
122 CH = 3,
124 HS = 4,
126 Any = 255,
128}
129
130#[derive(Debug, PartialEq, Eq, Clone, Copy)]
132pub enum Opcode {
133 StandardQuery,
135 InverseQuery,
137 ServerStatusRequest,
139 Reserved(u16),
141}
142
143quick_error! {
144 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
146 #[allow(missing_docs)] pub enum ResponseCode {
148 NoError
149 FormatError
150 ServerFailure
151 NameError
152 NotImplemented
153 Refused
154 Unknown(code: u8)
155 }
156}
157
158#[cfg(feature = "serde")]
159impl serde::Serialize for ResponseCode {
160 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
161 where
162 S: serde::Serializer,
163 {
164 match self {
165 ResponseCode::NoError => serializer.serialize_str("NoError"),
166 ResponseCode::FormatError => serializer.serialize_str("FormatError"),
167 ResponseCode::ServerFailure => serializer.serialize_str("ServerFailure"),
168 ResponseCode::NameError => serializer.serialize_str("NameError"),
169 ResponseCode::NotImplemented => serializer.serialize_str("NotImplemented"),
170 ResponseCode::Refused => serializer.serialize_str("Refused"),
171 ResponseCode::Unknown(r) => {
172 let mut s = [b'U', b'n', b'k', b'n', b'o', b'w', b'n', 0, 0, 0];
173 s[7] = (*r / 100) + b'0';
174 s[8] = (*r / 10) % 10 + b'0';
175 s[9] = (*r % 10) + b'0';
176 serializer.serialize_str(unsafe { std::str::from_utf8_unchecked(s.as_slice()) })
177 }
178 }
179 }
180}
181
182#[cfg(feature = "serde")]
183impl serde::Serialize for Opcode {
184 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
185 where
186 S: serde::Serializer,
187 {
188 match self {
189 Opcode::StandardQuery => serializer.serialize_str("StandardQuery"),
190 Opcode::InverseQuery => serializer.serialize_str("InverseQuery"),
191 Opcode::ServerStatusRequest => serializer.serialize_str("ServerStatusRequest"),
192 Opcode::Reserved(_) => serializer.serialize_str("Reserved"),
193 }
194 }
195}
196
197impl From<u16> for Opcode {
198 fn from(code: u16) -> Opcode {
199 use self::Opcode::*;
200 match code {
201 0 => StandardQuery,
202 1 => InverseQuery,
203 2 => ServerStatusRequest,
204 x => Reserved(x),
205 }
206 }
207}
208impl From<Opcode> for u16 {
209 fn from(val: Opcode) -> Self {
210 use self::Opcode::*;
211 match val {
212 StandardQuery => 0,
213 InverseQuery => 1,
214 ServerStatusRequest => 2,
215 Reserved(x) => x,
216 }
217 }
218}
219
220impl From<u8> for ResponseCode {
221 fn from(code: u8) -> ResponseCode {
222 use self::ResponseCode::*;
223 match code {
224 0 => NoError,
225 1 => FormatError,
226 2 => ServerFailure,
227 3 => NameError,
228 4 => NotImplemented,
229 5 => Refused,
230 _ => Unknown(code),
231 }
232 }
233}
234impl From<ResponseCode> for u8 {
235 fn from(val: ResponseCode) -> Self {
236 use self::ResponseCode::*;
237 match val {
238 NoError => 0,
239 FormatError => 1,
240 ServerFailure => 2,
241 NameError => 3,
242 NotImplemented => 4,
243 Refused => 5,
244 Unknown(code) => code,
245 }
246 }
247}
248
249impl QueryType {
250 pub fn parse(code: u16) -> Result<QueryType, Error> {
252 use self::QueryType::*;
253 match code as isize {
254 a::Record::TYPE => Ok(A),
255 ns::Record::TYPE => Ok(NS),
256 mf::Record::TYPE => Ok(MF),
257 cname::Record::TYPE => Ok(CNAME),
258 soa::Record::TYPE => Ok(SOA),
259 mb::Record::TYPE => Ok(MB),
260 mg::Record::TYPE => Ok(MG),
261 mr::Record::TYPE => Ok(MR),
262 null::Record::TYPE => Ok(NULL),
263 wks::Record::TYPE => Ok(WKS),
264 ptr::Record::TYPE => Ok(PTR),
265 hinfo::Record::TYPE => Ok(HINFO),
266 minfo::Record::TYPE => Ok(MINFO),
267 mx::Record::TYPE => Ok(MX),
268 txt::Record::TYPE => Ok(TXT),
269 aaaa::Record::TYPE => Ok(AAAA),
270 srv::Record::TYPE => Ok(SRV),
271 axfr::Record::TYPE => Ok(AXFR),
272 mailb::Record::TYPE => Ok(MAILB),
273 maila::Record::TYPE => Ok(MAILA),
274 all::Record::TYPE => Ok(All),
275 x => Err(Error::InvalidQueryType(x as u16)),
276 }
277 }
278}
279
280impl QueryClass {
281 pub fn parse(code: u16) -> Result<QueryClass, Error> {
283 use self::QueryClass::*;
284 match code {
285 1 => Ok(IN),
286 2 => Ok(CS),
287 3 => Ok(CH),
288 4 => Ok(HS),
289 255 => Ok(Any),
290 x => Err(Error::InvalidQueryClass(x)),
291 }
292 }
293}
294
295impl Type {
296 pub fn parse(code: u16) -> Result<Type, Error> {
298 use self::Type::*;
299 match code as isize {
300 a::Record::TYPE => Ok(A),
301 ns::Record::TYPE => Ok(NS),
302 mf::Record::TYPE => Ok(MF),
303 cname::Record::TYPE => Ok(CNAME),
304 soa::Record::TYPE => Ok(SOA),
305 mb::Record::TYPE => Ok(MB),
306 mg::Record::TYPE => Ok(MG),
307 mr::Record::TYPE => Ok(MR),
308 null::Record::TYPE => Ok(NULL),
309 wks::Record::TYPE => Ok(WKS),
310 ptr::Record::TYPE => Ok(PTR),
311 hinfo::Record::TYPE => Ok(HINFO),
312 minfo::Record::TYPE => Ok(MINFO),
313 mx::Record::TYPE => Ok(MX),
314 txt::Record::TYPE => Ok(TXT),
315 aaaa::Record::TYPE => Ok(AAAA),
316 srv::Record::TYPE => Ok(SRV),
317 opt::Record::TYPE => Ok(OPT),
318 nsec::Record::TYPE => Ok(NSEC),
319 x => Err(Error::InvalidType(x as u16)),
320 }
321 }
322}
323
324impl Class {
325 pub fn parse(code: u16) -> Result<Class, Error> {
327 use self::Class::*;
328 match code {
329 1 => Ok(IN),
330 2 => Ok(CS),
331 3 => Ok(CH),
332 4 => Ok(HS),
333 x => Err(Error::InvalidClass(x)),
334 }
335 }
336}