use std::future::{ready, Ready}; use btlib::Result; use btproto::protocol; use btrun::{CallMsg, End}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] pub struct Ping; impl CallMsg for Ping { type Reply = (); } /// Tests that the given variable is of the given type. macro_rules! assert_type { ($var:expr, $ty:ty) => {{ let _: $ty = $var; }}; } #[test] fn minimal_syntax() { pub struct Msg; protocol! { named MinimalTest; let states = [Server]; let client = [Client]; Client -> End, >service(Server)!Msg; Server?Msg -> End; } let msg: Option<MinimalTestMsgs> = None; match msg { Some(MinimalTestMsgs::Msg(act)) => assert_type!(act, Msg), None => (), } struct ServerState; impl Server for ServerState { type HandleMsgFut = Ready<Result<End>>; fn handle_msg(self, _msg: Msg) -> Self::HandleMsgFut { ready(Ok(End)) } } } #[test] fn reply() { protocol! { named ReplyTest; let server = [Listening]; let client = [Client, Waiting]; Client -> Waiting, >service(Listening)!Ping; Listening?Ping -> Listening, >Waiting!Ping::Reply; Waiting?Ping::Reply -> End; } let msg: Option<ReplyTestMsgs> = None; match msg { Some(ReplyTestMsgs::Ping(ping)) => assert_type!(ping, Ping), Some(ReplyTestMsgs::PingReply(reply)) => assert_type!(reply, <Ping as CallMsg>::Reply), None => (), } struct ListeningState; impl Listening for ListeningState { type HandlePingListening = Self; type HandlePingFut = Ready<Result<Self>>; fn handle_ping(self, _msg: Ping) -> Self::HandlePingFut { ready(Ok(self)) } } struct ClientState; impl Client for ClientState { type SendPingWaiting = WaitingState; type SendPingFut = Ready<Result<WaitingState>>; fn send_ping(self) -> Self::SendPingFut { ready(Ok(WaitingState)) } } struct WaitingState; impl Waiting for WaitingState { type HandlePingReplyFut = Ready<Result<End>>; fn handle_ping_reply(self, _msg: Ping) -> Self::HandlePingReplyFut { ready(Ok(End)) } } }