use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::generate; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use rand::{random, thread_rng, Rng}; use std::error::Error; // See the folder scribble_protocols for the related Scribble protocol // Create the new MeshedChannels for three participants and the close and fork functions generate!("recursive", MeshedChannels, Client, Other, Server,); // Types // SERVER type Choose0fromServerToClient = Send; type Choose0fromServerToOther = Send; // CLIENT enum Branching0fromServerToClient { Dummy(MeshedChannels, RoleServer, NameClient>), Query(MeshedChannels, RoleServer, NameClient>), } // OTHER enum Branching0fromServerToOther { Dummy(MeshedChannels, RoleServer, NameOther>), Query( MeshedChannels< End, Recv<(i32, i32), Send<(i32, i32), End>>, RoleServer>, NameOther, >, ), } // Creating the MP sessions // CLIENT type EndpointClient = MeshedChannels< End, Send>, RoleServer>, NameClient, >; // OTHER type EndpointOther = MeshedChannels, RoleServer, NameOther>; // SERVER type EndpointQuery = MeshedChannels< Send<(i32, i32), End>, Send<(i32, i32), Recv<(i32, i32), End>>, RoleOther>>, NameServer, >; type EndpointDummy = MeshedChannels< Send<(i32, i32), End>, Send<(), End>, RoleOther>, NameServer, >; type EndpointServer = MeshedChannels< Recv, Choose0fromServerToOther, RoleClient, NameServer, >; // Functions fn endpoint_client(s: EndpointClient) -> Result<(), Box> { let address = random::(); let s = s.send(address); offer_mpst!(s, { Branching0fromServerToClient::Dummy(s) => { let (_, s) = s.recv(); s.close() }, Branching0fromServerToClient::Query(s) => { let ((_new_address, _new_packet), s) = s.recv(); s.close() }, }) } fn endpoint_other(s: EndpointOther) -> Result<(), Box> { offer_mpst!(s, { Branching0fromServerToOther::Dummy(s) => { let (_, s) = s.recv(); s.close() }, Branching0fromServerToOther::Query(s) => { let ((address, packet), s) = s.recv(); let s = s.send((-address, -packet)); s.close() }, }) } fn endpoint_server(s: EndpointServer) -> Result<(), Box> { let choice: i32 = thread_rng().gen_range(1..3); let (address, s) = s.recv(); if choice == 1 { let s: EndpointDummy = choose_mpst_server_to_all!( s, Branching0fromServerToClient::Dummy, Branching0fromServerToOther::Dummy ); let s = s.send(()); let packet = random::(); let s = s.send((address, packet)); s.close() } else { let s: EndpointQuery = choose_mpst_server_to_all!( s, Branching0fromServerToClient::Query, Branching0fromServerToOther::Query ); let packet = random::(); let s = s.send((address, packet)); let ((new_address, new_packet), s) = s.recv(); let s = s.send((new_address, new_packet)); s.close() } } fn main() { let (thread_other, thread_server, thread_client) = fork_mpst(endpoint_client, endpoint_other, endpoint_server); thread_client.join().unwrap(); thread_server.join().unwrap(); thread_other.join().unwrap(); }