use std::marker::PhantomData;
use bytes::Bytes;
use dce_util::result::{DceError, DceResult, DceVoid};
use crate::{context::Context, protocol::RoutableProtocol};
pub struct RequestDecoder<'a, Rp: RoutableProtocol + 'static, ReqDto, Deser: Deserializer<ReqDto>> {
ctx: &'a mut Context<Rp>,
deserializer: Deser,
_phantom: PhantomData<ReqDto>,
}
impl <'a, Rp: RoutableProtocol + 'static, ReqDto, Deser: Deserializer<ReqDto>> RequestDecoder<'a, Rp, ReqDto, Deser> {
pub fn new(ctx: &'a mut Context<Rp>, deserializer: Deser) -> Self {
Self {ctx, deserializer, _phantom: Default::default()}
}
pub fn sync_deserialize(&mut self) -> DceResult<ReqDto> {
self.ctx.sync_body().map(|b| self.deserializer.deserialize(b)).flatten()
}
pub async fn deserialize(&mut self) -> DceResult<ReqDto> {
self.ctx.body().await.map(|b| self.deserializer.deserialize(b)).flatten()
}
pub fn sync_parse<Req: From<ReqDto>>(&mut self) -> DceResult<Req> {
self.sync_deserialize().map(|dto| Req::from(dto))
}
pub async fn parse<Req: From<ReqDto>>(&mut self) -> DceResult<Req> {
self.deserialize().await.map(|dto| Req::from(dto))
}
}
pub struct ResponseBuilder<'a, Rp: RoutableProtocol + 'static, RespDto, Ser: Serializer<RespDto>, Sta: Status> {
ctx: &'a mut Context<Rp>,
serializer: Ser,
status_serializer: Option<&'a dyn Serializer<Sta>>,
_phantom: PhantomData<RespDto>,
}
impl <'a, Rp: RoutableProtocol + 'static, RespDto: 'static, Ser: Serializer<RespDto>, Sta: Status> ResponseBuilder<'a, Rp, RespDto, Ser, Sta> {
pub fn new(ctx: &'a mut Context<Rp>, serializer: Ser, status_serializer: Option<&'a dyn Serializer<Sta>>) -> Self {
Self {ctx, serializer, status_serializer, _phantom: Default::default()}
}
pub fn response<Resp: Into<RespDto>>(&mut self, obj: Resp) -> DceVoid {
let dto = obj.into();
let bytes = self.serializer.serialize(dto)?;
Ok(self.ctx.write(bytes))
}
pub fn error(&mut self, err: DceError) -> DceVoid {
self.status(Some(err), None)
}
pub fn success(&mut self, data: Option<String>) -> DceVoid {
self.status(None, data)
}
pub fn fail(&mut self, msg: String, code: isize) -> DceVoid {
self.status(Some(DceError::msg(true, code, msg)), None)
}
pub fn status(&mut self, err: Option<DceError>, data: Option<String>) -> DceVoid {
let status = if let Some(err) = &err {
Sta::new(false, err.code, Some(err.to_string()), data)
} else {
Sta::new(true, 0, None, data)
};
if let Some(status_serializer) = &self.status_serializer {
let bytes = status_serializer.serialize(status)?;
return Ok(self.ctx.write(bytes));
}
panic!("Cannot serialize the Status because the Serializer is None");
}
}
pub trait Deserializer<T> {
fn deserialize(&self, bytes: Bytes) -> DceResult<T>;
}
pub trait Serializer<T> {
fn serialize(&self, obj: T) -> DceResult<Bytes>;
}
pub trait Status: Sized {
fn new(status: bool, code: isize, msg: Option<String>, data: Option<String>) -> Self;
fn status(&self) -> bool;
fn code(&self) -> isize;
fn msg(&self) -> &Option<String>;
fn data(&self) -> &Option<String>;
}