1use http_body_util::BodyExt as _;
12use rustolio_utils::{
13 bytes::encoding::{decode_from_hyper_stream, encode_to_bytes},
14 http::{self, StatusCode},
15 prelude::*,
16 threadsafe::Threadsafe,
17};
18
19use crate::ServerFnError;
20
21pub async fn decode_rpc_body<B, Msg>(req: http::Request<B>) -> Result<Msg, ServerFnError>
22where
23 B: hyper::body::Body + Unpin + Threadsafe,
24 Msg: Decode + Threadsafe,
25{
26 let stream = req.into_body().into_data_stream();
27
28 let Ok(msg) = decode_from_hyper_stream::<_, _, B>(stream).await else {
29 return Err(ServerFnError::http_error(
30 StatusCode::BAD_REQUEST,
31 "Failed to parse request body",
32 ));
33 };
34
35 Ok(msg)
49}
50
51pub fn encode_rpc_response<R, E>(res: Result<R, ServerFnError<E>>) -> http::Response
52where
53 R: Encode,
54 E: Encode,
55{
56 if let Err(ServerFnError::HttpError(status, msg)) = res {
57 return http::Response::builder()
58 .status(status)
59 .text(msg)
60 .build()
61 .unwrap();
62 }
63 let Ok(body) = encode_to_bytes(&res) else {
64 return http::Response::builder()
65 .status(StatusCode::INTERNAL_SERVER_ERROR)
66 .text("Failed to serialize response")
67 .build()
68 .unwrap();
69 };
70 http::Response::builder().bytes(body).build().unwrap()
71}