Skip to main content

cratestack_axum/transport/
encode_unary.rs

1use axum::http::{HeaderMap, StatusCode};
2use axum::response::Response;
3use cratestack_core::{CoolError, RouteTransportCapabilities};
4use serde::Serialize;
5
6use super::http_transport::HttpTransport;
7use super::internal::fallback_error_response;
8use super::media_type::select_response_content_type;
9
10pub fn encode_transport_result<TTransport, TValue>(
11    transport: &TTransport,
12    headers: &HeaderMap,
13    result: Result<TValue, CoolError>,
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, CoolError>,
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, CoolError>,
63) -> Response
64where
65    TTransport: HttpTransport,
66    TValue: Serialize,
67{
68    let content_type = match select_response_content_type(
69        headers,
70        capabilities.response_types,
71        capabilities.default_response_type,
72    ) {
73        Ok(content_type) => content_type,
74        Err(error) => return fallback_error_response(error),
75    };
76    match result {
77        Ok(value) => transport
78            .encode_response(content_type, success_status, &value)
79            .unwrap_or_else(fallback_error_response),
80        Err(error) => {
81            let status = error.status_code();
82            let body = error.into_response();
83            transport
84                .encode_response(content_type, status, &body)
85                .unwrap_or_else(fallback_error_response)
86        }
87    }
88}