use std::fmt;
use super::IntoResponse;
use crate::Body;
use crate::Response;
use crate::dep::http::StatusCode;
use crate::headers::ContentType;
use rama_core::error::OpaqueError;
use rama_utils::macros::impl_deref;
use serde::Serialize;
use super::Headers;
pub struct Form<T>(pub T);
impl<T: fmt::Debug> fmt::Debug for Form<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Form").field(&self.0).finish()
}
}
impl<T: Clone> Clone for Form<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl_deref!(Form);
impl<T> From<T> for Form<T> {
fn from(value: T) -> Self {
Self(value)
}
}
impl<T> IntoResponse for Form<T>
where
T: Serialize,
{
fn into_response(self) -> Response {
fn make_response(ser_result: Result<String, serde_html_form::ser::Error>) -> Response {
match ser_result {
Ok(body) => {
(Headers::single(ContentType::form_url_encoded()), body).into_response()
}
Err(err) => {
tracing::error!(error = %err, "response error");
StatusCode::INTERNAL_SERVER_ERROR.into_response()
}
}
}
make_response(serde_html_form::to_string(&self.0))
}
}
impl<T> TryInto<Body> for Form<T>
where
T: Serialize,
{
type Error = OpaqueError;
fn try_into(self) -> Result<Body, Self::Error> {
match serde_html_form::to_string(&self.0) {
Ok(body) => Ok(body.into()),
Err(err) => Err(OpaqueError::from_std(err)),
}
}
}