dce-router 1.8.0

A router for all type programming api route.
Documentation
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>;
}