use crate::{FromRequest, Request};
use crate::{IntoResponse, Response};
use http::header::CONTENT_TYPE;
use http::{HeaderValue, StatusCode};
use http_body_util::BodyExt;
use http_body_util::Full;
use hyper::body::Bytes;
use serde::Serialize;
use serde::de::DeserializeOwned;
use std::fmt::{Display, Formatter};
use std::ops::Deref;
pub struct Json<T>(pub T);
impl<T> Deref for Json<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> IntoResponse for Json<T>
where
T: Serialize,
{
fn into_response(self) -> Response {
let bytes = serde_json::to_vec(&self.0).expect("Serializable value could not serialize");
let mut response = Response::new(Full::new(Bytes::from(bytes)));
response
.headers_mut()
.append(CONTENT_TYPE, HeaderValue::from_static("application/json"));
response
}
}
impl<T> FromRequest for Json<T>
where
T: DeserializeOwned,
{
type Error = JsonError;
type Output = T;
async fn from_request(request: Request) -> Result<Self::Output, Self::Error> {
let bytes = request
.into_inner()
.collect()
.await
.map_err(|e| JsonError(e.to_string()))?
.to_bytes();
let serialized =
serde_json::from_slice(bytes.as_ref()).map_err(|e| JsonError(e.to_string()))?;
Ok(serialized)
}
}
pub struct JsonError(pub String);
impl Display for JsonError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl IntoResponse for JsonError {
fn into_response(self) -> Response {
let mut response = Response::new(Full::new(Bytes::new()));
*response.status_mut() = StatusCode::BAD_REQUEST;
response
}
}