use std::{
any::type_name,
fmt::{Debug, Display, Formatter},
ops::{Deref, DerefMut},
sync::Arc,
};
use serde::ser::Error;
use serde::{Serialize, Serializer};
use serde_json::value::RawValue;
use utoipa::{
openapi::{ObjectBuilder, RefOr, Schema, SchemaType},
ToSchema,
};
use crate::tina::{
data::AppResult,
server::{
application::{AppConfig, Application},
http::request::RequestAttribute,
session::Session,
},
util::not_empty::INotEmpty,
};
pub struct HttpReqByte {
data: Vec<u8>,
application: Application,
session: Session,
}
impl RequestAttribute for HttpReqByte {
fn application(&self) -> Application {
self.application.to_owned()
}
fn session(&self) -> Session {
self.session.to_owned()
}
}
impl HttpReqByte {
pub fn new(data: Vec<u8>, application: Application, session: Session) -> HttpReqByte {
HttpReqByte {
data,
application,
session,
}
}
pub fn into_inner(self) -> (Vec<u8>, Session) {
(self.data, self.session)
}
pub fn into_data(self) -> Vec<u8> {
self.data
}
pub fn extension<T: Send + Sync + 'static>(&self) -> AppResult<Arc<T>> {
self.application.extension()
}
}
impl From<HttpReqByte> for (Vec<u8>, Session) {
fn from(value: HttpReqByte) -> Self {
(value.data, value.session)
}
}
impl From<HttpReqByte> for (Vec<u8>, Session, Application) {
fn from(value: HttpReqByte) -> Self {
(value.data, value.session, value.application)
}
}
impl<'a> ToSchema<'a> for HttpReqByte {
fn schema() -> (&'a str, RefOr<Schema>) {
(type_name::<HttpReqByte>(), RefOr::T(Schema::from(ObjectBuilder::new().schema_type(SchemaType::Object))))
}
}
impl Default for HttpReqByte {
fn default() -> Self {
HttpReqByte {
data: Vec::new(),
application: AppConfig::new().into(),
session: Session::default(),
}
}
}
impl Deref for HttpReqByte {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl DerefMut for HttpReqByte {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl Debug for HttpReqByte {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.data.fmt(f)
}
}
impl Display for HttpReqByte {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.data.fmt(f)
}
}
impl Serialize for HttpReqByte {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
match self.data.is_empty() {
true => serializer.serialize_unit(),
false => {
let str = String::from_utf8(self.data.to_vec()).map_err(|err| <S as Serializer>::Error::custom(format!("{:?}", err)))?;
match str.not_empty() {
true => {
let raw_value = RawValue::from_string(str).map_err(|err| <S as Serializer>::Error::custom(format!("{:?}", err)))?;
raw_value.serialize(serializer)
}
false => serializer.serialize_str(str.as_str()),
}
}
}
}
}