use nix::errno::Errno;
use razor_rpc_codec::MsgpCodec;
use razor_stream::{Codec, error::RpcErrCodec};
use razor_stream::{
proto::{RpcAction, RpcActionOwned},
server::RpcSvrResp,
server::task::*,
};
use razor_stream_macros::server_task_enum;
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Default, PartialEq)]
struct ReqMsg1 {
pub val: u32,
}
#[derive(Serialize, Deserialize, Debug, Default, PartialEq)]
struct ReqMsg2 {
pub name: String,
}
#[derive(Serialize, Deserialize, Debug, Default)]
struct Msg1;
#[derive(Serialize, Deserialize, Debug, Default)]
struct Msg2;
#[derive(Debug, Default, PartialEq)]
struct StaticActionTask;
impl<R: Send + Unpin + 'static> ServerTaskDecode<R> for StaticActionTask {
fn decode_req<'a, C: Codec>(
_codec: &'a C, _action: RpcAction<'a>, _seq: u64, _req: &'a [u8],
_blob: Option<io_buffer::Buffer>, _noti: RespNoti<R>,
) -> Result<Self, ()> {
Ok(StaticActionTask)
}
}
#[test]
fn test_server_task_enum_req_macro() {
#[server_task_enum(req, resp_type=RpcSvrResp, error = Errno)]
#[derive(Debug)]
pub enum ExampleServerTaskReq {
#[action(1)]
Task1(ServerTaskVariant<RpcSvrResp, ReqMsg1, Errno>),
#[action("sub_task_2")]
Task2(ServerTaskVariant<RpcSvrResp, ReqMsg2, Errno>),
#[action("static_action")] Task3(StaticActionTask),
}
let codec = MsgpCodec::default();
let (tx, _rx) = crossfire::mpsc::unbounded_async();
let noti: RespNoti<RpcSvrResp> = RespNoti::new(tx);
let req_msg_1_data = ReqMsg1 { val: 100 };
let req_msg_1_buf = codec.encode(&req_msg_1_data).unwrap();
let task1 = <ExampleServerTaskReq as ServerTaskDecode<RpcSvrResp>>::decode_req(
&codec,
RpcAction::Num(1),
123,
&req_msg_1_buf,
None,
noti.clone(),
)
.unwrap();
if let ExampleServerTaskReq::Task1(req_task_variant) = task1 {
assert_eq!(req_task_variant.seq, 123);
assert_eq!(req_task_variant.msg, req_msg_1_data);
assert!(req_task_variant.blob.is_none()); } else {
panic!("Decoded to wrong variant");
}
let req_msg_2_data = ReqMsg2 { name: "test_name".to_string() };
let req_msg_2_buf = codec.encode(&req_msg_2_data).unwrap();
let task2 = <ExampleServerTaskReq as ServerTaskDecode<RpcSvrResp>>::decode_req(
&codec,
RpcAction::Str("sub_task_2"),
456,
&req_msg_2_buf,
None,
noti.clone(),
)
.unwrap();
assert_eq!(task2.get_action(), RpcAction::Str("sub_task_2"));
if let ExampleServerTaskReq::Task2(req_task_variant) = task2 {
assert_eq!(req_task_variant.seq, 456);
assert_eq!(req_task_variant.msg, req_msg_2_data);
assert!(req_task_variant.blob.is_none()); } else {
panic!("Decoded to wrong variant");
}
let task3 = <ExampleServerTaskReq as ServerTaskDecode<RpcSvrResp>>::decode_req(
&codec,
RpcAction::Str("static_action"),
0, &[], None, noti.clone(),
)
.unwrap();
assert_eq!(task3.get_action(), RpcAction::Str("static_action"));
if let ExampleServerTaskReq::Task3(inner_task) = task3 {
assert_eq!(inner_task, StaticActionTask);
} else {
panic!("Decoded to wrong variant");
}
let req_task_variant_from_sub = ServerTaskVariant {
seq: 3,
action: RpcActionOwned::Num(1),
msg: ReqMsg1::default(),
blob: None,
res: None,
noti: Some(noti.clone()),
};
let server_task_from_sub: ExampleServerTaskReq = req_task_variant_from_sub.into();
assert!(matches!(server_task_from_sub, ExampleServerTaskReq::Task1(_)));
assert_eq!(server_task_from_sub.get_action(), RpcAction::Num(1));
}
#[test]
fn test_server_task_enum_resp_macro() {
#[server_task_enum(resp, error = Errno)]
#[derive(Debug)]
pub enum ExampleServerTaskResp {
Task1(ServerTaskVariant<ExampleServerTaskResp, Msg1, Errno>),
Task2(ServerTaskVariant<ExampleServerTaskResp, Msg2, Errno>),
}
let codec = MsgpCodec::default();
let (tx, _rx) = crossfire::mpsc::unbounded_async();
let noti: RespNoti<ExampleServerTaskResp> = RespNoti::new(tx);
let msg1_buf = codec.encode(&Msg1::default()).unwrap();
let variant1: ServerTaskVariant<ExampleServerTaskResp, Msg1, Errno> =
<ServerTaskVariant<ExampleServerTaskResp, Msg1, Errno> as ServerTaskDecode<
ExampleServerTaskResp,
>>::decode_req(&codec, RpcAction::Num(1), 123, &msg1_buf, None, noti.clone())
.unwrap();
let msg2_buf = codec.encode(&Msg2::default()).unwrap();
let variant2: ServerTaskVariant<ExampleServerTaskResp, Msg2, Errno> =
<ServerTaskVariant<ExampleServerTaskResp, Msg2, Errno> as ServerTaskDecode<
ExampleServerTaskResp,
>>::decode_req(&codec, RpcAction::Num(2), 456, &msg2_buf, None, noti.clone())
.unwrap();
let mut task1_for_encode = ExampleServerTaskResp::Task1(variant1);
<ExampleServerTaskResp as ServerTaskDone<ExampleServerTaskResp, Errno>>::_set_result(
&mut task1_for_encode,
Err(Errno::EPERM.into()),
);
let mut buf = Vec::new();
let (seq1, resp1) = <ExampleServerTaskResp as ServerTaskEncode>::encode_resp(
&mut task1_for_encode,
&codec,
&mut buf,
);
assert_eq!(seq1, 123);
assert_eq!(resp1.unwrap_err(), Errno::EPERM.encode(&codec));
let mut task2_for_encode = ExampleServerTaskResp::Task2(variant2);
<ExampleServerTaskResp as ServerTaskDone<ExampleServerTaskResp, Errno>>::_set_result(
&mut task2_for_encode,
Ok(()),
);
let mut buf = Vec::new();
let (seq2, resp2) = <ExampleServerTaskResp as ServerTaskEncode>::encode_resp(
&mut task2_for_encode,
&codec,
&mut buf,
);
assert_eq!(seq2, 456);
assert!(resp2.is_ok());
let mut task_for_set_result = ExampleServerTaskResp::Task1(
<ServerTaskVariant<ExampleServerTaskResp, Msg1, Errno> as ServerTaskDecode<
ExampleServerTaskResp,
>>::decode_req(&codec, RpcAction::Num(1), 789, &msg1_buf, None, noti.clone())
.unwrap(),
);
let _: RespNoti<ExampleServerTaskResp> = <ExampleServerTaskResp as ServerTaskDone<
ExampleServerTaskResp,
Errno,
>>::_set_result(&mut task_for_set_result, Ok(()));
#[allow(unused_mut)]
let mut task_for_set_result_done = ExampleServerTaskResp::Task2(
<ServerTaskVariant<ExampleServerTaskResp, Msg2, Errno> as ServerTaskDecode<
ExampleServerTaskResp,
>>::decode_req(&codec, RpcAction::Num(2), 101, &msg2_buf, None, noti.clone())
.unwrap(),
);
task_for_set_result_done.set_result(Ok(()));
}
#[test]
fn test_server_task_enum_multiple_actions() {
#[server_task_enum(req, resp_type=RpcSvrResp, error = Errno)]
#[derive(Debug)]
pub enum MultiActionServerTask {
#[action(1, 2, "action_str")]
TaskA(ServerTaskVariant<RpcSvrResp, ReqMsg1, Errno>),
}
let codec = MsgpCodec::default();
let (tx, _rx) = crossfire::mpsc::unbounded_async();
let noti: RespNoti<RpcSvrResp> = RespNoti::new(tx);
let req_msg_data = ReqMsg1 { val: 100 };
let req_msg_buf = codec.encode(&req_msg_data).unwrap();
let task1 = <MultiActionServerTask as ServerTaskDecode<RpcSvrResp>>::decode_req(
&codec,
RpcAction::Num(1),
123,
&req_msg_buf,
None,
noti.clone(),
)
.unwrap();
assert_eq!(task1.get_action(), RpcAction::Num(1));
let MultiActionServerTask::TaskA(req_task_variant) = task1;
assert_eq!(req_task_variant.seq, 123);
assert_eq!(req_task_variant.msg, req_msg_data);
let task2 = <MultiActionServerTask as ServerTaskDecode<RpcSvrResp>>::decode_req(
&codec,
RpcAction::Num(2),
456,
&req_msg_buf,
None,
noti.clone(),
)
.unwrap();
assert_eq!(task2.get_action(), RpcAction::Num(2));
let MultiActionServerTask::TaskA(req_task_variant) = task2;
assert_eq!(req_task_variant.seq, 456);
assert_eq!(req_task_variant.msg, req_msg_data);
let task3 = <MultiActionServerTask as ServerTaskDecode<RpcSvrResp>>::decode_req(
&codec,
RpcAction::Str("action_str"),
789,
&req_msg_buf,
None,
noti.clone(),
)
.unwrap();
assert_eq!(task3.get_action(), RpcAction::Str("action_str"));
let MultiActionServerTask::TaskA(req_task_variant) = task3;
assert_eq!(req_task_variant.seq, 789);
assert_eq!(req_task_variant.msg, req_msg_data);
}