#![allow( clippy::type_complexity, clippy::too_many_arguments, clippy::large_enum_variant )] use mpstthree::binary::struct_trait::session::Session; 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 std::error::Error; // Create the new MeshedChannels for three participants and the close and fork functions generate!( "rec_and_cancel", MeshedChannels, Calculator1, Calculator2, Server ); // Labels struct Data1 {} struct Data2 {} struct ProcesData2 {} struct ProcesData3 {} struct Complete {} struct Stop {} // Types // Calculator1 type OfferFromServertoCalculator1 = Recv; type Calculator1toCalculator2Data = Recv>; type Calculator1toServerData = Recv>; type Calculator1toCalculator2Stop = End; type Calculator1toServerStop = Recv; enum BranchingFromServertoCalculator1 { Data( MeshedChannels< Calculator1toCalculator2Data, Calculator1toServerData, RoleServer>>>>, NameCalculator1, >, ), Stop( MeshedChannels< Calculator1toCalculator2Stop, Calculator1toServerStop, RoleServer, NameCalculator1, >, ), } // Calculator2 type OfferFromServertoCalculator2 = Recv; type Calculator2toCalculator1Data = Send>; type Calculator2toServerData = Recv>; type Calculator2toCalculator1Stop = End; type Calculator2toServerStop = Recv; enum BranchingFromServertoCalculator2 { Data( MeshedChannels< Calculator2toCalculator1Data, Calculator2toServerData, RoleServer>>>>, NameCalculator2, >, ), Stop( MeshedChannels< Calculator2toCalculator1Stop, Calculator2toServerStop, RoleServer, NameCalculator2, >, ), } // Server type ChooseFromServertoCalculator1 = ::Dual; type ChooseFromServertoCalculator2 = ::Dual; type ServertoCalculator1Data = ::Dual; type ServertoCalculator2Data = ::Dual; type ServertoCalculator1Stop = ::Dual; type ServertoCalculator2Stop = ::Dual; // Endpoints // Calculator1 type Endpoint0Calculator1 = MeshedChannels, NameCalculator1>; // Calculator2 type Endpoint0Calculator2 = MeshedChannels, NameCalculator2>; // Server type Endpoint0Server = MeshedChannels< ChooseFromServertoCalculator1, ChooseFromServertoCalculator2, RoleBroadcast, NameServer, >; type Endpoint1ServerData = MeshedChannels< ServertoCalculator1Data, ServertoCalculator2Data, RoleCalculator1>>>, NameServer, >; type Endpoint1ServerStop = MeshedChannels< ServertoCalculator1Stop, ServertoCalculator2Stop, RoleCalculator1>, NameServer, >; // Functions ///////////////////////// // Calculator1 fn endpoint_calculator_1(s: Endpoint0Calculator1) -> Result<(), Box> { recurs_calculator_1(s) } fn recurs_calculator_1(s: Endpoint0Calculator1) -> Result<(), Box> { offer_mpst!(s, { BranchingFromServertoCalculator1::Stop(s) => { let (_stop, s) = s.recv()?; s.close() }, BranchingFromServertoCalculator1::Data(s) => { let (_data_1, s) = s.recv()?; let (_processed_data_2, s) = s.recv()?; let s = s.send(ProcesData3 {})?; let s = s.send(Complete {})?; recurs_calculator_1(s) }, }) } ///////////////////////// // Calculator2 fn endpoint_calculator_2(s: Endpoint0Calculator2) -> Result<(), Box> { recurs_calculator_2(s) } fn recurs_calculator_2(s: Endpoint0Calculator2) -> Result<(), Box> { offer_mpst!(s, { BranchingFromServertoCalculator2::Stop(s) => { let (_stop, s) = s.recv()?; s.close() }, BranchingFromServertoCalculator2::Data(s) => { let (_data_2, s) = s.recv()?; let s = s.send(ProcesData2 {})?; let (_complete, s) = s.recv()?; let (_complete, s) = s.recv()?; recurs_calculator_2(s) }, }) } ///////////////////////// // Server fn endpoint_server(s: Endpoint0Server) -> Result<(), Box> { recurs_server(s, LOOPS) } fn recurs_server(s: Endpoint0Server, loops: i64) -> Result<(), Box> { match loops { 0 => { let s: Endpoint1ServerStop = choose_mpst_server_to_all!( s, BranchingFromServertoCalculator1::Stop, BranchingFromServertoCalculator2::Stop, ); let s = s.send(Stop {})?; let s = s.send(Stop {})?; s.close() } i => { let s: Endpoint1ServerData = choose_mpst_server_to_all!( s, BranchingFromServertoCalculator1::Data, BranchingFromServertoCalculator2::Data, ); let s = s.send(Data1 {})?; let s = s.send(Data2 {})?; let (_data, s) = s.recv()?; let s = s.send(Complete {})?; recurs_server(s, i - 1) } } } ///////////////////////// fn main() { let (thread_calculator_1, thread_calculator_2, thread_server) = fork_mpst( endpoint_calculator_1, endpoint_calculator_2, endpoint_server, ); thread_calculator_1.join().unwrap(); thread_calculator_2.join().unwrap(); thread_server.join().unwrap(); } static LOOPS: i64 = 100;