#![allow( clippy::type_complexity, clippy::too_many_arguments, clippy::large_enum_variant )] use mpstthree::binary::struct_trait::end::End; use mpstthree::binary_atmp::struct_trait::{recv::RecvTimed, send::SendTimed}; use mpstthree::generate_atmp; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use rand::{thread_rng, Rng}; use std::collections::HashMap; use std::error::Error; use std::time::Instant; generate_atmp!(MeshedChannels, Voter, Server); // Types // SERVER type Choose0fromStoV = SendTimed; // VOTER type Choose1fromVtoS = SendTimed; // VOTER enum Branching0fromStoV { Auth( MeshedChannels< RecvTimed, RoleServer, NameVoter, >, ), Reject( MeshedChannels< RecvTimed, RoleServer, NameVoter, >, ), } // SERVER enum Branching1fromVtoS { Yes( MeshedChannels< RecvTimed, RoleVoter, NameServer, >, ), No( MeshedChannels< RecvTimed, RoleVoter, NameServer, >, ), } type Choice1fromStoV = RecvTimed; // Creating the MP sessions // VOTER type ChoiceVoter = MeshedChannels< RecvTimed, RoleServer, NameVoter, >; type EndpointVoter = MeshedChannels< SendTimed< i32, 'a', 0, true, 10, true, ' ', RecvTimed, >, RoleServer>, NameVoter, >; // SERVER type ChoiceServer = MeshedChannels, NameServer>; type EndpointServer = MeshedChannels< RecvTimed, RoleVoter, NameServer, >; // Functions fn endpoint_voter( s: EndpointVoter, all_clocks: &mut HashMap, ) -> Result<(), Box> { let auth: i32 = thread_rng().gen_range(1..=2); all_clocks.insert('a', Instant::now()); let s = s.send(auth, all_clocks)?; offer_mpst!(s, all_clocks, { Branching0fromStoV::Reject(s) => { let (_, s) = s.recv(all_clocks)?; s.close() }, Branching0fromStoV::Auth(s) => { choice_voter(s, all_clocks) }, }) } fn choice_voter( s: ChoiceVoter, all_clocks: &mut HashMap, ) -> Result<(), Box> { let (ok, s) = s.recv(all_clocks)?; let expected: i32 = thread_rng().gen_range(1..=2); if ok == expected { let s = choose_mpst_voter_to_all!(s, all_clocks, Branching1fromVtoS::Yes); let s = s.send(1, all_clocks)?; s.close() } else { let s = choose_mpst_voter_to_all!(s, all_clocks, Branching1fromVtoS::No); let s = s.send(0, all_clocks)?; s.close() } } fn endpoint_server( s: EndpointServer, all_clocks: &mut HashMap, ) -> Result<(), Box> { let choice: i32 = thread_rng().gen_range(1..=2); all_clocks.insert('a', Instant::now()); let (auth, s) = s.recv(all_clocks)?; if choice == auth { let s = choose_mpst_server_to_all!(s, all_clocks, Branching0fromStoV::Reject); let s = s.send(0, all_clocks)?; s.close() } else { let s = choose_mpst_server_to_all!(s, all_clocks, Branching0fromStoV::Auth); let s = s.send(1, all_clocks)?; choice_server(s, all_clocks) } } fn choice_server( s: ChoiceServer, all_clocks: &mut HashMap, ) -> Result<(), Box> { offer_mpst!(s, all_clocks, { Branching1fromVtoS::Yes(s) => { let (_answer, s) = s.recv(all_clocks)?; s.close() }, Branching1fromVtoS::No(s) => { let (_answer, s) = s.recv(all_clocks)?; s.close() }, }) } fn main() { let (thread_server, thread_voter) = fork_mpst(endpoint_server, endpoint_voter); thread_voter.join().unwrap(); thread_server.join().unwrap(); }