Skip to main content

cratestack_axum/transport/
encode_unary.rs

1use 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 status = error.status_code();
79            let body = error.into_response();
80            transport
81                .encode_response(content_type, status, &body)
82                .unwrap_or_else(fallback_error_response)
83        }
84    }
85}
86
87#[cfg(test)]
88mod tests;