enum_status_code/lib.rs
1/// A macro to attach status codes to enum errors
2/// Usage:
3/// ```
4/// use http::StatusCode;
5///
6/// #[status_code]
7/// pub enum DatabaseError {
8/// #[code(StatusCode::NOT_FOUND)]
9/// NotFoundInDatabase,
10/// #[code(StatusCode::INTERNAL_SERVER_ERROR)]
11/// DatabaseNetworkError
12/// }
13/// ```
14///
15/// You can also set a default and override when neccesary.
16/// ```
17/// use http::StatusCode;
18///
19/// #[status_code(StatusCode::FORBIDDEN)]
20/// pub enum TokenError {
21/// MalformedToken,
22/// InvalidToken,
23/// #[code(StatusCode::INTERNAL_SERVER_ERROR)]
24/// DeserializationError
25/// }
26/// ```
27///
28/// You can even include the contents of the enum!
29/// ```
30/// use http::StatusCode;
31///
32/// #[status_code]
33/// pub enum Error {
34/// #[pattern((code, _, _))]
35/// // Note that you have to deference as we borrow the enum
36/// #[code(*code)]
37/// Dynamic(StatusCode, (), ()),
38/// #[pattern({ status, .. })]
39/// #[code(*status)]
40/// DynamicStruct {
41/// status: StatusCode,
42/// ctx: (),
43/// }
44/// }
45/// ```
46///
47/// You can even write arbitrary code!
48/// ```
49/// #[status_code]
50/// pub enum Error {
51/// #[pattern((ctx))]
52/// #[code({
53/// let result = StatusCode::try_from(ctx.status_code()).unwrap();
54/// return result
55/// })]
56/// Number(ErrorContext)
57/// }
58/// ```
59///
60/// The interior of the code attribute, as you've probably figured out, is the contents of the match arm (which is what the macro expands to).
61/// The interior of the pattern attribute is the binding pattern to which to bind variables to. Note that the name of the variant should not be included here.
62///
63/// ```
64/// match enum {
65/// Variant #pattern => #attribute,
66/// ...
67/// }
68/// ```
69///
70/// Pattern is optional, being filled in by an ignore-all if not set.
71/// Code is only optional if a default status code is set in the top-level status_code attribute.
72///
73/// Find out what status code something has using the as_status_code function.
74/// ```
75/// pub fn endpoint(...) -> impl IntoResponse {
76/// let user = fetch_user(cookies);
77/// if let Err(err) = user {
78/// return (err.as_status_code(), err.to_string())
79/// }
80/// }
81/// ```
82pub use enum_status_code_macros::status_code;
83pub use http;
84
85pub trait AsStatusCode {
86 fn as_status_code(&self) -> http::StatusCode;
87}