use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send, session::Session}; use mpstthree::generate; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use rand::{thread_rng, Rng}; use std::error::Error; // See the folder scribble_protocols for the related Scribble protocol // Create new MeshedChannels for four participants generate!("rec_and_cancel", MeshedChannels, Voter, Server); // Types // SERVER type Choose0fromStoV = Send; // VOTER type Choose1fromVtoS = ::Dual; // VOTER enum Branching0fromStoV { Auth(MeshedChannels, RoleServer, NameVoter>), Reject(MeshedChannels, RoleServer, NameVoter>), } // SERVER enum Branching1fromVtoS { Yes(MeshedChannels, RoleVoter, NameServer>), No(MeshedChannels, RoleVoter, NameServer>), } type Choice1fromStoV = Recv; // Creating the MP sessions // VOTER type ChoiceVoter = MeshedChannels, RoleServer, NameVoter>; type EndpointVoter = MeshedChannels< Send>, RoleServer>, NameVoter, >; // SERVER type ChoiceServer = MeshedChannels, NameServer>; type EndpointServer = MeshedChannels, RoleVoter, NameServer>; // Functions fn endpoint_voter(s: EndpointVoter) -> Result<(), Box> { let auth: i32 = thread_rng().gen_range(1..=2); let s = s.send(auth)?; offer_mpst!(s, { Branching0fromStoV::Reject(s) => { let (_, s) = s.recv()?; s.close() }, Branching0fromStoV::Auth(s) => { choice_voter(s) }, }) } fn choice_voter(s: ChoiceVoter) -> Result<(), Box> { let (ok, s) = s.recv()?; let expected: i32 = thread_rng().gen_range(1..=2); if ok == expected { let s = choose_mpst_voter_to_all!(s, Branching1fromVtoS::Yes); let s = s.send(1)?; s.close() } else { let s = choose_mpst_voter_to_all!(s, Branching1fromVtoS::No); let s = s.send(0)?; s.close() } } fn endpoint_server(s: EndpointServer) -> Result<(), Box> { let choice: i32 = thread_rng().gen_range(1..=2); let (auth, s) = s.recv()?; if choice == auth { let s = choose_mpst_server_to_all!(s, Branching0fromStoV::Reject); let s = s.send(0)?; s.close() } else { let s = choose_mpst_server_to_all!(s, Branching0fromStoV::Auth); let s = s.send(1)?; choice_server(s) } } fn choice_server(s: ChoiceServer) -> Result<(), Box> { offer_mpst!(s, { Branching1fromVtoS::Yes(s) => { let (_answer, s) = s.recv()?; s.close() }, Branching1fromVtoS::No(s) => { let (_answer, s) = s.recv()?; s.close() }, }) } fn main() { let (thread_server, thread_voter) = fork_mpst(endpoint_server, endpoint_voter); thread_voter.join().unwrap(); thread_server.join().unwrap(); }