hickory_proto/op/op_code.rs
1// Copyright 2015-2021 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! Operation code for queries, updates, and responses
9
10use core::{convert::From, fmt};
11
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15/// Operation code for queries, updates, and responses
16///
17/// [RFC 1035, DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION, November 1987](https://tools.ietf.org/html/rfc1035)
18///
19/// ```text
20/// OPCODE A four bit field that specifies kind of query in this
21/// message. This value is set by the originator of a query
22/// and copied into the response. The values are:
23///
24/// 0 a standard query (QUERY)
25///
26/// 1 an inverse query (IQUERY)
27///
28/// 2 a server status request (STATUS)
29///
30/// 3-15 reserved for future use
31/// ```
32#[derive(Debug, PartialEq, Eq, PartialOrd, Copy, Clone, Hash)]
33#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
34#[allow(dead_code)]
35pub enum OpCode {
36 /// Query request [RFC 1035](https://tools.ietf.org/html/rfc1035)
37 Query,
38
39 /// Status message [RFC 1035](https://tools.ietf.org/html/rfc1035)
40 Status,
41
42 /// Notify of change [RFC 1996](https://tools.ietf.org/html/rfc1996)
43 Notify,
44
45 /// Update message [RFC 2136](https://tools.ietf.org/html/rfc2136)
46 Update,
47
48 /// Any other opcode
49 Unknown(u8),
50}
51
52impl fmt::Display for OpCode {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
54 match self {
55 Self::Query => f.write_str("QUERY"),
56 Self::Status => f.write_str("STATUS"),
57 Self::Notify => f.write_str("NOTIFY"),
58 Self::Update => f.write_str("UPDATE"),
59 Self::Unknown(opcode) => write!(f, "Unknown opcode ({opcode})"),
60 }
61 }
62}
63
64/// Convert from `OpCode` to `u8`
65///
66/// ```
67/// use hickory_proto::op::op_code::OpCode;
68///
69/// let var: u8 = From::from(OpCode::Query);
70/// assert_eq!(0, var);
71///
72/// let var: u8 = OpCode::Query.into();
73/// assert_eq!(0, var);
74/// ```
75impl From<OpCode> for u8 {
76 fn from(rt: OpCode) -> Self {
77 match rt {
78 OpCode::Query => 0,
79 // 1 IQuery (Inverse Query, OBSOLETE) [RFC3425]
80 OpCode::Status => 2,
81 // 3 Unassigned
82 OpCode::Notify => 4,
83 OpCode::Update => 5,
84 // 6-15 Unassigned
85 OpCode::Unknown(opcode) => opcode,
86 }
87 }
88}
89
90/// Convert from `u8` to `OpCode`
91///
92/// ```
93/// use hickory_proto::op::op_code::OpCode;
94///
95/// let var: OpCode = OpCode::from_u8(0);
96/// assert_eq!(OpCode::Query, var);
97/// ```
98impl OpCode {
99 /// Decodes the binary value of the OpCode
100 pub fn from_u8(value: u8) -> Self {
101 match value {
102 0 => Self::Query,
103 2 => Self::Status,
104 4 => Self::Notify,
105 5 => Self::Update,
106 _ => Self::Unknown(value),
107 }
108 }
109}