1use std::cmp;
4use std::fmt;
5use std::hash;
6use bytes::BufMut;
7use ::bits::compose::Compose;
8use ::bits::parse::{Parse, Parser, ShortBuf};
9
10
11#[derive(Clone, Copy, Debug)]
23pub enum OptionCode {
24 Llq,
25 Ul,
26 Nsid,
27 Dau,
28 Dhu,
29 N3u,
30 ClientSubnet,
31 Expire,
32 Cookie,
33 TcpKeepalive,
34 Padding,
35 Chain,
36 KeyTag,
37 DeviceId,
38
39 Int(u16),
41}
42
43impl OptionCode {
44 pub fn from_int(value: u16) -> Self {
46 use self::OptionCode::*;
47
48 match value {
49 1 => Llq,
50 2 => Ul,
51 3 => Nsid,
52 5 => Dau,
53 6 => Dhu,
54 7 => N3u,
55 8 => ClientSubnet,
56 9 => Expire,
57 10 => Cookie,
58 11 => TcpKeepalive,
59 12 => Padding,
60 13 => Chain,
61 14 => KeyTag,
62 26946 => DeviceId,
63 _ => Int(value)
64 }
65 }
66
67 pub fn to_int(self) -> u16 {
69 use self::OptionCode::*;
70
71 match self {
72 Llq => 1,
73 Ul => 2,
74 Nsid => 3,
75 Dau => 5,
76 Dhu => 6,
77 N3u => 7,
78 ClientSubnet => 8,
79 Expire => 9,
80 Cookie => 10,
81 TcpKeepalive => 11,
82 Padding => 12,
83 Chain => 13,
84 KeyTag => 14,
85 DeviceId => 26946,
86 Int(v) => v
87 }
88 }
89}
90
91
92impl Parse for OptionCode {
95 type Err = ShortBuf;
96
97 fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
98 u16::parse(parser).map(OptionCode::from_int)
99 }
100
101 fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
102 u16::skip(parser)
103 }
104}
105
106impl Compose for OptionCode {
107 fn compose_len(&self) -> usize {
108 2
109 }
110
111 fn compose<B: BufMut>(&self, buf: &mut B) {
112 self.to_int().compose(buf)
113 }
114}
115
116
117impl From<u16> for OptionCode {
120 fn from(value: u16) -> Self {
121 OptionCode::from_int(value)
122 }
123}
124
125impl From<OptionCode> for u16 {
126 fn from(value: OptionCode) -> Self {
127 value.to_int()
128 }
129}
130
131
132impl fmt::Display for OptionCode {
135 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
136 use self::OptionCode::*;
137
138 match *self {
139 Llq => "LLQ".fmt(f),
140 Ul => "UL".fmt(f),
141 Nsid => "NSID".fmt(f),
142 Dau => "DAU".fmt(f),
143 Dhu => "DHU".fmt(f),
144 N3u => "N3U".fmt(f),
145 ClientSubnet => "edns-client-subnet".fmt(f),
146 Expire => "EDNS EXPIRE".fmt(f),
147 Cookie => "COOKIE".fmt(f),
148 TcpKeepalive => "edns-tcp-keepalive".fmt(f),
149 Padding => "Padding".fmt(f),
150 Chain => "CHAIN".fmt(f),
151 KeyTag => "edns-key-tag".fmt(f),
152 DeviceId => "DeviceID".fmt(f),
153 Int(value) => {
154 match OptionCode::from_int(value) {
155 Int(value) => value.fmt(f),
156 value => value.fmt(f),
157 }
158 }
159 }
160 }
161}
162
163
164impl PartialEq for OptionCode {
167 fn eq(&self, other: &Self) -> bool {
168 self.to_int() == other.to_int()
169 }
170}
171
172impl PartialEq<u16> for OptionCode {
173 fn eq(&self, other: &u16) -> bool {
174 self.to_int() == *other
175 }
176}
177
178impl PartialEq<OptionCode> for u16 {
179 fn eq(&self, other: &OptionCode) -> bool {
180 *self == other.to_int()
181 }
182}
183
184impl Eq for OptionCode { }
185
186
187impl PartialOrd for OptionCode {
190 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
191 self.to_int().partial_cmp(&other.to_int())
192 }
193}
194
195impl PartialOrd<u16> for OptionCode {
196 fn partial_cmp(&self, other: &u16) -> Option<cmp::Ordering> {
197 self.to_int().partial_cmp(other)
198 }
199}
200
201impl PartialOrd<OptionCode> for u16 {
202 fn partial_cmp(&self, other: &OptionCode) -> Option<cmp::Ordering> {
203 self.partial_cmp(&other.to_int())
204 }
205}
206
207impl Ord for OptionCode {
208 fn cmp(&self, other: &Self) -> cmp::Ordering {
209 self.to_int().cmp(&other.to_int())
210 }
211}
212
213
214impl hash::Hash for OptionCode {
217 fn hash<H: hash::Hasher>(&self, state: &mut H) {
218 self.to_int().hash(state)
219 }
220}
221