rust/src/test/run-pass/pipe-bank-proto.rs

121 lines
3.0 KiB
Rust
Raw Normal View History

// xfail-fast
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
2012-07-06 15:42:06 -05:00
// An example of the bank protocol from eholk's blog post.
//
// http://theincredibleholk.wordpress.com/2012/07/06/rusty-pipes/
2013-02-02 05:10:12 -06:00
use core::pipes;
use core::pipes::try_recv;
2012-07-06 15:42:06 -05:00
pub type username = ~str;
pub type password = ~str;
pub type money = float;
pub type amount = float;
2012-07-06 15:42:06 -05:00
proto! bank (
2012-07-06 15:42:06 -05:00
login:send {
login(::username, ::password) -> login_response
2012-07-06 15:42:06 -05:00
}
login_response:recv {
ok -> connected,
invalid -> login
}
connected:send {
deposit(::money) -> connected,
withdrawal(::amount) -> withdrawal_response
2012-07-06 15:42:06 -05:00
}
withdrawal_response:recv {
money(::money) -> connected,
2012-07-06 15:42:06 -05:00
insufficient_funds -> connected
}
)
2012-07-06 15:42:06 -05:00
macro_rules! move_it (
2013-04-22 16:27:30 -05:00
{ $x:expr } => { unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } }
)
2012-07-06 15:42:06 -05:00
fn switch<T:Owned,U>(+endp: pipes::RecvPacket<T>,
f: &fn(+v: Option<T>) -> U) -> U {
2013-02-15 04:44:18 -06:00
f(pipes::try_recv(endp))
}
fn move_it<T>(+x: T) -> T { x }
macro_rules! follow (
2012-08-22 19:24:52 -05:00
{
$($message:path$(($($x: ident),+))||* -> $next:ident $e:expr)+
} => (
2013-02-15 04:44:18 -06:00
|m| match m {
2012-08-20 14:23:37 -05:00
$(Some($message($($($x,)+)* next)) => {
2012-08-22 19:24:52 -05:00
let $next = move_it!(next);
$e })+
_ => { fail!() }
}
);
)
fn client_follow(+bank: bank::client::login) {
use bank::*;
2013-02-15 04:44:18 -06:00
let bank = client::login(bank, ~"theincredibleholk", ~"1234");
let bank = switch(bank, follow! (
ok -> connected { connected }
invalid -> _next { fail!(~"bank closed the connected") }
2012-08-22 19:24:52 -05:00
));
2013-02-15 04:44:18 -06:00
let bank = client::deposit(bank, 100.00);
let bank = client::withdrawal(bank, 50.00);
switch(bank, follow! (
money(m) -> _next {
io::println(~"Yay! I got money!");
}
insufficient_funds -> _next {
fail!(~"someone stole my money")
}
2012-08-22 19:24:52 -05:00
));
}
2012-07-06 15:42:06 -05:00
fn bank_client(+bank: bank::client::login) {
use bank::*;
2012-07-06 15:42:06 -05:00
2013-02-15 04:44:18 -06:00
let bank = client::login(bank, ~"theincredibleholk", ~"1234");
let bank = match try_recv(bank) {
2012-08-20 14:23:37 -05:00
Some(ok(connected)) => {
2012-08-22 19:24:52 -05:00
move_it!(connected)
2012-07-06 15:42:06 -05:00
}
Some(invalid(_)) => { fail!(~"login unsuccessful") }
None => { fail!(~"bank closed the connection") }
2012-07-06 15:42:06 -05:00
};
2013-02-15 04:44:18 -06:00
let bank = client::deposit(bank, 100.00);
let bank = client::withdrawal(bank, 50.00);
match try_recv(bank) {
2012-09-19 00:45:24 -05:00
Some(money(*)) => {
io::println(~"Yay! I got money!");
2012-07-06 15:42:06 -05:00
}
2012-08-20 14:23:37 -05:00
Some(insufficient_funds(_)) => {
fail!(~"someone stole my money")
2012-07-06 15:42:06 -05:00
}
2012-08-20 14:23:37 -05:00
None => {
fail!(~"bank closed the connection")
2012-07-06 15:42:06 -05:00
}
}
}
pub fn main() {
}