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))
}
}
}