Skip to main content

razor_rpc/server/
task.rs

1//! task for server internal use, only need to known when you are writing
2//! [Dispatch](crate::server::dispatch)
3
4use crate::{Codec, error::*};
5use razor_stream::server::task::{RespNoti, ServerTaskEncode, ServerTaskResp};
6use serde::{Deserialize, Serialize};
7use std::fmt;
8use std::io::Write;
9use std::sync::Arc;
10
11pub struct APIServerReq<C: Codec> {
12    pub seq: u64,
13    pub service: String,
14    pub method: String,
15    pub req: Option<Vec<u8>>,
16    pub codec: Arc<C>,
17    pub noti: RespNoti<APIServerResp>,
18}
19
20impl<C: Codec> APIServerReq<C> {
21    #[inline]
22    pub fn decode<'a, R: Deserialize<'a>>(&'a mut self, buf: &'a [u8]) -> Result<R, ()> {
23        self.codec.decode::<R>(buf)
24    }
25
26    #[inline(always)]
27    pub fn set_result<R: Serialize>(self, resp: R) {
28        match self.codec.encode::<R>(&resp) {
29            Err(()) => {
30                self.noti.done(APIServerResp {
31                    seq: self.seq,
32                    msg: None,
33                    res: Some(Err(RpcIntErr::Encode.into())),
34                });
35            }
36            Ok(msg) => {
37                self.noti.done(APIServerResp { seq: self.seq, msg: Some(msg), res: Some(Ok(())) });
38            }
39        }
40    }
41
42    #[inline(always)]
43    pub fn set_rpc_error(self, e: RpcIntErr) {
44        self.noti.done(APIServerResp { seq: self.seq, msg: None, res: Some(Err(e.into())) });
45    }
46
47    #[inline(always)]
48    pub fn set_error<E: RpcErrCodec>(self, e: RpcError<E>) {
49        let encoded_err = match e {
50            RpcError::Rpc(rpc_int_err) => rpc_int_err.into(),
51            RpcError::User(user_err) => user_err.encode(self.codec.as_ref()),
52        };
53        self.noti.done(APIServerResp { seq: self.seq, msg: None, res: Some(Err(encoded_err)) });
54    }
55}
56
57pub struct APIServerResp {
58    pub seq: u64,
59    pub msg: Option<Vec<u8>>,
60    pub res: Option<Result<(), EncodedErr>>,
61}
62
63impl fmt::Debug for APIServerResp {
64    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65        write!(f, "resp {} res {:?}", self.seq, self.res)
66    }
67}
68
69impl ServerTaskEncode for APIServerResp {
70    #[inline]
71    fn encode_resp<'a, 'b, C: Codec>(
72        &'a mut self, _codec: &'b C, buf: &'b mut Vec<u8>,
73    ) -> (u64, Result<(usize, Option<&'a [u8]>), EncodedErr>) {
74        match self.res.take().unwrap() {
75            Ok(()) => {
76                if let Some(msg) = self.msg.as_ref() {
77                    buf.write_all(msg).expect("fill msg buf");
78                    (self.seq, Ok((msg.len(), None)))
79                } else {
80                    (self.seq, Ok((0, None)))
81                }
82            }
83            Err(e) => (self.seq, Err(e)),
84        }
85    }
86}
87
88impl ServerTaskResp for APIServerResp {}