zino_http/response/
response_code.rs

1use std::borrow::Cow;
2use zino_core::SharedString;
3
4/// Trait for response code.
5/// See [Problem Details for HTTP APIs](https://tools.ietf.org/html/rfc9457).
6pub trait ResponseCode {
7    /// 200 Ok.
8    const OK: Self;
9    /// 400 Bad Request.
10    const BAD_REQUEST: Self;
11    /// 500 Internal Server Error.
12    const INTERNAL_SERVER_ERROR: Self;
13
14    /// Status code.
15    fn status_code(&self) -> u16;
16
17    /// Returns `true` if the response is successful.
18    fn is_success(&self) -> bool;
19
20    /// A URI reference that identifies the problem type.
21    /// For successful response, it should be `None`.
22    fn type_uri(&self) -> Option<SharedString> {
23        None
24    }
25
26    /// A short, human-readable summary of the problem type.
27    /// For successful response, it should be `None`.
28    fn title(&self) -> Option<SharedString> {
29        None
30    }
31
32    /// A context-specific descriptive message. If the response is not successful,
33    /// it should be a human-readable explanation specific to this occurrence of the problem.
34    fn message(&self) -> Option<SharedString> {
35        None
36    }
37}
38
39macro_rules! impl_response_code {
40    ($Ty:ty) => {
41        impl ResponseCode for $Ty {
42            const OK: Self = Self::OK;
43            const BAD_REQUEST: Self = Self::BAD_REQUEST;
44            const INTERNAL_SERVER_ERROR: Self = Self::INTERNAL_SERVER_ERROR;
45
46            #[inline]
47            fn status_code(&self) -> u16 {
48                self.as_u16()
49            }
50
51            #[inline]
52            fn is_success(&self) -> bool {
53                self.is_success()
54            }
55
56            #[inline]
57            fn type_uri(&self) -> Option<SharedString> {
58                None
59            }
60
61            #[inline]
62            fn title(&self) -> Option<SharedString> {
63                if self.is_success() {
64                    None
65                } else {
66                    self.canonical_reason().map(Cow::Borrowed)
67                }
68            }
69
70            #[inline]
71            fn message(&self) -> Option<SharedString> {
72                if self.is_success() {
73                    self.canonical_reason().map(Cow::Borrowed)
74                } else {
75                    None
76                }
77            }
78        }
79    };
80}
81
82impl_response_code!(http::StatusCode);
83
84#[cfg(feature = "http02")]
85impl_response_code!(http02::StatusCode);