1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
macro_rules! netfn {
    ($($name:ident => [$req:literal | $resp:literal]),*) => {
        #[derive(Debug, Clone, Copy, PartialEq)]
        pub enum NetFn {
            $($name,)*
            Reserved(u8),
        }

        impl From<u8> for NetFn {
            fn from(value: u8) -> Self {
                match value {
                    $($req | $resp => Self::$name,)*
                    v => Self::Reserved(v),
                }
            }
        }

        impl NetFn {
            pub fn is_response_value(v: u8) -> bool {
                v % 2 == 0
            }

            pub fn is_request_value(v: u8) -> bool {
                !Self::is_response_value(v)
            }

            pub fn request_value(&self) -> u8 {
                match self {
                    $(Self::$name => $req,)*
                    Self::Reserved(v) => {
                        if v % 2 == 1 {
                            v - 1
                        } else {
                            *v
                        }
                    }
                }
            }

            pub fn response_value(&self) -> u8 {
                match self {
                    $(Self::$name => $resp,)*
                    NetFn::Reserved(v) => {
                        if v % 2 == 0 {
                            v + 1
                        } else {
                            *v
                        }
                    }
                }
            }
        }
    };
}

netfn!(
    Chassis => [0x00 | 0x01],
    Bridge => [0x02 | 0x03],
    SensorEvent => [0x04 | 0x05],
    App => [0x06 | 0x07],
    Firmware => [0x08 | 0x09],
    Storage => [0x0A | 0x0B],
    Transport => [0x0C | 0x0D]
);