Skip to main content

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}