2012-12-13 15:05:22 -06:00
|
|
|
// xfail-fast
|
|
|
|
|
2012-12-10 19:32:48 -06:00
|
|
|
// 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
|
|
|
|
2013-01-08 21:37:25 -06: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
|
|
|
|
2012-08-22 20:10:48 -05:00
|
|
|
proto! bank (
|
2012-07-06 15:42:06 -05:00
|
|
|
login:send {
|
2013-01-08 21:37:25 -06:00
|
|
|
login(::username, ::password) -> login_response
|
2012-07-06 15:42:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
login_response:recv {
|
|
|
|
ok -> connected,
|
|
|
|
invalid -> login
|
|
|
|
}
|
|
|
|
|
|
|
|
connected:send {
|
2013-01-08 21:37:25 -06:00
|
|
|
deposit(::money) -> connected,
|
|
|
|
withdrawal(::amount) -> withdrawal_response
|
2012-07-06 15:42:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
withdrawal_response:recv {
|
2013-01-08 21:37:25 -06:00
|
|
|
money(::money) -> connected,
|
2012-07-06 15:42:06 -05:00
|
|
|
insufficient_funds -> connected
|
|
|
|
}
|
2012-08-22 20:10:48 -05:00
|
|
|
)
|
2012-07-06 15:42:06 -05:00
|
|
|
|
2012-08-22 19:47:11 -05:00
|
|
|
macro_rules! move_it (
|
2013-02-15 04:44:18 -06:00
|
|
|
{ $x:expr } => { unsafe { let y = *ptr::addr_of(&($x)); y } }
|
2012-08-22 19:47:11 -05:00
|
|
|
)
|
2012-07-06 15:42:06 -05:00
|
|
|
|
2013-02-20 19:07:17 -06:00
|
|
|
fn switch<T:Owned,U>(+endp: pipes::RecvPacket<T>,
|
2013-03-07 16:38:38 -06:00
|
|
|
f: &fn(+v: Option<T>) -> U) -> U {
|
2013-02-15 04:44:18 -06:00
|
|
|
f(pipes::try_recv(endp))
|
2012-07-18 18:28:58 -05:00
|
|
|
}
|
|
|
|
|
2013-03-10 10:02:16 -05:00
|
|
|
fn move_it<T>(+x: T) -> T { x }
|
2012-07-18 18:28:58 -05:00
|
|
|
|
2012-08-22 19:47:11 -05:00
|
|
|
macro_rules! follow (
|
2012-08-22 19:24:52 -05:00
|
|
|
{
|
2012-08-06 16:51:53 -05:00
|
|
|
$($message:path$(($($x: ident),+))||* -> $next:ident $e:expr)+
|
2012-07-18 18:28:58 -05:00
|
|
|
} => (
|
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);
|
2012-07-18 18:28:58 -05:00
|
|
|
$e })+
|
2013-02-11 21:26:38 -06:00
|
|
|
_ => { fail!() }
|
2012-07-18 18:28:58 -05:00
|
|
|
}
|
|
|
|
);
|
2012-08-22 19:47:11 -05:00
|
|
|
)
|
2012-07-18 18:28:58 -05:00
|
|
|
|
|
|
|
fn client_follow(+bank: bank::client::login) {
|
2012-09-07 20:08:21 -05:00
|
|
|
use bank::*;
|
2012-07-18 18:28:58 -05:00
|
|
|
|
2013-02-15 04:44:18 -06:00
|
|
|
let bank = client::login(bank, ~"theincredibleholk", ~"1234");
|
|
|
|
let bank = switch(bank, follow! (
|
|
|
|
ok -> connected { connected }
|
2013-02-11 21:26:38 -06:00
|
|
|
invalid -> _next { fail!(~"bank closed the connected") }
|
2012-08-22 19:24:52 -05:00
|
|
|
));
|
2012-07-18 18:28:58 -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! (
|
2012-08-06 16:51:53 -05:00
|
|
|
money(m) -> _next {
|
|
|
|
io::println(~"Yay! I got money!");
|
|
|
|
}
|
|
|
|
insufficient_funds -> _next {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!(~"someone stole my money")
|
2012-08-06 16:51:53 -05:00
|
|
|
}
|
2012-08-22 19:24:52 -05:00
|
|
|
));
|
2012-07-18 18:28:58 -05:00
|
|
|
}
|
|
|
|
|
2012-07-06 15:42:06 -05:00
|
|
|
fn bank_client(+bank: bank::client::login) {
|
2012-09-07 20:08:21 -05:00
|
|
|
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
|
|
|
}
|
2013-02-11 21:26:38 -06: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(*)) => {
|
2012-07-14 00:57:48 -05:00
|
|
|
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(_)) => {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!(~"someone stole my money")
|
2012-07-06 15:42:06 -05:00
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
None => {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!(~"bank closed the connection")
|
2012-07-06 15:42:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-01 21:43:17 -06:00
|
|
|
pub fn main() {
|
2012-07-31 21:27:23 -05:00
|
|
|
}
|