docs: doc-comments for crate::status

This commit is contained in:
DarkCat09 2024-08-08 13:02:52 +04:00
parent 39b1009048
commit 61828f18d2
Signed by: DarkCat09
GPG key ID: 0A26CD5B3345D6E3

View file

@ -1,7 +1,10 @@
//! Response status code representation
use crate::error::LibError; use crate::error::LibError;
use num_enum::{IntoPrimitive, TryFromPrimitive}; use num_enum::{IntoPrimitive, TryFromPrimitive};
/// Handy representation of a Gemini response status code
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Status { pub struct Status {
status_code: StatusCode, status_code: StatusCode,
@ -9,46 +12,76 @@ pub struct Status {
second_digit: u8, second_digit: u8,
} }
/// Type of a Gemini response defined by the first digit of a status code
#[derive(Debug, Clone, Copy, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] #[derive(Debug, Clone, Copy, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)]
#[num_enum(error_type(name = LibError, constructor = LibError::status_out_of_range))] #[num_enum(error_type(name = LibError, constructor = LibError::status_out_of_range))]
#[repr(u8)] #[repr(u8)]
pub enum ReplyType { pub enum ReplyType {
/// User input in a query argument is expected for this path
Input = 1, Input = 1,
/// Request has been processed successfully, content is served
Success, Success,
/// Server redirects to another URL
Redirect, Redirect,
/// Temporary failure, try again later
TempFail, TempFail,
/// Permanent failure, request is incorrect
PermFail, PermFail,
/// Server requires authorization via client certificates to access this resource
Auth, Auth,
} }
/// 2-digit status code enum; all the codes defined in Gemini spec are listed
#[derive(Debug, Clone, Copy, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] #[derive(Debug, Clone, Copy, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)]
#[num_enum(error_type(name = LibError, constructor = LibError::status_out_of_range))] #[num_enum(error_type(name = LibError, constructor = LibError::status_out_of_range))]
#[repr(u8)] #[repr(u8)]
pub enum StatusCode { pub enum StatusCode {
/// User input is expected
Input = 10, Input = 10,
/// User input with sensitive data such as password is expected
InputSensitive = 11, InputSensitive = 11,
/// Request has been processed successfully, content is served
Success = 20, Success = 20,
/// Temporary redirection to another URL
TempRedirect = 30, TempRedirect = 30,
/// Permanent redirection to another URL
PermRedirect = 31, PermRedirect = 31,
/// General status code for temporary failures
TempFail = 40, TempFail = 40,
/// Server is unavailable due to overload or maintenance
ServerUnavailable = 41, ServerUnavailable = 41,
/// CGI process returned an error or timed out
CgiError = 42, CgiError = 42,
/// Request to a remote host was not successful
ProxyError = 43, ProxyError = 43,
/// Client must slow down requests (some kind of ratelimit)
SlowDown = 44, SlowDown = 44,
/// General status code for permanent failures
PermFail = 50, PermFail = 50,
/// Requested resource was not found
NotFound = 51, NotFound = 51,
/// Requested resource is no longer available
Gone = 52, Gone = 52,
/// Given URL is not meant to be processed by this server
/// (host does not match, scheme is not `gemini://`, etc.),
/// but the server does not accept proxy requests
ProxyRequestRefused = 53, ProxyRequestRefused = 53,
/// Server is unable to parse the request
BadRequest = 59, BadRequest = 59,
/// Client certificate is required to access the content
ClientCerts = 60, ClientCerts = 60,
/// Provided certificate is not authorized for accessing this resource
CertNotAuthorized = 61, CertNotAuthorized = 61,
/// Provided certificate is not valid: violates X.509 standard,
/// has invalid signature or expiry date
CertNotValid = 62, CertNotValid = 62,
/// Undefined status code between 10 and 69 inclusive
// 1..6 first digit range check is still // 1..6 first digit range check is still
// covered by conversion into ReplyType // covered by conversion into ReplyType
// (see Status::parse_status) // (see Status::parse_status)
@ -59,6 +92,8 @@ pub enum StatusCode {
const ASCII_ZERO: u8 = 48; // '0' const ASCII_ZERO: u8 = 48; // '0'
impl Status { impl Status {
/// Take first two bytes from the buffer and parse them as a status code,
/// returning [`Status`] on success or [`LibError::StatusOutOfRange`] on error
pub fn parse_status(buf: &[u8]) -> Result<Self, LibError> { pub fn parse_status(buf: &[u8]) -> Result<Self, LibError> {
// simple decimal digit conversion // simple decimal digit conversion
// '2' - '0' = 50 - 48 = 2 (from byte '2' to uint 2) // '2' - '0' = 50 - 48 = 2 (from byte '2' to uint 2)
@ -77,18 +112,22 @@ impl Status {
}) })
} }
/// Get the 2-digit status code as a [`StatusCode`] enum item
pub fn status_code(&self) -> StatusCode { pub fn status_code(&self) -> StatusCode {
self.status_code self.status_code
} }
/// Get this status code as a number
pub fn num(&self) -> u8 { pub fn num(&self) -> u8 {
self.status_code.into() self.status_code.into()
} }
/// Get the response type (the first digit) as a [`ReplyType`] enum item
pub fn reply_type(&self) -> ReplyType { pub fn reply_type(&self) -> ReplyType {
self.reply_type self.reply_type
} }
/// Get the second digit of this status code
pub fn second_digit(&self) -> u8 { pub fn second_digit(&self) -> u8 {
self.second_digit self.second_digit
} }