use std::{
any::type_name,
fmt::{Debug, Display, Formatter},
sync::Arc,
};
use serde::{Serialize, Serializer};
use utoipa::{
openapi::{ObjectBuilder, RefOr, Schema, SchemaType},
ToSchema,
};
use crate::tina::{
data::AppResult,
server::{
application::{AppConfig, Application},
http::request::{AnyType, RequestAttribute, RequestExt},
session::Session,
},
};
pub struct HttpReqMetadata {
application: Application,
pub session: Session,
pub(crate) request: Box<AnyType>,
}
impl RequestAttribute for HttpReqMetadata {
fn application(&self) -> Application {
self.application.to_owned()
}
fn session(&self) -> Session {
self.session.to_owned()
}
}
impl HttpReqMetadata {
pub fn new<Req: RequestExt + 'static>(req: Req, application: Application, session: Session) -> HttpReqMetadata {
let request = Box::new(req);
HttpReqMetadata {
application,
session,
request,
}
}
pub fn extension<T: Send + Sync + 'static>(&self) -> AppResult<Arc<T>> {
self.application.extension()
}
}
impl From<HttpReqMetadata> for (Session, Application) {
fn from(value: HttpReqMetadata) -> Self {
(value.session, value.application)
}
}
impl<'a> ToSchema<'a> for HttpReqMetadata {
fn schema() -> (&'a str, RefOr<Schema>) {
(type_name::<HttpReqMetadata>(), RefOr::T(Schema::from(ObjectBuilder::new().schema_type(SchemaType::Object))))
}
}
impl Default for HttpReqMetadata {
fn default() -> Self {
HttpReqMetadata {
application: AppConfig::new().into(),
session: Session::default(),
request: Box::new(()),
}
}
}
impl Debug for HttpReqMetadata {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("[RequestMetadata]")
}
}
impl Display for HttpReqMetadata {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("[RequestMetadata]")
}
}
impl Serialize for HttpReqMetadata {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
"[RequestMetadata]".serialize(serializer)
}
}