seamless/handler/
response.rs1use crate::api::{ ApiBody, ApiBodyInfo, ApiError };
2use async_trait::async_trait;
3use serde::Serialize;
4
5type HttpResponse = http::Response<Vec<u8>>;
6
7#[async_trait]
11pub trait HandlerResponse {
12 type ResponseBody: ApiBody;
14 async fn handler_response(self) -> Result<HttpResponse, ApiError>;
16}
17
18pub struct ToJson<T: ApiBody>(pub T);
20
21#[async_trait]
22impl <T: ApiBody + Serialize + Send> HandlerResponse for ToJson<T> {
23 type ResponseBody = T;
24 async fn handler_response(self) -> Result<HttpResponse, ApiError> {
25 let body = serde_json::to_vec(&self.0).unwrap();
26 let res = http::Response::builder()
27 .header("content-type", "application/json")
28 .body(body)
29 .unwrap();
30 Ok(res)
31 }
32}
33
34impl <T> ApiBody for ToJson<T> where T: ApiBody {
35 fn api_body_info() -> ApiBodyInfo {
36 T::api_body_info()
37 }
38}
39
40#[async_trait]
42impl <T> HandlerResponse for Option<T>
43where
44 T: HandlerResponse + Send
45{
46 type ResponseBody = <T as HandlerResponse>::ResponseBody;
47 async fn handler_response(self) -> Result<HttpResponse, ApiError> {
48 let res = self.ok_or_else(|| ApiError::path_not_found())?;
49 res.handler_response().await.map_err(|e| e.into())
50 }
51}
52
53#[async_trait]
55impl <T, E> HandlerResponse for Result<T,E>
56where
57 T: HandlerResponse + Send,
58 E: Into<ApiError> + Send + 'static,
59{
60 type ResponseBody = <T as HandlerResponse>::ResponseBody;
61 async fn handler_response(self) -> Result<HttpResponse, ApiError> {
62 let res = self.map_err(|e| e.into())?;
63 res.handler_response().await.map_err(|e| e.into())
64 }
65}
66