Skip to main content

enum_status_code/
lib.rs

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