Created
July 18, 2012 23:19
-
-
Save eholk/3139643 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // xfail-pretty | |
| // An example of the bank protocol from eholk's blog post. | |
| // | |
| // http://theincredibleholk.wordpress.com/2012/07/06/rusty-pipes/ | |
| import pipes::try_recv; | |
| type username = ~str; | |
| type password = ~str; | |
| type money = float; | |
| type amount = float; | |
| proto! bank { | |
| login:send { | |
| login(username, password) -> login_response | |
| } | |
| login_response:recv { | |
| ok -> connected, | |
| invalid -> login | |
| } | |
| connected:send { | |
| deposit(money) -> connected, | |
| withdrawal(amount) -> withdrawal_response | |
| } | |
| withdrawal_response:recv { | |
| money(money) -> connected, | |
| insufficient_funds -> connected | |
| } | |
| } | |
| macro_rules! move { | |
| { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } } | |
| } | |
| fn switch<T: send, U>(+endp: pipes::recv_packet<T>, | |
| f: fn(+option<T>) -> U) -> U { | |
| f(pipes::try_recv(endp)) | |
| } | |
| fn move<T>(-x: T) -> T { x } | |
| macro_rules! follow { | |
| { | |
| $($message:path($($x: ident),+) => $next:ident $e:expr)+ | |
| } => ( | |
| |m| alt move(m) { | |
| $(some($message($($x,)* next)) { | |
| let $next = move!{next}; | |
| $e })+ | |
| _ { fail } | |
| } | |
| ); | |
| { | |
| $($message:path => $next:ident $e:expr)+ | |
| } => ( | |
| |m| alt move(m) { | |
| $(some($message(next)) { | |
| let $next = move!{next}; | |
| $e })+ | |
| _ { fail } | |
| } | |
| ) | |
| } | |
| fn client_follow(+bank: bank::client::login) { | |
| import bank::*; | |
| let bank = client::login(bank, ~"theincredibleholk", ~"1234"); | |
| let bank = switch(bank, follow! { | |
| ok => connected { connected } | |
| invalid => _next { fail ~"bank closed the connected" } | |
| }); | |
| /* // potential alternate syntax | |
| let bank = recv_alt! { | |
| bank => { | |
| | ok -> connected { connected } | |
| | invalid -> _next { fail } | |
| } | |
| bank2 => { | |
| | foo -> _n { fail } | |
| } | |
| } | |
| */ | |
| let bank = client::deposit(bank, 100.00); | |
| let bank = client::withdrawal(bank, 50.00); | |
| alt try_recv(bank) { | |
| some(money(m, _)) { | |
| io::println(~"Yay! I got money!"); | |
| } | |
| some(insufficient_funds(_)) { | |
| fail ~"someone stole my money" | |
| } | |
| none { | |
| fail ~"bank closed the connection" | |
| } | |
| } | |
| } | |
| fn bank_client(+bank: bank::client::login) { | |
| import bank::*; | |
| let bank = client::login(bank, ~"theincredibleholk", ~"1234"); | |
| let bank = alt try_recv(bank) { | |
| some(ok(connected)) { | |
| move!{connected} | |
| } | |
| some(invalid(_)) { fail ~"login unsuccessful" } | |
| none { fail ~"bank closed the connection" } | |
| }; | |
| let bank = client::deposit(bank, 100.00); | |
| let bank = client::withdrawal(bank, 50.00); | |
| alt try_recv(bank) { | |
| some(money(m, _)) { | |
| io::println(~"Yay! I got money!"); | |
| } | |
| some(insufficient_funds(_)) { | |
| fail ~"someone stole my money" | |
| } | |
| none { | |
| fail ~"bank closed the connection" | |
| } | |
| } | |
| } | |
| fn main() { | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment