1use crate::maud::Markup;
2use serde::Serialize;
3use warp::http::{Response, StatusCode};
4use warp::reply;
5use warp::reply::WithStatus;
6
7pub fn hx_with(
8 status: StatusCode,
9 res: Markup,
10) -> Response<String> {
11 Response::builder()
12 .header("Content", "text/html")
13 .status(status)
14 .body(res.into_string())
15 .expect("BUG: impossible")
17}
18
19macro_rules! generate_hx_status_functions {
20 ($($fname:ident, $status:ident);* $(;)?) => {
21 $(
22 pub fn $fname(res: Markup) -> Response<String> {
23 hx_with(StatusCode::$status, res)
24 }
25 )*
26 };
27}
28
29generate_hx_status_functions! {
30 hx, OK;
32 hx_error, IM_A_TEAPOT;
33
34 hx_continue, CONTINUE;
36 hx_switching_protocols, SWITCHING_PROTOCOLS;
37 hx_processing, PROCESSING;
38
39 hx_ok, OK;
41 hx_created, CREATED;
42 hx_accepted, ACCEPTED;
43 hx_non_authoritative_information, NON_AUTHORITATIVE_INFORMATION;
44 hx_no_content, NO_CONTENT;
45 hx_reset_content, RESET_CONTENT;
46 hx_partial_content, PARTIAL_CONTENT;
47 hx_multi_status, MULTI_STATUS;
48 hx_already_reported, ALREADY_REPORTED;
49 hx_im_used, IM_USED;
50
51 hx_multiple_choices, MULTIPLE_CHOICES;
53 hx_moved_permanently, MOVED_PERMANENTLY;
54 hx_found, FOUND;
55 hx_see_other, SEE_OTHER;
56 hx_not_modified, NOT_MODIFIED;
57 hx_use_proxy, USE_PROXY;
58 hx_temporary_redirect, TEMPORARY_REDIRECT;
59 hx_permanent_redirect, PERMANENT_REDIRECT;
60
61 hx_bad_request, BAD_REQUEST;
63 hx_unauthorized, UNAUTHORIZED;
64 hx_payment_required, PAYMENT_REQUIRED;
65 hx_forbidden, FORBIDDEN;
66 hx_not_found, NOT_FOUND;
67 hx_method_not_allowed, METHOD_NOT_ALLOWED;
68 hx_not_acceptable, NOT_ACCEPTABLE;
69 hx_proxy_authentication_required, PROXY_AUTHENTICATION_REQUIRED;
70 hx_request_timeout, REQUEST_TIMEOUT;
71 hx_conflict, CONFLICT;
72 hx_gone, GONE;
73 hx_length_required, LENGTH_REQUIRED;
74 hx_precondition_failed, PRECONDITION_FAILED;
75 hx_payload_too_large, PAYLOAD_TOO_LARGE;
76 hx_uri_too_long, URI_TOO_LONG;
77 hx_unsupported_media_type, UNSUPPORTED_MEDIA_TYPE;
78 hx_range_not_satisfiable, RANGE_NOT_SATISFIABLE;
79 hx_expectation_failed, EXPECTATION_FAILED;
80 hx_im_a_teapot, IM_A_TEAPOT;
81 hx_misdirected_request, MISDIRECTED_REQUEST;
82 hx_unprocessable_entity, UNPROCESSABLE_ENTITY;
83 hx_locked, LOCKED;
84 hx_failed_dependency, FAILED_DEPENDENCY;
85 hx_upgrade_required, UPGRADE_REQUIRED;
86 hx_precondition_required, PRECONDITION_REQUIRED;
87 hx_too_many_requests, TOO_MANY_REQUESTS;
88 hx_request_header_fields_too_large, REQUEST_HEADER_FIELDS_TOO_LARGE;
89 hx_unavailable_for_legal_reasons, UNAVAILABLE_FOR_LEGAL_REASONS;
90
91 hx_internal_server_error, INTERNAL_SERVER_ERROR;
93 hx_not_implemented, NOT_IMPLEMENTED;
94 hx_bad_gateway, BAD_GATEWAY;
95 hx_service_unavailable, SERVICE_UNAVAILABLE;
96 hx_gateway_timeout, GATEWAY_TIMEOUT;
97 hx_http_version_not_supported, HTTP_VERSION_NOT_SUPPORTED;
98 hx_variant_also_negotiates, VARIANT_ALSO_NEGOTIATES;
99 hx_insufficient_storage, INSUFFICIENT_STORAGE;
100 hx_loop_detected, LOOP_DETECTED;
101 hx_not_extended, NOT_EXTENDED;
102 hx_network_authentication_required, NETWORK_AUTHENTICATION_REQUIRED
103}
104
105pub fn js_with<T: Serialize>(
106 data: &T,
107 status_code: &StatusCode,
108) -> WithStatus<String> {
109 let json =
110 serde_json::to_string(data).expect("BUG: Impossible");
111 reply::with_status(json, *status_code)
112}
113
114macro_rules! generate_js_status_functions {
115 ($($fname:ident, $status:ident);* $(;)?) => {
116 $(
117 pub fn $fname<T: Serialize>(
118 data: &T,
119 ) -> WithStatus<String> {
120 js_with(data, &StatusCode::$status)
121 }
122 )*
123 };
124}
125
126generate_js_status_functions! {
127 js, OK;
129 js_error, IM_A_TEAPOT;
130
131 js_continue, CONTINUE;
133 js_switching_protocols, SWITCHING_PROTOCOLS;
134 js_processing, PROCESSING;
135
136 js_ok, OK;
138 js_created, CREATED;
139 js_accepted, ACCEPTED;
140 js_non_authoritative_information, NON_AUTHORITATIVE_INFORMATION;
141 js_no_content, NO_CONTENT;
142 js_reset_content, RESET_CONTENT;
143 js_partial_content, PARTIAL_CONTENT;
144 js_multi_status, MULTI_STATUS;
145 js_already_reported, ALREADY_REPORTED;
146 js_im_used, IM_USED;
147
148 js_multiple_choices, MULTIPLE_CHOICES;
150 js_moved_permanently, MOVED_PERMANENTLY;
151 js_found, FOUND;
152 js_see_other, SEE_OTHER;
153 js_not_modified, NOT_MODIFIED;
154 js_use_proxy, USE_PROXY;
155 js_temporary_redirect, TEMPORARY_REDIRECT;
156 js_permanent_redirect, PERMANENT_REDIRECT;
157
158 js_bad_request, BAD_REQUEST;
160 js_unauthorized, UNAUTHORIZED;
161 js_payment_required, PAYMENT_REQUIRED;
162 js_forbidden, FORBIDDEN;
163 js_not_found, NOT_FOUND;
164 js_method_not_allowed, METHOD_NOT_ALLOWED;
165 js_not_acceptable, NOT_ACCEPTABLE;
166 js_proxy_authentication_required, PROXY_AUTHENTICATION_REQUIRED;
167 js_request_timeout, REQUEST_TIMEOUT;
168 js_conflict, CONFLICT;
169 js_gone, GONE;
170 js_length_required, LENGTH_REQUIRED;
171 js_precondition_failed, PRECONDITION_FAILED;
172 js_payload_too_large, PAYLOAD_TOO_LARGE;
173 js_uri_too_long, URI_TOO_LONG;
174 js_unsupported_media_type, UNSUPPORTED_MEDIA_TYPE;
175 js_range_not_satisfiable, RANGE_NOT_SATISFIABLE;
176 js_expectation_failed, EXPECTATION_FAILED;
177 js_im_a_teapot, IM_A_TEAPOT;
178 js_misdirected_request, MISDIRECTED_REQUEST;
179 js_unprocessable_entity, UNPROCESSABLE_ENTITY;
180 js_locked, LOCKED;
181 js_failed_dependency, FAILED_DEPENDENCY;
182 js_upgrade_required, UPGRADE_REQUIRED;
183 js_precondition_required, PRECONDITION_REQUIRED;
184 js_too_many_requests, TOO_MANY_REQUESTS;
185 js_request_header_fields_too_large, REQUEST_HEADER_FIELDS_TOO_LARGE;
186 js_unavailable_for_legal_reasons, UNAVAILABLE_FOR_LEGAL_REASONS;
187
188 js_internal_server_error, INTERNAL_SERVER_ERROR;
190 js_not_implemented, NOT_IMPLEMENTED;
191 js_bad_gateway, BAD_GATEWAY;
192 js_service_unavailable, SERVICE_UNAVAILABLE;
193 js_gateway_timeout, GATEWAY_TIMEOUT;
194 js_http_version_not_supported, HTTP_VERSION_NOT_SUPPORTED;
195 js_variant_also_negotiates, VARIANT_ALSO_NEGOTIATES;
196 js_insufficient_storage, INSUFFICIENT_STORAGE;
197 js_loop_detected, LOOP_DETECTED;
198 js_not_extended, NOT_EXTENDED;
199 js_network_authentication_required, NETWORK_AUTHENTICATION_REQUIRED
200}
201
202pub fn sse_chunk<T: Into<String>>(s: T) -> crate::sse::Event {
203 crate::sse::Event::default().event("message-chunk").data(s)
204}
205pub fn sse_complete<T: Into<String>>(s: T) -> crate::sse::Event {
206 crate::sse::Event::default()
207 .event("message-complete")
208 .data(s)
209}