#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum Reason {
NoError = 0x00,
ProtocolError = 0x01,
InternalError = 0x02,
FlowControlError = 0x03,
SettingsTimeout = 0x04,
StreamClosed = 0x05,
FrameSizeError = 0x06,
RefusedStream = 0x07,
Cancel = 0x08,
CompressionError = 0x09,
ConnectError = 0x0a,
EnhanceYourCalm = 0x0b,
InadequateSecurity = 0x0c,
Http11Required = 0x0d,
}
impl Reason {
pub const fn code(self) -> u32 {
self as u32
}
pub const fn from_code(code: u32) -> Option<Reason> {
match code {
0x00 => Some(Reason::NoError),
0x01 => Some(Reason::ProtocolError),
0x02 => Some(Reason::InternalError),
0x03 => Some(Reason::FlowControlError),
0x04 => Some(Reason::SettingsTimeout),
0x05 => Some(Reason::StreamClosed),
0x06 => Some(Reason::FrameSizeError),
0x07 => Some(Reason::RefusedStream),
0x08 => Some(Reason::Cancel),
0x09 => Some(Reason::CompressionError),
0x0a => Some(Reason::ConnectError),
0x0b => Some(Reason::EnhanceYourCalm),
0x0c => Some(Reason::InadequateSecurity),
0x0d => Some(Reason::Http11Required),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct H2Error {
pub reason: Reason,
pub message: &'static str,
}
impl H2Error {
pub const fn new(reason: Reason, message: &'static str) -> H2Error {
H2Error { reason, message }
}
pub const fn protocol(message: &'static str) -> H2Error {
H2Error::new(Reason::ProtocolError, message)
}
pub const fn frame_size(message: &'static str) -> H2Error {
H2Error::new(Reason::FrameSizeError, message)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn codes_round_trip() {
for reason in [
Reason::NoError,
Reason::ProtocolError,
Reason::InternalError,
Reason::FlowControlError,
Reason::SettingsTimeout,
Reason::StreamClosed,
Reason::FrameSizeError,
Reason::RefusedStream,
Reason::Cancel,
Reason::CompressionError,
Reason::ConnectError,
Reason::EnhanceYourCalm,
Reason::InadequateSecurity,
Reason::Http11Required,
] {
assert_eq!(Reason::from_code(reason.code()), Some(reason));
}
assert_eq!(Reason::from_code(0x0e), None);
assert_eq!(Reason::from_code(u32::MAX), None);
}
}