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}