wp_error/
http_map.rs

1//! Lightweight mapping from system error code (SysErrorCode) to HTTP status.
2//! This module is framework-agnostic and does not depend on any HTTP stack.
3use crate::SysErrorCode;
4
5/// Map a system error code (u16) to an HTTP status code (u16).
6/// Suggested contract:
7/// - 404xx -> 404
8/// - 422xx -> 422
9/// - 204xx -> 204
10/// - 499xx -> 499 (Client Closed Request) or 503; we choose 499 to distinguish
11/// - 502xx -> 502
12/// - 503xx -> 503
13/// - 500xx -> 500
14/// - else -> 500
15pub fn http_status_for_sys(sys: u16) -> u16 {
16    let head = sys / 100; // e.g., 42211 -> 422
17    match head {
18        404 => 404,
19        422 => 422,
20        204 => 204,
21        499 => 499,
22        502 => 502,
23        503 => 503,
24        500 => 500,
25        _ => 500,
26    }
27}
28
29/// Convenience: map a reason to HTTP status.
30pub fn http_status_for_reason<R: SysErrorCode>(r: &R) -> u16 {
31    http_status_for_sys(r.sys_code())
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn test_http_status_404() {
40        assert_eq!(http_status_for_sys(40401), 404);
41        assert_eq!(http_status_for_sys(40402), 404);
42        assert_eq!(http_status_for_sys(40411), 404);
43        assert_eq!(http_status_for_sys(40412), 404);
44    }
45
46    #[test]
47    fn test_http_status_422() {
48        assert_eq!(http_status_for_sys(42201), 422);
49        assert_eq!(http_status_for_sys(42211), 422);
50        assert_eq!(http_status_for_sys(42212), 422);
51        assert_eq!(http_status_for_sys(42299), 422);
52    }
53
54    #[test]
55    fn test_http_status_204() {
56        assert_eq!(http_status_for_sys(20401), 204);
57        assert_eq!(http_status_for_sys(20402), 204);
58    }
59
60    #[test]
61    fn test_http_status_499() {
62        assert_eq!(http_status_for_sys(49901), 499);
63        assert_eq!(http_status_for_sys(49999), 499);
64    }
65
66    #[test]
67    fn test_http_status_502() {
68        assert_eq!(http_status_for_sys(50201), 502);
69        assert_eq!(http_status_for_sys(50209), 502);
70    }
71
72    #[test]
73    fn test_http_status_503() {
74        assert_eq!(http_status_for_sys(50301), 503);
75        assert_eq!(http_status_for_sys(50311), 503);
76        assert_eq!(http_status_for_sys(50312), 503);
77    }
78
79    #[test]
80    fn test_http_status_500() {
81        assert_eq!(http_status_for_sys(50001), 500);
82        assert_eq!(http_status_for_sys(50009), 500);
83        assert_eq!(http_status_for_sys(50041), 500);
84    }
85
86    #[test]
87    fn test_http_status_default_fallback() {
88        // Unknown codes should fallback to 500
89        assert_eq!(http_status_for_sys(10001), 500);
90        assert_eq!(http_status_for_sys(60001), 500);
91        assert_eq!(http_status_for_sys(0), 500);
92    }
93
94    #[test]
95    fn test_http_status_for_reason() {
96        struct TestReason(u16);
97        impl SysErrorCode for TestReason {
98            fn sys_code(&self) -> u16 {
99                self.0
100            }
101        }
102
103        let r404 = TestReason(40401);
104        assert_eq!(http_status_for_reason(&r404), 404);
105
106        let r422 = TestReason(42201);
107        assert_eq!(http_status_for_reason(&r422), 422);
108
109        let r500 = TestReason(50001);
110        assert_eq!(http_status_for_reason(&r500), 500);
111    }
112}