1use axum::http::{HeaderMap, StatusCode, header};
2use axum::response::IntoResponse;
3use facet::Facet;
4use moire_types::ApiError;
5
6pub fn copy_request_headers(headers: &HeaderMap) -> Vec<(String, String)> {
7 headers
8 .iter()
9 .filter_map(|(name, value)| {
10 value
11 .to_str()
12 .ok()
13 .map(|v| (name.as_str().to_string(), v.to_string()))
14 })
15 .collect()
16}
17
18pub fn skip_request_header(name: &str) -> bool {
19 let lower = name.to_ascii_lowercase();
20 lower == "host" || lower == "content-length" || is_hop_by_hop(&lower)
21}
22
23pub fn skip_response_header(name: &str) -> bool {
24 let lower = name.to_ascii_lowercase();
25 lower == "content-length" || is_hop_by_hop(&lower)
26}
27
28pub fn json_ok<T>(value: &T) -> axum::response::Response
29where
30 T: for<'facet> Facet<'facet>,
31{
32 match facet_json::to_string(value) {
33 Ok(body) => (
34 StatusCode::OK,
35 [(header::CONTENT_TYPE, "application/json; charset=utf-8")],
36 body,
37 )
38 .into_response(),
39 Err(error) => (
40 StatusCode::INTERNAL_SERVER_ERROR,
41 [(header::CONTENT_TYPE, "text/plain; charset=utf-8")],
42 format!("json encode error: {error}"),
43 )
44 .into_response(),
45 }
46}
47
48pub fn json_error(status: StatusCode, message: impl Into<String>) -> axum::response::Response {
49 json_with_status(
50 status,
51 &ApiError {
52 error: message.into(),
53 },
54 )
55}
56
57pub fn json_with_status<T>(status: StatusCode, value: &T) -> axum::response::Response
58where
59 T: for<'facet> Facet<'facet>,
60{
61 match facet_json::to_string(value) {
62 Ok(body) => (
63 status,
64 [(header::CONTENT_TYPE, "application/json; charset=utf-8")],
65 body,
66 )
67 .into_response(),
68 Err(error) => (
69 StatusCode::INTERNAL_SERVER_ERROR,
70 [(header::CONTENT_TYPE, "text/plain; charset=utf-8")],
71 format!("json encode error: {error}"),
72 )
73 .into_response(),
74 }
75}
76
77fn is_hop_by_hop(lowercase_name: &str) -> bool {
78 matches!(
79 lowercase_name,
80 "connection"
81 | "keep-alive"
82 | "proxy-authenticate"
83 | "proxy-authorization"
84 | "te"
85 | "trailers"
86 | "transfer-encoding"
87 | "upgrade"
88 )
89}