/rust/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.23.29/src/msgs/enums.rs
Line | Count | Source (jump to first uncovered line) |
1 | | #![allow(clippy::upper_case_acronyms)] |
2 | | #![allow(non_camel_case_types)] |
3 | | use crate::crypto::{KeyExchangeAlgorithm, hash}; |
4 | | use crate::msgs::codec::{Codec, Reader}; |
5 | | |
6 | | enum_builder! { |
7 | | /// The `HashAlgorithm` TLS protocol enum. Values in this enum are taken |
8 | | /// from the various RFCs covering TLS, and are listed by IANA. |
9 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
10 | | #[repr(u8)] |
11 | | pub enum HashAlgorithm { |
12 | | NONE => 0x00, |
13 | | MD5 => 0x01, |
14 | | SHA1 => 0x02, |
15 | | SHA224 => 0x03, |
16 | | SHA256 => 0x04, |
17 | | SHA384 => 0x05, |
18 | | SHA512 => 0x06, |
19 | | } |
20 | | } |
21 | | |
22 | | impl HashAlgorithm { |
23 | | /// Returns the hash of the empty input. |
24 | | /// |
25 | | /// This returns `None` for some hash algorithms, so the caller |
26 | | /// should be prepared to do the computation themselves in this case. |
27 | 0 | pub(crate) fn hash_for_empty_input(&self) -> Option<hash::Output> { |
28 | 0 | match self { |
29 | 0 | Self::SHA256 => Some(hash::Output::new( |
30 | 0 | b"\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\ |
31 | 0 | \x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\ |
32 | 0 | \x27\xae\x41\xe4\x64\x9b\x93\x4c\ |
33 | 0 | \xa4\x95\x99\x1b\x78\x52\xb8\x55", |
34 | 0 | )), |
35 | 0 | Self::SHA384 => Some(hash::Output::new( |
36 | 0 | b"\x38\xb0\x60\xa7\x51\xac\x96\x38\ |
37 | 0 | \x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a\ |
38 | 0 | \x21\xfd\xb7\x11\x14\xbe\x07\x43\ |
39 | 0 | \x4c\x0c\xc7\xbf\x63\xf6\xe1\xda\ |
40 | 0 | \x27\x4e\xde\xbf\xe7\x6f\x65\xfb\ |
41 | 0 | \xd5\x1a\xd2\xf1\x48\x98\xb9\x5b", |
42 | 0 | )), |
43 | 0 | _ => None, |
44 | | } |
45 | 0 | } Unexecuted instantiation: <rustls::msgs::enums::HashAlgorithm>::hash_for_empty_input Unexecuted instantiation: <rustls::msgs::enums::HashAlgorithm>::hash_for_empty_input |
46 | | } |
47 | | |
48 | | enum_builder! { |
49 | | /// The `ClientCertificateType` TLS protocol enum. Values in this enum are taken |
50 | | /// from the various RFCs covering TLS, and are listed by IANA. |
51 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
52 | | #[repr(u8)] |
53 | | pub(crate) enum ClientCertificateType { |
54 | | RSASign => 0x01, |
55 | | DSSSign => 0x02, |
56 | | RSAFixedDH => 0x03, |
57 | | DSSFixedDH => 0x04, |
58 | | RSAEphemeralDH => 0x05, |
59 | | DSSEphemeralDH => 0x06, |
60 | | FortezzaDMS => 0x14, |
61 | | ECDSASign => 0x40, |
62 | | RSAFixedECDH => 0x41, |
63 | | ECDSAFixedECDH => 0x42, |
64 | | } |
65 | | } |
66 | | |
67 | | enum_builder! { |
68 | | /// The `Compression` TLS protocol enum. Values in this enum are taken |
69 | | /// from the various RFCs covering TLS, and are listed by IANA. |
70 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
71 | | #[repr(u8)] |
72 | | pub enum Compression { |
73 | | Null => 0x00, |
74 | | Deflate => 0x01, |
75 | | LSZ => 0x40, |
76 | | } |
77 | | } |
78 | | |
79 | | enum_builder! { |
80 | | /// The `AlertLevel` TLS protocol enum. Values in this enum are taken |
81 | | /// from the various RFCs covering TLS, and are listed by IANA. |
82 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
83 | | #[repr(u8)] |
84 | | pub enum AlertLevel { |
85 | | Warning => 0x01, |
86 | | Fatal => 0x02, |
87 | | } |
88 | | } |
89 | | |
90 | | enum_builder! { |
91 | | /// The `HeartbeatMessageType` TLS protocol enum. Values in this enum are taken |
92 | | /// from the various RFCs covering TLS, and are listed by IANA. |
93 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
94 | | #[repr(u8)] |
95 | | pub(crate) enum HeartbeatMessageType { |
96 | | Request => 0x01, |
97 | | Response => 0x02, |
98 | | } |
99 | | } |
100 | | |
101 | | enum_builder! { |
102 | | /// The `ExtensionType` TLS protocol enum. Values in this enum are taken |
103 | | /// from the various RFCs covering TLS, and are listed by IANA. |
104 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
105 | | #[repr(u16)] |
106 | | pub enum ExtensionType { |
107 | | ServerName => 0x0000, |
108 | | MaxFragmentLength => 0x0001, |
109 | | ClientCertificateUrl => 0x0002, |
110 | | TrustedCAKeys => 0x0003, |
111 | | TruncatedHMAC => 0x0004, |
112 | | StatusRequest => 0x0005, |
113 | | UserMapping => 0x0006, |
114 | | ClientAuthz => 0x0007, |
115 | | ServerAuthz => 0x0008, |
116 | | CertificateType => 0x0009, |
117 | | EllipticCurves => 0x000a, |
118 | | ECPointFormats => 0x000b, |
119 | | SRP => 0x000c, |
120 | | SignatureAlgorithms => 0x000d, |
121 | | UseSRTP => 0x000e, |
122 | | Heartbeat => 0x000f, |
123 | | ALProtocolNegotiation => 0x0010, |
124 | | SCT => 0x0012, |
125 | | ClientCertificateType => 0x0013, |
126 | | ServerCertificateType => 0x0014, |
127 | | Padding => 0x0015, |
128 | | ExtendedMasterSecret => 0x0017, |
129 | | CompressCertificate => 0x001b, |
130 | | SessionTicket => 0x0023, |
131 | | PreSharedKey => 0x0029, |
132 | | EarlyData => 0x002a, |
133 | | SupportedVersions => 0x002b, |
134 | | Cookie => 0x002c, |
135 | | PSKKeyExchangeModes => 0x002d, |
136 | | TicketEarlyDataInfo => 0x002e, |
137 | | CertificateAuthorities => 0x002f, |
138 | | OIDFilters => 0x0030, |
139 | | PostHandshakeAuth => 0x0031, |
140 | | SignatureAlgorithmsCert => 0x0032, |
141 | | KeyShare => 0x0033, |
142 | | TransportParameters => 0x0039, |
143 | | NextProtocolNegotiation => 0x3374, |
144 | | ChannelId => 0x754f, |
145 | | RenegotiationInfo => 0xff01, |
146 | | TransportParametersDraft => 0xffa5, |
147 | | EncryptedClientHello => 0xfe0d, // https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-11.1 |
148 | | EncryptedClientHelloOuterExtensions => 0xfd00, // https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-5.1 |
149 | | } |
150 | | } |
151 | | |
152 | | impl ExtensionType { |
153 | | /// Returns true if the extension type can be compressed in an "inner" client hello for ECH. |
154 | | /// |
155 | | /// This function should only return true for extension types where the inner hello and outer |
156 | | /// hello extensions values will always be identical. Extensions that may be identical |
157 | | /// sometimes (e.g. server name, cert compression methods), but not always, SHOULD NOT be |
158 | | /// compressed. |
159 | | /// |
160 | | /// See [draft-ietf-esni-18 §5](https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-5) |
161 | | /// and [draft-ietf-esni-18 §10.5](https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-10.5) |
162 | | /// for more information. |
163 | 0 | pub(crate) fn ech_compress(&self) -> bool { |
164 | | // We match which extensions we will compress with BoringSSL and Go's stdlib. |
165 | 0 | matches!( |
166 | 0 | self, |
167 | | Self::StatusRequest |
168 | | | Self::EllipticCurves |
169 | | | Self::SignatureAlgorithms |
170 | | | Self::SignatureAlgorithmsCert |
171 | | | Self::ALProtocolNegotiation |
172 | | | Self::SupportedVersions |
173 | | | Self::Cookie |
174 | | | Self::KeyShare |
175 | | | Self::PSKKeyExchangeModes |
176 | | ) |
177 | 0 | } Unexecuted instantiation: <rustls::msgs::enums::ExtensionType>::ech_compress Unexecuted instantiation: <rustls::msgs::enums::ExtensionType>::ech_compress |
178 | | } |
179 | | |
180 | | enum_builder! { |
181 | | /// The `ServerNameType` TLS protocol enum. Values in this enum are taken |
182 | | /// from the various RFCs covering TLS, and are listed by IANA. |
183 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
184 | | #[repr(u8)] |
185 | | pub(crate) enum ServerNameType { |
186 | | HostName => 0x00, |
187 | | } |
188 | | } |
189 | | |
190 | | enum_builder! { |
191 | | /// The `NamedCurve` TLS protocol enum. Values in this enum are taken |
192 | | /// from the various RFCs covering TLS, and are listed by IANA. |
193 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
194 | | /// |
195 | | /// This enum is used for recognizing elliptic curve parameters advertised |
196 | | /// by a peer during a TLS handshake. It is **not** a list of curves that |
197 | | /// Rustls supports. See [`crate::crypto::ring::kx_group`] for the list of supported |
198 | | /// elliptic curve groups. |
199 | | #[repr(u16)] |
200 | | pub(crate) enum NamedCurve { |
201 | | sect163k1 => 0x0001, |
202 | | sect163r1 => 0x0002, |
203 | | sect163r2 => 0x0003, |
204 | | sect193r1 => 0x0004, |
205 | | sect193r2 => 0x0005, |
206 | | sect233k1 => 0x0006, |
207 | | sect233r1 => 0x0007, |
208 | | sect239k1 => 0x0008, |
209 | | sect283k1 => 0x0009, |
210 | | sect283r1 => 0x000a, |
211 | | sect409k1 => 0x000b, |
212 | | sect409r1 => 0x000c, |
213 | | sect571k1 => 0x000d, |
214 | | sect571r1 => 0x000e, |
215 | | secp160k1 => 0x000f, |
216 | | secp160r1 => 0x0010, |
217 | | secp160r2 => 0x0011, |
218 | | secp192k1 => 0x0012, |
219 | | secp192r1 => 0x0013, |
220 | | secp224k1 => 0x0014, |
221 | | secp224r1 => 0x0015, |
222 | | secp256k1 => 0x0016, |
223 | | secp256r1 => 0x0017, |
224 | | secp384r1 => 0x0018, |
225 | | secp521r1 => 0x0019, |
226 | | brainpoolp256r1 => 0x001a, |
227 | | brainpoolp384r1 => 0x001b, |
228 | | brainpoolp512r1 => 0x001c, |
229 | | X25519 => 0x001d, |
230 | | X448 => 0x001e, |
231 | | arbitrary_explicit_prime_curves => 0xff01, |
232 | | arbitrary_explicit_char2_curves => 0xff02, |
233 | | } |
234 | | } |
235 | | |
236 | | enum_builder! { |
237 | | /// The `NamedGroup` TLS protocol enum. Values in this enum are taken |
238 | | /// from the various RFCs covering TLS, and are listed by IANA. |
239 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
240 | | #[repr(u16)] |
241 | | pub enum NamedGroup { |
242 | | secp256r1 => 0x0017, |
243 | | secp384r1 => 0x0018, |
244 | | secp521r1 => 0x0019, |
245 | | X25519 => 0x001d, |
246 | | X448 => 0x001e, |
247 | | FFDHE2048 => 0x0100, |
248 | | FFDHE3072 => 0x0101, |
249 | | FFDHE4096 => 0x0102, |
250 | | FFDHE6144 => 0x0103, |
251 | | FFDHE8192 => 0x0104, |
252 | | MLKEM512 => 0x0200, |
253 | | MLKEM768 => 0x0201, |
254 | | MLKEM1024 => 0x0202, |
255 | | secp256r1MLKEM768 => 0x11eb, |
256 | | X25519MLKEM768 => 0x11ec, |
257 | | } |
258 | | } |
259 | | |
260 | | impl NamedGroup { |
261 | | /// Return the key exchange algorithm associated with this `NamedGroup` |
262 | 0 | pub fn key_exchange_algorithm(self) -> KeyExchangeAlgorithm { |
263 | 0 | match u16::from(self) { |
264 | 0 | x if (0x100..0x200).contains(&x) => KeyExchangeAlgorithm::DHE, |
265 | 0 | _ => KeyExchangeAlgorithm::ECDHE, |
266 | | } |
267 | 0 | } Unexecuted instantiation: <rustls::msgs::enums::NamedGroup>::key_exchange_algorithm Unexecuted instantiation: <rustls::msgs::enums::NamedGroup>::key_exchange_algorithm |
268 | | } |
269 | | |
270 | | enum_builder! { |
271 | | /// The `ECPointFormat` TLS protocol enum. Values in this enum are taken |
272 | | /// from the various RFCs covering TLS, and are listed by IANA. |
273 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
274 | | #[repr(u8)] |
275 | | pub enum ECPointFormat { |
276 | | Uncompressed => 0x00, |
277 | | ANSIX962CompressedPrime => 0x01, |
278 | | ANSIX962CompressedChar2 => 0x02, |
279 | | } |
280 | | } |
281 | | |
282 | | enum_builder! { |
283 | | /// The `HeartbeatMode` TLS protocol enum. Values in this enum are taken |
284 | | /// from the various RFCs covering TLS, and are listed by IANA. |
285 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
286 | | #[repr(u8)] |
287 | | pub(crate) enum HeartbeatMode { |
288 | | PeerAllowedToSend => 0x01, |
289 | | PeerNotAllowedToSend => 0x02, |
290 | | } |
291 | | } |
292 | | |
293 | | enum_builder! { |
294 | | /// The `ECCurveType` TLS protocol enum. Values in this enum are taken |
295 | | /// from the various RFCs covering TLS, and are listed by IANA. |
296 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
297 | | #[repr(u8)] |
298 | | pub(crate) enum ECCurveType { |
299 | | ExplicitPrime => 0x01, |
300 | | ExplicitChar2 => 0x02, |
301 | | NamedCurve => 0x03, |
302 | | } |
303 | | } |
304 | | |
305 | | enum_builder! { |
306 | | /// The `PskKeyExchangeMode` TLS protocol enum. Values in this enum are taken |
307 | | /// from the various RFCs covering TLS, and are listed by IANA. |
308 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
309 | | #[repr(u8)] |
310 | | pub enum PskKeyExchangeMode { |
311 | | PSK_KE => 0x00, |
312 | | PSK_DHE_KE => 0x01, |
313 | | } |
314 | | } |
315 | | |
316 | | enum_builder! { |
317 | | /// The `KeyUpdateRequest` TLS protocol enum. Values in this enum are taken |
318 | | /// from the various RFCs covering TLS, and are listed by IANA. |
319 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
320 | | #[repr(u8)] |
321 | | pub enum KeyUpdateRequest { |
322 | | UpdateNotRequested => 0x00, |
323 | | UpdateRequested => 0x01, |
324 | | } |
325 | | } |
326 | | |
327 | | enum_builder! { |
328 | | /// The `CertificateStatusType` TLS protocol enum. Values in this enum are taken |
329 | | /// from the various RFCs covering TLS, and are listed by IANA. |
330 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
331 | | #[repr(u8)] |
332 | | pub enum CertificateStatusType { |
333 | | OCSP => 0x01, |
334 | | } |
335 | | } |
336 | | |
337 | | enum_builder! { |
338 | | /// The Key Encapsulation Mechanism (`Kem`) type for HPKE operations. |
339 | | /// Listed by IANA, as specified in [RFC 9180 Section 7.1] |
340 | | /// |
341 | | /// [RFC 9180 Section 7.1]: <https://datatracker.ietf.org/doc/html/rfc9180#kemid-values> |
342 | | #[repr(u16)] |
343 | | pub enum HpkeKem { |
344 | | DHKEM_P256_HKDF_SHA256 => 0x0010, |
345 | | DHKEM_P384_HKDF_SHA384 => 0x0011, |
346 | | DHKEM_P521_HKDF_SHA512 => 0x0012, |
347 | | DHKEM_X25519_HKDF_SHA256 => 0x0020, |
348 | | DHKEM_X448_HKDF_SHA512 => 0x0021, |
349 | | } |
350 | | } |
351 | | |
352 | | enum_builder! { |
353 | | /// The Key Derivation Function (`Kdf`) type for HPKE operations. |
354 | | /// Listed by IANA, as specified in [RFC 9180 Section 7.2] |
355 | | /// |
356 | | /// [RFC 9180 Section 7.2]: <https://datatracker.ietf.org/doc/html/rfc9180#name-key-derivation-functions-kd> |
357 | | #[repr(u16)] |
358 | | pub enum HpkeKdf { |
359 | | HKDF_SHA256 => 0x0001, |
360 | | HKDF_SHA384 => 0x0002, |
361 | | HKDF_SHA512 => 0x0003, |
362 | | } |
363 | | } |
364 | | |
365 | | impl Default for HpkeKdf { |
366 | | // TODO(XXX): revisit the default configuration. This is just what Cloudflare ships right now. |
367 | 0 | fn default() -> Self { |
368 | 0 | Self::HKDF_SHA256 |
369 | 0 | } Unexecuted instantiation: <rustls::msgs::enums::HpkeKdf as core::default::Default>::default Unexecuted instantiation: <rustls::msgs::enums::HpkeKdf as core::default::Default>::default |
370 | | } |
371 | | |
372 | | enum_builder! { |
373 | | /// The Authenticated Encryption with Associated Data (`Aead`) type for HPKE operations. |
374 | | /// Listed by IANA, as specified in [RFC 9180 Section 7.3] |
375 | | /// |
376 | | /// [RFC 9180 Section 7.3]: <https://datatracker.ietf.org/doc/html/rfc9180#name-authenticated-encryption-wi> |
377 | | #[repr(u16)] |
378 | | pub enum HpkeAead { |
379 | | AES_128_GCM => 0x0001, |
380 | | AES_256_GCM => 0x0002, |
381 | | CHACHA20_POLY_1305 => 0x0003, |
382 | | EXPORT_ONLY => 0xFFFF, |
383 | | } |
384 | | } |
385 | | |
386 | | impl HpkeAead { |
387 | | /// Returns the length of the tag for the AEAD algorithm, or none if the AEAD is EXPORT_ONLY. |
388 | 0 | pub(crate) fn tag_len(&self) -> Option<usize> { |
389 | 0 | match self { |
390 | | // See RFC 9180 Section 7.3, column `Nt`, the length in bytes of the authentication tag |
391 | | // for the algorithm. |
392 | | // https://www.rfc-editor.org/rfc/rfc9180.html#section-7.3 |
393 | 0 | Self::AES_128_GCM | Self::AES_256_GCM | Self::CHACHA20_POLY_1305 => Some(16), |
394 | 0 | _ => None, |
395 | | } |
396 | 0 | } Unexecuted instantiation: <rustls::msgs::enums::HpkeAead>::tag_len Unexecuted instantiation: <rustls::msgs::enums::HpkeAead>::tag_len |
397 | | } |
398 | | |
399 | | impl Default for HpkeAead { |
400 | | // TODO(XXX): revisit the default configuration. This is just what Cloudflare ships right now. |
401 | 0 | fn default() -> Self { |
402 | 0 | Self::AES_128_GCM |
403 | 0 | } Unexecuted instantiation: <rustls::msgs::enums::HpkeAead as core::default::Default>::default Unexecuted instantiation: <rustls::msgs::enums::HpkeAead as core::default::Default>::default |
404 | | } |
405 | | |
406 | | enum_builder! { |
407 | | /// The Encrypted Client Hello protocol version (`EchVersion`). |
408 | | /// |
409 | | /// Specified in [draft-ietf-tls-esni Section 4]. |
410 | | /// TODO(XXX): Update reference once RFC is published. |
411 | | /// |
412 | | /// [draft-ietf-tls-esni Section 4]: <https://www.ietf.org/archive/id/draft-ietf-tls-esni-17.html#section-4> |
413 | | #[repr(u16)] |
414 | | pub enum EchVersion { |
415 | | V18 => 0xfe0d, |
416 | | } |
417 | | } |
418 | | |
419 | | #[cfg(test)] |
420 | | pub(crate) mod tests { |
421 | | // These tests are intended to provide coverage and |
422 | | // check panic-safety of relatively unused values. |
423 | | |
424 | | use std::prelude::v1::*; |
425 | | |
426 | | use super::*; |
427 | | |
428 | | #[test] |
429 | | fn test_enums() { |
430 | | test_enum8::<HashAlgorithm>(HashAlgorithm::NONE, HashAlgorithm::SHA512); |
431 | | test_enum8::<ClientCertificateType>( |
432 | | ClientCertificateType::RSASign, |
433 | | ClientCertificateType::ECDSAFixedECDH, |
434 | | ); |
435 | | test_enum8::<Compression>(Compression::Null, Compression::LSZ); |
436 | | test_enum8::<AlertLevel>(AlertLevel::Warning, AlertLevel::Fatal); |
437 | | test_enum8::<HeartbeatMessageType>( |
438 | | HeartbeatMessageType::Request, |
439 | | HeartbeatMessageType::Response, |
440 | | ); |
441 | | test_enum16::<ExtensionType>(ExtensionType::ServerName, ExtensionType::RenegotiationInfo); |
442 | | test_enum8::<ServerNameType>(ServerNameType::HostName, ServerNameType::HostName); |
443 | | test_enum16::<NamedCurve>( |
444 | | NamedCurve::sect163k1, |
445 | | NamedCurve::arbitrary_explicit_char2_curves, |
446 | | ); |
447 | | test_enum16::<NamedGroup>(NamedGroup::secp256r1, NamedGroup::FFDHE8192); |
448 | | test_enum8::<ECPointFormat>( |
449 | | ECPointFormat::Uncompressed, |
450 | | ECPointFormat::ANSIX962CompressedChar2, |
451 | | ); |
452 | | test_enum8::<HeartbeatMode>( |
453 | | HeartbeatMode::PeerAllowedToSend, |
454 | | HeartbeatMode::PeerNotAllowedToSend, |
455 | | ); |
456 | | test_enum8::<ECCurveType>(ECCurveType::ExplicitPrime, ECCurveType::NamedCurve); |
457 | | test_enum8::<PskKeyExchangeMode>( |
458 | | PskKeyExchangeMode::PSK_KE, |
459 | | PskKeyExchangeMode::PSK_DHE_KE, |
460 | | ); |
461 | | test_enum8::<KeyUpdateRequest>( |
462 | | KeyUpdateRequest::UpdateNotRequested, |
463 | | KeyUpdateRequest::UpdateRequested, |
464 | | ); |
465 | | test_enum8::<CertificateStatusType>( |
466 | | CertificateStatusType::OCSP, |
467 | | CertificateStatusType::OCSP, |
468 | | ); |
469 | | } |
470 | | |
471 | | pub(crate) fn test_enum8<T: for<'a> Codec<'a>>(first: T, last: T) { |
472 | | let first_v = get8(&first); |
473 | | let last_v = get8(&last); |
474 | | |
475 | | for val in first_v..last_v + 1 { |
476 | | let mut buf = Vec::new(); |
477 | | val.encode(&mut buf); |
478 | | assert_eq!(buf.len(), 1); |
479 | | |
480 | | let t = T::read_bytes(&buf).unwrap(); |
481 | | assert_eq!(val, get8(&t)); |
482 | | } |
483 | | } |
484 | | |
485 | | pub(crate) fn test_enum16<T: for<'a> Codec<'a>>(first: T, last: T) { |
486 | | let first_v = get16(&first); |
487 | | let last_v = get16(&last); |
488 | | |
489 | | for val in first_v..last_v + 1 { |
490 | | let mut buf = Vec::new(); |
491 | | val.encode(&mut buf); |
492 | | assert_eq!(buf.len(), 2); |
493 | | |
494 | | let t = T::read_bytes(&buf).unwrap(); |
495 | | assert_eq!(val, get16(&t)); |
496 | | } |
497 | | } |
498 | | |
499 | | fn get8<T: for<'a> Codec<'a>>(enum_value: &T) -> u8 { |
500 | | let enc = enum_value.get_encoding(); |
501 | | assert_eq!(enc.len(), 1); |
502 | | enc[0] |
503 | | } |
504 | | |
505 | | fn get16<T: for<'a> Codec<'a>>(enum_value: &T) -> u16 { |
506 | | let enc = enum_value.get_encoding(); |
507 | | assert_eq!(enc.len(), 2); |
508 | | (enc[0] as u16 >> 8) | (enc[1] as u16) |
509 | | } |
510 | | } |