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::{AppConfig, Application},
http::request::RequestAttribute,
session::Session,
},
};
pub struct HttpReqPath<D: DeserializeOwned> {
names: Vec<String>,
data: D,
application: Application,
session: Session,
}
impl<D: DeserializeOwned> RequestAttribute for HttpReqPath<D> {
fn application(&self) -> Application {
self.application.to_owned()
}
fn session(&self) -> Session {
self.session.to_owned()
}
}
impl<D: DeserializeOwned> HttpReqPath<D> {
pub fn new(names: Vec<String>, data: D, application: Application, session: Session) -> HttpReqPath<D> {
HttpReqPath {
names,
data,
application,
session,
}
}
pub fn names(&self) -> &[String] {
self.names.as_slice()
}
pub fn into_inner(self) -> (Vec<String>, D, Session) {
(self.names, 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<HttpReqPath<D>> for (D, Session) {
fn from(value: HttpReqPath<D>) -> Self {
(value.data, value.session)
}
}
impl<D: DeserializeOwned> From<HttpReqPath<D>> for (D, Session, Application) {
fn from(value: HttpReqPath<D>) -> Self {
(value.data, value.session, value.application)
}
}
impl<D: DeserializeOwned + Default> Default for HttpReqPath<D> {
fn default() -> Self {
HttpReqPath {
names: vec![],
data: D::default(),
application: AppConfig::new().into(),
session: Session::default(),
}
}
}
impl<'a, D: DeserializeOwned + ToSchema<'a>> ToSchema<'a> for HttpReqPath<D> {
fn schema() -> (&'a str, RefOr<Schema>) {
D::schema()
}
}
impl<D: DeserializeOwned> Deref for HttpReqPath<D> {
type Target = D;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<D: DeserializeOwned> DerefMut for HttpReqPath<D> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl<D: DeserializeOwned + Debug> Debug for HttpReqPath<D> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.data.fmt(f)
}
}
impl<D: DeserializeOwned + Display> Display for HttpReqPath<D> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.data.fmt(f)
}
}
impl<D: DeserializeOwned + Serialize> Serialize for HttpReqPath<D> {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
self.data.serialize(serializer)
}
}