khttp 0.2.0

A low-level synchronous HTTP/1.1 server/client library
Documentation
use std::{borrow::Cow, fmt};

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Status<'a> {
    pub code: u16,
    pub reason: Cow<'a, str>,
}

impl<'a> Status<'a> {
    pub const fn borrowed(code: u16, reason: &'a str) -> Self {
        Self {
            code,
            reason: Cow::Borrowed(reason),
        }
    }
    pub fn owned(code: u16, reason: String) -> Self {
        Self {
            code,
            reason: Cow::Owned(reason),
        }
    }
}

impl fmt::Display for Status<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{} {}", self.code, self.reason)
    }
}

impl From<u16> for Status<'_> {
    fn from(code: u16) -> Self {
        Self::of(code)
    }
}

impl PartialEq<u16> for Status<'_> {
    fn eq(&self, other: &u16) -> bool {
        self.code == *other
    }
}

macro_rules! define_statuses {
    (
        common {
            $( $pcode:literal => $pident:ident, $preason:expr );* $(;)?
        }
        other {
            $( $ocode:literal => $oident:ident, $oreason:expr );* $(;)?
        }
    ) => {
        impl<'a> Status<'a> {
            $(
                pub const $pident: Status<'a> = Status::borrowed($pcode, $preason);
            )*
            $(
                const $oident: Status<'a> = Status::borrowed($ocode, $oreason);
            )*

            pub const fn of(code: u16) -> Self {
                match code {
                    $(
                        $pcode => Status::$pident,
                    )*
                    $(
                        $ocode => Status::$oident,
                    )*
                    _ => Status::borrowed(code, ""),
                }
            }
        }
    };
}

define_statuses! {
    common {
        200 => OK, "OK";
        201 => CREATED, "CREATED";
        204 => NO_CONTENT, "NO CONTENT";
        301 => MOVED_PERMANENTLY, "MOVED PERMANENTLY";
        302 => FOUND, "FOUND";
        304 => NOT_MODIFIED, "NOT MODIFIED";
        400 => BAD_REQUEST, "BAD REQUEST";
        401 => UNAUTHORIZED, "UNAUTHORIZED";
        403 => FORBIDDEN, "FORBIDDEN";
        404 => NOT_FOUND, "NOT FOUND";
        429 => TOO_MANY_REQUESTS, "TOO MANY REQUESTS";
        500 => INTERNAL_SERVER_ERROR, "INTERNAL SERVER ERROR";
        503 => SERVICE_UNAVAILABLE, "SERVICE UNAVAILABLE";
    }
    other {
        100 => CONTINUE, "CONTINUE";
        101 => SWITCHING_PROTOCOLS, "SWITCHING PROTOCOLS";
        102 => PROCESSING, "PROCESSING";
        103 => EARLY_HINTS, "EARLY HINTS";
        202 => ACCEPTED, "ACCEPTED";
        203 => NON_AUTHORITATIVE_INFORMATION, "NON-AUTHORITATIVE INFORMATION";
        205 => RESET_CONTENT, "RESET CONTENT";
        206 => PARTIAL_CONTENT, "PARTIAL CONTENT";
        207 => MULTI_STATUS, "MULTI-STATUS";
        208 => ALREADY_REPORTED, "ALREADY REPORTED";
        226 => IM_USED, "IM USED";
        300 => MULTIPLE_CHOICES, "MULTIPLE CHOICES";
        303 => SEE_OTHER, "SEE OTHER";
        305 => USE_PROXY, "USE PROXY";
        307 => TEMPORARY_REDIRECT, "TEMPORARY REDIRECT";
        308 => PERMANENT_REDIRECT, "PERMANENT REDIRECT";
        402 => PAYMENT_REQUIRED, "PAYMENT REQUIRED";
        405 => METHOD_NOT_ALLOWED, "METHOD NOT ALLOWED";
        406 => NOT_ACCEPTABLE, "NOT ACCEPTABLE";
        407 => PROXY_AUTHENTICATION_REQUIRED, "PROXY AUTHENTICATION REQUIRED";
        408 => REQUEST_TIMEOUT, "REQUEST TIMEOUT";
        409 => CONFLICT, "CONFLICT";
        410 => GONE, "GONE";
        411 => LENGTH_REQUIRED, "LENGTH REQUIRED";
        412 => PRECONDITION_FAILED, "PRECONDITION FAILED";
        413 => PAYLOAD_TOO_LARGE, "PAYLOAD TOO LARGE";
        414 => URI_TOO_LONG, "URI TOO LONG";
        415 => UNSUPPORTED_MEDIA_TYPE, "UNSUPPORTED MEDIA TYPE";
        416 => RANGE_NOT_SATISFIABLE, "RANGE NOT SATISFIABLE";
        417 => EXPECTATION_FAILED, "EXPECTATION FAILED";
        418 => IM_A_TEAPOT, "I'M A TEAPOT";
        421 => MISDIRECTED_REQUEST, "MISDIRECTED REQUEST";
        422 => UNPROCESSABLE_ENTITY, "UNPROCESSABLE ENTITY";
        423 => LOCKED, "LOCKED";
        424 => FAILED_DEPENDENCY, "FAILED DEPENDENCY";
        425 => TOO_EARLY, "TOO EARLY";
        426 => UPGRADE_REQUIRED, "UPGRADE REQUIRED";
        428 => PRECONDITION_REQUIRED, "PRECONDITION REQUIRED";
        431 => REQUEST_HEADER_FIELDS_TOO_LARGE, "REQUEST HEADER FIELDS TOO LARGE";
        451 => UNAVAILABLE_FOR_LEGAL_REASONS, "UNAVAILABLE FOR LEGAL REASONS";
        501 => NOT_IMPLEMENTED, "NOT IMPLEMENTED";
        502 => BAD_GATEWAY, "BAD GATEWAY";
        504 => GATEWAY_TIMEOUT, "GATEWAY TIMEOUT";
        505 => HTTP_VERSION_NOT_SUPPORTED, "HTTP VERSION NOT SUPPORTED";
        506 => VARIANT_ALSO_NEGOTIATES, "VARIANT ALSO NEGOTIATES";
        507 => INSUFFICIENT_STORAGE, "INSUFFICIENT STORAGE";
        508 => LOOP_DETECTED, "LOOP DETECTED";
        510 => NOT_EXTENDED, "NOT EXTENDED";
        511 => NETWORK_AUTHENTICATION_REQUIRED, "NETWORK AUTHENTICATION REQUIRED";
    }
}