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 = None; match msg { Some(MinimalTestMsgs::Msg(act)) => assert_type!(act, Msg), None => (), } struct ServerState; impl Server for ServerState { type HandleMsgFut = Ready>; fn handle_msg(self, _msg: Msg) -> Self::HandleMsgFut { ready(Ok(End)) } } struct ClientState; impl Client for ClientState { type SendMsgFut = Ready>; fn send_msg(self, _msg: Msg) -> Self::SendMsgFut { 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 = None; match msg { Some(ReplyTestMsgs::Ping(ping)) => assert_type!(ping, Ping), Some(ReplyTestMsgs::PingReply(reply)) => assert_type!(reply, ::Reply), None => (), } struct ListeningState; impl Listening for ListeningState { type HandlePingListening = Self; type HandlePingFut = Ready::Reply)>>; fn handle_ping(self, _msg: Ping) -> Self::HandlePingFut { ready(Ok((self, ()))) } } struct ClientState; impl Client for ClientState { type SendPingWaiting = WaitingState; type SendPingFut = Ready::Reply)>>; fn send_ping(self, _ping: Ping) -> Self::SendPingFut { ready(Ok((WaitingState, ()))) } } struct WaitingState; // TODO: This state should not be generated, as it is never observed. impl Waiting for WaitingState { type HandlePingReplyFut = Ready>; fn handle_ping_reply(self, _msg: ()) -> Self::HandlePingReplyFut { ready(Ok(End)) } } }