1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[repr(u32)]
6pub enum Reason {
7 NoError = 0x00,
8 ProtocolError = 0x01,
9 InternalError = 0x02,
10 FlowControlError = 0x03,
11 SettingsTimeout = 0x04,
12 StreamClosed = 0x05,
13 FrameSizeError = 0x06,
14 RefusedStream = 0x07,
15 Cancel = 0x08,
16 CompressionError = 0x09,
17 ConnectError = 0x0a,
18 EnhanceYourCalm = 0x0b,
19 InadequateSecurity = 0x0c,
20 Http11Required = 0x0d,
21}
22
23impl Reason {
24 pub const fn code(self) -> u32 {
26 self as u32
27 }
28
29 pub const fn from_code(code: u32) -> Option<Reason> {
32 match code {
33 0x00 => Some(Reason::NoError),
34 0x01 => Some(Reason::ProtocolError),
35 0x02 => Some(Reason::InternalError),
36 0x03 => Some(Reason::FlowControlError),
37 0x04 => Some(Reason::SettingsTimeout),
38 0x05 => Some(Reason::StreamClosed),
39 0x06 => Some(Reason::FrameSizeError),
40 0x07 => Some(Reason::RefusedStream),
41 0x08 => Some(Reason::Cancel),
42 0x09 => Some(Reason::CompressionError),
43 0x0a => Some(Reason::ConnectError),
44 0x0b => Some(Reason::EnhanceYourCalm),
45 0x0c => Some(Reason::InadequateSecurity),
46 0x0d => Some(Reason::Http11Required),
47 _ => None,
48 }
49 }
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct H2Error {
56 pub reason: Reason,
57 pub message: &'static str,
58}
59
60impl H2Error {
61 pub const fn new(reason: Reason, message: &'static str) -> H2Error {
64 H2Error { reason, message }
65 }
66
67 pub const fn protocol(message: &'static str) -> H2Error {
69 H2Error::new(Reason::ProtocolError, message)
70 }
71
72 pub const fn frame_size(message: &'static str) -> H2Error {
74 H2Error::new(Reason::FrameSizeError, message)
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn codes_round_trip() {
84 for reason in [
85 Reason::NoError,
86 Reason::ProtocolError,
87 Reason::InternalError,
88 Reason::FlowControlError,
89 Reason::SettingsTimeout,
90 Reason::StreamClosed,
91 Reason::FrameSizeError,
92 Reason::RefusedStream,
93 Reason::Cancel,
94 Reason::CompressionError,
95 Reason::ConnectError,
96 Reason::EnhanceYourCalm,
97 Reason::InadequateSecurity,
98 Reason::Http11Required,
99 ] {
100 assert_eq!(Reason::from_code(reason.code()), Some(reason));
101 }
102 assert_eq!(Reason::from_code(0x0e), None);
103 assert_eq!(Reason::from_code(u32::MAX), None);
104 }
105}