1 /// Code value in an ICMPv4 Redirect message.
2 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
3 pub enum RedirectCode {
4     /// Redirect Datagram for the Network (or subnet)
5     RedirectForNetwork = 0,
6     /// Redirect Datagram for the Host
7     RedirectForHost = 1,
8     /// Redirect Datagram for the Type of Service and Network
9     RedirectForTypeOfServiceAndNetwork = 2,
10     /// Redirect datagrams for the Type of Service and Host
11     RedirectForTypeOfServiceAndHost = 3,
12 }
13 
14 impl RedirectCode {
15     /// Tries to convert a code [`u8`] value to a [`RedirectCode`] value.
16     ///
17     /// Returns [`None`] in case the code value is not known as a redirect code.
18     #[inline]
from_u8(code_u8: u8) -> Option<RedirectCode>19     pub fn from_u8(code_u8: u8) -> Option<RedirectCode> {
20         use crate::icmpv4::{RedirectCode::*, *};
21         match code_u8 {
22             CODE_REDIRECT_FOR_NETWORK => Some(RedirectForNetwork),
23             CODE_REDIRECT_FOR_HOST => Some(RedirectForHost),
24             CODE_REDIRECT_TYPE_OF_SERVICE_AND_NETWORK => Some(RedirectForTypeOfServiceAndNetwork),
25             CODE_REDIRECT_TYPE_OF_SERVICE_AND_HOST => Some(RedirectForTypeOfServiceAndHost),
26             _ => None,
27         }
28     }
29 
30     /// Returns the [`u8`] value of the code.
31     #[inline]
code_u8(&self) -> u832     pub fn code_u8(&self) -> u8 {
33         *self as u8
34     }
35 }
36 
37 #[cfg(test)]
38 
39 mod test {
40     use crate::icmpv4::{RedirectCode::*, *};
41     use alloc::format;
42 
43     #[test]
from_u8()44     fn from_u8() {
45         let tests = [
46             (CODE_REDIRECT_FOR_NETWORK, RedirectForNetwork),
47             (CODE_REDIRECT_FOR_HOST, RedirectForHost),
48             (
49                 CODE_REDIRECT_TYPE_OF_SERVICE_AND_NETWORK,
50                 RedirectForTypeOfServiceAndNetwork,
51             ),
52             (
53                 CODE_REDIRECT_TYPE_OF_SERVICE_AND_HOST,
54                 RedirectForTypeOfServiceAndHost,
55             ),
56         ];
57         for t in tests {
58             assert_eq!(Some(t.1), RedirectCode::from_u8(t.0));
59         }
60         for code_u8 in 4..=u8::MAX {
61             assert_eq!(None, RedirectCode::from_u8(code_u8));
62         }
63     }
64 
65     #[test]
code_u8()66     fn code_u8() {
67         let tests = [
68             (CODE_REDIRECT_FOR_NETWORK, RedirectForNetwork),
69             (CODE_REDIRECT_FOR_HOST, RedirectForHost),
70             (
71                 CODE_REDIRECT_TYPE_OF_SERVICE_AND_NETWORK,
72                 RedirectForTypeOfServiceAndNetwork,
73             ),
74             (
75                 CODE_REDIRECT_TYPE_OF_SERVICE_AND_HOST,
76                 RedirectForTypeOfServiceAndHost,
77             ),
78         ];
79         for t in tests {
80             assert_eq!(t.1.code_u8(), t.0);
81         }
82     }
83 
84     #[test]
clone_eq()85     fn clone_eq() {
86         let tests = [
87             RedirectForNetwork,
88             RedirectForHost,
89             RedirectForTypeOfServiceAndNetwork,
90             RedirectForTypeOfServiceAndHost,
91         ];
92         for t in tests {
93             assert_eq!(t.clone(), t);
94         }
95     }
96 
97     #[test]
debug()98     fn debug() {
99         let tests = [
100             ("RedirectForNetwork", RedirectForNetwork),
101             ("RedirectForHost", RedirectForHost),
102             (
103                 "RedirectForTypeOfServiceAndNetwork",
104                 RedirectForTypeOfServiceAndNetwork,
105             ),
106             (
107                 "RedirectForTypeOfServiceAndHost",
108                 RedirectForTypeOfServiceAndHost,
109             ),
110         ];
111         for t in tests {
112             assert_eq!(t.0, format!("{:?}", t.1));
113         }
114     }
115 }
116