use serde::{de::DeserializeOwned, Serialize, Serializer};
use std::{
fmt::{Debug, Display, Formatter},
ops::{Deref, DerefMut},
sync::Arc,
};
use utoipa::{
openapi::{RefOr, Schema},
ToSchema,
};
use crate::tina::{
data::AppResult,
server::{application::Application, http::request::RequestAttribute, session::Session},
};
pub struct HttpReqJson<D: DeserializeOwned> {
data: D,
application: Application,
session: Session,
}
impl<D: DeserializeOwned> RequestAttribute for HttpReqJson<D> {
fn application(&self) -> Application {
self.application.to_owned()
}
fn session(&self) -> Session {
self.session.to_owned()
}
}
impl<D: DeserializeOwned> HttpReqJson<D> {
pub fn new(data: D, application: Application, session: Session) -> HttpReqJson<D> {
HttpReqJson {
data,
application,
session,
}
}
pub fn into_inner(self) -> (D, Session) {
(self.data, self.session)
}
pub fn into_data(self) -> D {
self.data
}
pub fn extension<T: Send + Sync + 'static>(&self) -> AppResult<Arc<T>> {
self.application.extension()
}
}
impl<D: DeserializeOwned> From<HttpReqJson<D>> for (D, Session) {
fn from(value: HttpReqJson<D>) -> Self {
(value.data, value.session)
}
}
impl<D: DeserializeOwned> From<HttpReqJson<D>> for (D, Session, Application) {
fn from(value: HttpReqJson<D>) -> Self {
(value.data, value.session, value.application)
}
}
impl<'a, D: DeserializeOwned + ToSchema<'a>> ToSchema<'a> for HttpReqJson<D> {
fn schema() -> (&'a str, RefOr<Schema>) {
D::schema()
}
}
impl<D: DeserializeOwned> Deref for HttpReqJson<D> {
type Target = D;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<D: DeserializeOwned> DerefMut for HttpReqJson<D> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl<D: DeserializeOwned + Debug> Debug for HttpReqJson<D> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.data.fmt(f)
}
}
impl<D: DeserializeOwned + Display> Display for HttpReqJson<D> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.data.fmt(f)
}
}
impl<D: DeserializeOwned + Serialize> Serialize for HttpReqJson<D> {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
self.data.serialize(serializer)
}
}