Skip to main content

cratestack_axum/codec/
encode.rs

1use axum::body::Body;
2use axum::http::{HeaderValue, StatusCode, header};
3use axum::response::Response;
4use cratestack_core::{CoolCodec, CoolError};
5use serde::{Deserialize, Serialize};
6
7use crate::transport::fallback_error_response;
8
9pub fn decode_codec_request<C, T>(codec: &C, body: &[u8]) -> Result<T, CoolError>
10where
11    C: CoolCodec,
12    T: for<'de> Deserialize<'de>,
13{
14    codec.decode(body)
15}
16
17pub fn encode_codec_response<C, T>(
18    codec: &C,
19    status: StatusCode,
20    value: &T,
21) -> Result<Response, CoolError>
22where
23    C: CoolCodec,
24    T: Serialize + ?Sized,
25{
26    let bytes = codec.encode(value)?;
27    let mut response = Response::new(Body::from(bytes));
28    *response.status_mut() = status;
29    response.headers_mut().insert(
30        header::CONTENT_TYPE,
31        HeaderValue::from_static(C::CONTENT_TYPE),
32    );
33    Ok(response)
34}
35
36pub fn encode_codec_result<C, T>(codec: &C, result: Result<T, CoolError>) -> Response
37where
38    C: CoolCodec,
39    T: Serialize,
40{
41    encode_codec_result_with_status(codec, StatusCode::OK, result)
42}
43
44pub fn encode_codec_result_with_status<C, T>(
45    codec: &C,
46    success_status: StatusCode,
47    result: Result<T, CoolError>,
48) -> Response
49where
50    C: CoolCodec,
51    T: Serialize,
52{
53    match result {
54        Ok(value) => encode_codec_response(codec, success_status, &value)
55            .unwrap_or_else(fallback_error_response),
56        Err(error) => {
57            let status = error.status_code();
58            let body = error.into_response();
59            encode_codec_response(codec, status, &body).unwrap_or_else(fallback_error_response)
60        }
61    }
62}