Skip to main content

cratestack_axum/transport/
encode_sequence.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_sequence_result<TTransport, TValue>(
11    transport: &TTransport,
12    headers: &HeaderMap,
13    result: Result<Vec<TValue>, CoolError>,
14) -> Response
15where
16    TTransport: HttpTransport,
17    TValue: Serialize,
18{
19    encode_transport_sequence_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_sequence_result_with_status<TTransport, TValue>(
34    transport: &TTransport,
35    headers: &HeaderMap,
36    success_status: StatusCode,
37    result: Result<Vec<TValue>, CoolError>,
38) -> Response
39where
40    TTransport: HttpTransport,
41    TValue: Serialize,
42{
43    encode_transport_sequence_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_sequence_result_with_status_for<TTransport, TValue>(
58    transport: &TTransport,
59    headers: &HeaderMap,
60    capabilities: &RouteTransportCapabilities,
61    success_status: StatusCode,
62    result: Result<Vec<TValue>, CoolError>,
63) -> Response
64where
65    TTransport: HttpTransport,
66    TValue: Serialize,
67{
68    if !capabilities.supports_sequence_response {
69        return fallback_error_response(CoolError::Internal(
70            "sequence response encoding requested for a route without sequence capability"
71                .to_owned(),
72        ));
73    }
74    let content_type = match select_response_content_type(
75        headers,
76        capabilities.response_types,
77        capabilities.default_response_type,
78    ) {
79        Ok(content_type) => content_type,
80        Err(error) => return fallback_error_response(error),
81    };
82    match result {
83        Ok(values) => transport
84            .encode_sequence_response(content_type, success_status, &values)
85            .unwrap_or_else(fallback_error_response),
86        Err(error) => {
87            let status = error.status_code();
88            let body = error.into_response();
89            transport
90                .encode_sequence_error_response(content_type, status, &body)
91                .unwrap_or_else(fallback_error_response)
92        }
93    }
94}