use anyhow::Context; use axum::http::{HeaderValue, StatusCode, header::CONTENT_TYPE}; use serde::Serialize; use serror::serialize_error; pub struct Response(pub axum::response::Response); impl From for Response where T: Serialize, { fn from(value: T) -> Response { let res = match serde_json::to_string(&value) .context("failed to serialize response body") { Ok(body) => axum::response::Response::builder() .header( CONTENT_TYPE, HeaderValue::from_static("application/json"), ) .body(axum::body::Body::from(body)) .unwrap(), Err(e) => axum::response::Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .header( CONTENT_TYPE, HeaderValue::from_static("application/json"), ) .body(axum::body::Body::from(serialize_error(&e))) .unwrap(), }; Response(res) } } pub enum JsonString { Ok(String), Err(serde_json::Error), } impl From for JsonString where T: Serialize, { fn from(value: T) -> JsonString { match serde_json::to_string(&value) { Ok(body) => JsonString::Ok(body), Err(e) => JsonString::Err(e), } } } impl JsonString { pub fn into_response(self) -> axum::response::Response { match self { JsonString::Ok(body) => axum::response::Response::builder() .header( CONTENT_TYPE, HeaderValue::from_static("application/json"), ) .body(axum::body::Body::from(body)) .unwrap(), JsonString::Err(error) => axum::response::Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .header( CONTENT_TYPE, HeaderValue::from_static("application/json"), ) .body(axum::body::Body::from(serialize_error( &anyhow::Error::from(error) .context("failed to serialize response body"), ))) .unwrap(), } } }