trust_dns_proto/rr/
dns_class.rs
1#![allow(clippy::use_self)]
10
11use std::cmp::Ordering;
12use std::convert::From;
13use std::fmt;
14use std::fmt::{Display, Formatter};
15use std::str::FromStr;
16
17#[cfg(feature = "serde-config")]
18use serde::{Deserialize, Serialize};
19
20use crate::error::*;
21use crate::serialize::binary::*;
22
23#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
25#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
26#[allow(dead_code)]
27pub enum DNSClass {
28 IN,
30 CH,
32 HS,
34 NONE,
36 ANY,
38 OPT(u16),
41}
42
43impl FromStr for DNSClass {
44 type Err = ProtoError;
45
46 fn from_str(str: &str) -> ProtoResult<Self> {
56 debug_assert!(str.chars().all(|x| char::is_ascii_uppercase(&x)));
57 match str {
58 "IN" => Ok(Self::IN),
59 "CH" => Ok(Self::CH),
60 "HS" => Ok(Self::HS),
61 "NONE" => Ok(Self::NONE),
62 "ANY" | "*" => Ok(Self::ANY),
63 _ => Err(ProtoErrorKind::UnknownDnsClassStr(str.to_string()).into()),
64 }
65 }
66}
67
68impl DNSClass {
69 pub fn from_u16(value: u16) -> ProtoResult<Self> {
78 match value {
79 1 => Ok(Self::IN),
80 3 => Ok(Self::CH),
81 4 => Ok(Self::HS),
82 254 => Ok(Self::NONE),
83 255 => Ok(Self::ANY),
84 _ => Err(ProtoErrorKind::UnknownDnsClassValue(value).into()),
85 }
86 }
87
88 pub fn for_opt(value: u16) -> Self {
90 let value = value.max(512);
92 Self::OPT(value)
93 }
94}
95
96impl BinEncodable for DNSClass {
97 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
98 encoder.emit_u16((*self).into())
99 }
100}
101
102impl<'r> BinDecodable<'r> for DNSClass {
103 fn read(decoder: &mut BinDecoder<'_>) -> ProtoResult<Self> {
104 Self::from_u16(
105 decoder.read_u16()?.unverified(),
106 )
107 }
108}
109
110impl From<DNSClass> for &'static str {
121 fn from(rt: DNSClass) -> &'static str {
122 match rt {
123 DNSClass::IN => "IN",
124 DNSClass::CH => "CH",
125 DNSClass::HS => "HS",
126 DNSClass::NONE => "NONE",
127 DNSClass::ANY => "ANY",
128 DNSClass::OPT(_) => "OPT",
129 }
130 }
131}
132
133impl From<DNSClass> for u16 {
142 fn from(rt: DNSClass) -> Self {
143 match rt {
144 DNSClass::IN => 1,
145 DNSClass::CH => 3,
146 DNSClass::HS => 4,
147 DNSClass::NONE => 254,
148 DNSClass::ANY => 255,
149 DNSClass::OPT(max_payload_len) => max_payload_len.max(512),
151 }
152 }
153}
154
155impl PartialOrd<Self> for DNSClass {
156 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
157 Some(self.cmp(other))
158 }
159}
160
161impl Ord for DNSClass {
162 fn cmp(&self, other: &Self) -> Ordering {
163 u16::from(*self).cmp(&u16::from(*other))
164 }
165}
166
167impl Display for DNSClass {
168 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
169 f.write_str(Into::<&str>::into(*self))
170 }
171}
172
173#[test]
174fn test_order() {
175 let ordered = vec![
176 DNSClass::IN,
177 DNSClass::CH,
178 DNSClass::HS,
179 DNSClass::NONE,
180 DNSClass::ANY,
181 ];
182 let mut unordered = vec![
183 DNSClass::NONE,
184 DNSClass::HS,
185 DNSClass::CH,
186 DNSClass::IN,
187 DNSClass::ANY,
188 ];
189
190 unordered.sort();
191
192 assert_eq!(unordered, ordered);
193}