Skip to main content

scrapling_fetch/
status.rs

1//! HTTP status code to reason phrase mapping.
2//!
3//! This module provides a single function, [`status_text`], that maps numeric HTTP
4//! status codes to their standard reason phrases (e.g., 200 -> "OK", 404 -> "Not Found").
5//! It is used by [`Response::new`](crate::Response::new) to populate the `reason` field
6//! when the upstream HTTP client does not provide one.
7//!
8//! The lookup table covers all standard status codes defined in RFCs 7231, 7538, 6585,
9//! 4918, and others, including informational oddities like 418 "I'm a teapot".
10
11use std::sync::LazyLock;
12
13use std::collections::HashMap;
14
15static PHRASES: LazyLock<HashMap<u16, &'static str>> = LazyLock::new(|| {
16    HashMap::from([
17        (100, "Continue"),
18        (101, "Switching Protocols"),
19        (102, "Processing"),
20        (103, "Early Hints"),
21        (200, "OK"),
22        (201, "Created"),
23        (202, "Accepted"),
24        (203, "Non-Authoritative Information"),
25        (204, "No Content"),
26        (205, "Reset Content"),
27        (206, "Partial Content"),
28        (207, "Multi-Status"),
29        (208, "Already Reported"),
30        (226, "IM Used"),
31        (300, "Multiple Choices"),
32        (301, "Moved Permanently"),
33        (302, "Found"),
34        (303, "See Other"),
35        (304, "Not Modified"),
36        (305, "Use Proxy"),
37        (307, "Temporary Redirect"),
38        (308, "Permanent Redirect"),
39        (400, "Bad Request"),
40        (401, "Unauthorized"),
41        (402, "Payment Required"),
42        (403, "Forbidden"),
43        (404, "Not Found"),
44        (405, "Method Not Allowed"),
45        (406, "Not Acceptable"),
46        (407, "Proxy Authentication Required"),
47        (408, "Request Timeout"),
48        (409, "Conflict"),
49        (410, "Gone"),
50        (411, "Length Required"),
51        (412, "Precondition Failed"),
52        (413, "Payload Too Large"),
53        (414, "URI Too Long"),
54        (415, "Unsupported Media Type"),
55        (416, "Range Not Satisfiable"),
56        (417, "Expectation Failed"),
57        (418, "I'm a teapot"),
58        (421, "Misdirected Request"),
59        (422, "Unprocessable Entity"),
60        (423, "Locked"),
61        (424, "Failed Dependency"),
62        (425, "Too Early"),
63        (426, "Upgrade Required"),
64        (428, "Precondition Required"),
65        (429, "Too Many Requests"),
66        (431, "Request Header Fields Too Large"),
67        (451, "Unavailable For Legal Reasons"),
68        (500, "Internal Server Error"),
69        (501, "Not Implemented"),
70        (502, "Bad Gateway"),
71        (503, "Service Unavailable"),
72        (504, "Gateway Timeout"),
73        (505, "HTTP Version Not Supported"),
74        (506, "Variant Also Negotiates"),
75        (507, "Insufficient Storage"),
76        (508, "Loop Detected"),
77        (510, "Not Extended"),
78        (511, "Network Authentication Required"),
79    ])
80});
81
82/// Returns the standard reason phrase for an HTTP status code, or `"Unknown Status Code"`
83/// if the code is not in the lookup table. The table is initialized once on first call
84/// and reused for the lifetime of the process.
85pub fn status_text(code: u16) -> &'static str {
86    PHRASES.get(&code).copied().unwrap_or("Unknown Status Code")
87}