91 lines
2.1 KiB
Rust
91 lines
2.1 KiB
Rust
use crate::error::LibError;
|
|
|
|
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct Status {
|
|
status_code: StatusCode,
|
|
reply_type: ReplyType,
|
|
second_digit: u8,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)]
|
|
#[num_enum(error_type(name = LibError, constructor = LibError::status_out_of_range))]
|
|
#[repr(u8)]
|
|
pub enum ReplyType {
|
|
Input = 1,
|
|
Success,
|
|
Redirect,
|
|
TempFail,
|
|
PermFail,
|
|
Auth,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)]
|
|
#[num_enum(error_type(name = LibError, constructor = LibError::status_out_of_range))]
|
|
#[repr(u8)]
|
|
pub enum StatusCode {
|
|
Input = 10,
|
|
InputSensitive = 11,
|
|
|
|
Success = 20,
|
|
|
|
TempRedirect = 30,
|
|
PermRedirect = 31,
|
|
|
|
TempFail = 40,
|
|
ServerUnavailable = 41,
|
|
CgiError = 42,
|
|
ProxyError = 43,
|
|
SlowDown = 44,
|
|
|
|
PermFail = 50,
|
|
NotFound = 51,
|
|
Gone = 52,
|
|
ProxyRequestRefused = 53,
|
|
BadRequest = 59,
|
|
|
|
ClientCerts = 60,
|
|
CertNotAuthorized = 61,
|
|
CertNotValid = 62,
|
|
|
|
// 1..6 first digit range check is still
|
|
// covered by conversion into ReplyType
|
|
// (see Status::parse_status)
|
|
#[num_enum(catch_all)]
|
|
Unknown(u8),
|
|
}
|
|
|
|
const ASCII_ZERO: u8 = 48; // '0'
|
|
|
|
impl Status {
|
|
pub fn parse_status(buf: &[u8]) -> Result<Self, LibError> {
|
|
// simple decimal digit conversion
|
|
// '2' - '0' = 50 - 48 = 2 (from byte '2' to uint 2)
|
|
let first = buf[0] - ASCII_ZERO;
|
|
let second = buf[1] - ASCII_ZERO;
|
|
|
|
let code = first * 10 + second;
|
|
|
|
Ok(Status {
|
|
// get enum item for 2-digit status code
|
|
status_code: StatusCode::try_from_primitive(code)?,
|
|
// get enum entry for first digit
|
|
reply_type: ReplyType::try_from_primitive(first)?,
|
|
// provide separate field for the 2nd digit
|
|
second_digit: second,
|
|
})
|
|
}
|
|
|
|
pub fn status_code(self: &Self) -> StatusCode {
|
|
self.status_code
|
|
}
|
|
|
|
pub fn reply_type(self: &Self) -> ReplyType {
|
|
self.reply_type
|
|
}
|
|
|
|
pub fn second_digit(self: &Self) -> u8 {
|
|
self.second_digit
|
|
}
|
|
}
|