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}