#![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, Satellite, Sensor, Server); // Labels struct Stop {} struct GetData {} struct Data {} // Types // Satellite type OfferFromServertoSatellite = Recv; type BinaryDataFromSensortoSatellite = Send>; type BinaryDataFromServertoSatellite = Recv>; type BinaryStopFromSensortoSatellite = Send; type BinaryStopFromServertoSatellite = Recv; enum BranchingFromServertoSatellite { Data( MeshedChannels< BinaryDataFromSensortoSatellite, BinaryDataFromServertoSatellite, RoleServer>>>>, NameSatellite, >, ), Stop( MeshedChannels< BinaryStopFromSensortoSatellite, BinaryStopFromServertoSatellite, RoleServer>, NameSatellite, >, ), } // Sensor type OfferFromServertoSensor = Recv; type BinaryDataFromSatellitetoSensor = ::Dual; type BinaryStopFromSatellitetoSensor = ::Dual; enum BranchingFromServertoSensor { Data( MeshedChannels< BinaryDataFromSatellitetoSensor, OfferFromServertoSensor, RoleSatellite>>, NameSensor, >, ), Stop(MeshedChannels, NameSensor>), } // Server type ChooseFromServertoSatellite = ::Dual; type ChooseFromServertoSensor = ::Dual; type BinaryDataFromSatellitetoServer = ::Dual; type BinaryStopFromSatellitetoServer = ::Dual; // Endpoints // Satellite type EndpointSatellite0 = MeshedChannels, NameSatellite>; // Sensor type EndpointSensor0 = MeshedChannels, NameSensor>; // Server type EndpointServer0 = MeshedChannels< ChooseFromServertoSatellite, ChooseFromServertoSensor, RoleBroadcast, NameServer, >; type EndpointServer1Data = MeshedChannels< BinaryDataFromSatellitetoServer, ChooseFromServertoSensor, RoleSatellite>, NameServer, >; type EndpointServer1Stop = MeshedChannels, NameServer>; // Functions ///////////////////////// // Satellite fn endpoint_satellite(s: EndpointSatellite0) -> Result<(), Box> { recurs_satellite(s) } fn recurs_satellite(s: EndpointSatellite0) -> Result<(), Box> { offer_mpst!(s, { BranchingFromServertoSatellite::Stop(s) => { let (stop, s) = s.recv()?; let s = s.send(stop)?; s.close() }, BranchingFromServertoSatellite::Data(s) => { // Forward get_data signal let (get_data, s) = s.recv()?; let s = s.send(get_data)?; // Forward the data let (data, s) = s.recv()?; let s = s.send(data)?; recurs_satellite(s) }, }) } ///////////////////////// // Sensor fn endpoint_sensor(s: EndpointSensor0) -> Result<(), Box> { recurs_sensor(s) } fn recurs_sensor(s: EndpointSensor0) -> Result<(), Box> { offer_mpst!(s, { BranchingFromServertoSensor::Stop(s) => { let (_stop, s) = s.recv()?; s.close() }, BranchingFromServertoSensor::Data(s) => { // Get get_data signal let (_get_data, s) = s.recv()?; // Send the data let s = s.send(Data {})?; recurs_sensor(s) }, }) } ///////////////////////// // Server fn endpoint_server(s: EndpointServer0) -> Result<(), Box> { recurs_server(s, 100) } fn recurs_server(s: EndpointServer0, loops: i32) -> Result<(), Box> { match loops { 0 => { let s: EndpointServer1Stop = choose_mpst_server_to_all!( s, BranchingFromServertoSatellite::Stop, BranchingFromServertoSensor::Stop, ); let s = s.send(Stop {})?; s.close() } i => { let s: EndpointServer1Data = choose_mpst_server_to_all!( s, BranchingFromServertoSatellite::Data, BranchingFromServertoSensor::Data, ); let s = s.send(GetData {})?; let (_data, s) = s.recv()?; recurs_server(s, i - 1) } } } ///////////////////////// fn main() { let (thread_satellite, thread_sensor, thread_server) = fork_mpst(endpoint_satellite, endpoint_sensor, endpoint_server); thread_satellite.join().unwrap(); thread_sensor.join().unwrap(); thread_server.join().unwrap(); }