cratestack_axum/transport/
encode_unary.rs1use axum::http::{HeaderMap, StatusCode};
2use axum::response::Response;
3use cratestack_core::{CratestackError, RouteTransportCapabilities};
4use serde::Serialize;
5
6use super::http_transport::HttpTransport;
7use super::internal::fallback_error_response;
8use super::media_type::select_transport_response_content_type;
9
10pub fn encode_transport_result<TTransport, TValue>(
11 transport: &TTransport,
12 headers: &HeaderMap,
13 result: Result<TValue, CratestackError>,
14) -> Response
15where
16 TTransport: HttpTransport,
17 TValue: Serialize,
18{
19 encode_transport_result_with_status_for(
20 transport,
21 headers,
22 &RouteTransportCapabilities {
23 request_types: &[],
24 response_types: &[],
25 default_response_type: "",
26 supports_sequence_response: false,
27 },
28 StatusCode::OK,
29 result,
30 )
31}
32
33pub fn encode_transport_result_with_status<TTransport, TValue>(
34 transport: &TTransport,
35 headers: &HeaderMap,
36 success_status: StatusCode,
37 result: Result<TValue, CratestackError>,
38) -> Response
39where
40 TTransport: HttpTransport,
41 TValue: Serialize,
42{
43 encode_transport_result_with_status_for(
44 transport,
45 headers,
46 &RouteTransportCapabilities {
47 request_types: &[],
48 response_types: &[],
49 default_response_type: "",
50 supports_sequence_response: false,
51 },
52 success_status,
53 result,
54 )
55}
56
57pub fn encode_transport_result_with_status_for<TTransport, TValue>(
58 transport: &TTransport,
59 headers: &HeaderMap,
60 capabilities: &RouteTransportCapabilities,
61 success_status: StatusCode,
62 result: Result<TValue, CratestackError>,
63) -> Response
64where
65 TTransport: HttpTransport,
66 TValue: Serialize,
67{
68 let content_type =
69 match select_transport_response_content_type(transport, headers, capabilities) {
70 Ok(content_type) => content_type,
71 Err(error) => return fallback_error_response(error),
72 };
73 match result {
74 Ok(value) => transport
75 .encode_response(content_type, success_status, &value)
76 .unwrap_or_else(fallback_error_response),
77 Err(error) => {
78 let (error, tag) = crate::idempotency::answered(error);
79 let status = error.status_code();
80 let challenges = crate::auth_challenge::challenges_of(&error);
81 let body = error.into_response();
82 let response = transport
83 .encode_response(content_type, status, &body)
84 .unwrap_or_else(fallback_error_response);
85 let response = crate::auth_challenge::attach(response, &challenges);
86 crate::idempotency::with_tag(tag, response)
87 }
88 }
89}
90
91#[cfg(test)]
92mod tests;