use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use mpstthree::{close_mpst_interleaved, fork_mpst_multi_solo, generate, offer_mpst_interleaved}; use rand::random; use std::error::Error; use std::marker; // See the folder scribble_protocols for the related Scribble protocol // Create new MeshedChannels for two participants generate!("rec_and_cancel", MeshedChannels, Controller, Logs); close_mpst_interleaved!(close_mpst, MeshedChannels, 2); fork_mpst_multi_solo!(fork_mpst_solo, MeshedChannels, 2); // RoleController enum Branching0fromLtoC { Success( MeshedChannels>, RoleLogs>, NameController>, ), Failure(MeshedChannels>, RoleLogs, NameController>), } type Recurs0fromCtoL = Recv, End>; type Choose1fromCtoL = Send, End>; // RoleLogs type Choose0fromLtoC = Send, End>; enum Branching1fromCtoL { Restart(MeshedChannels>, RoleController, NameLogs>), Stop(MeshedChannels, RoleController, NameLogs>), } type Recurs1fromLtoC = Recv, End>; // Creating the MP sessions // RoleController type EndpointController1Stop = MeshedChannels, RoleLogs, NameController>; type EndpointController1Restart = MeshedChannels>, RoleLogs>, NameController>; type EndpointController0 = MeshedChannels, RoleLogs, NameController>; type EndpointController1 = MeshedChannels, RoleBroadcast, NameController>; type EndpointControllerInit = MeshedChannels>, RoleLogs>, NameController>; // RoleLogs type EndpointLogs0Success = MeshedChannels>, RoleController, NameLogs>; type EndpointLogs0Failure = MeshedChannels>, RoleController>, NameLogs>; type EndpointLogs0 = MeshedChannels, RoleBroadcast, NameLogs>; type EndpointLogs1 = MeshedChannels, RoleController, NameLogs>; type EndpointLogsInit = MeshedChannels>, RoleController, NameLogs>; ///////////////////////// fn start( s_controller: EndpointControllerInit, s_logs: EndpointLogsInit, ) -> Result<(), Box> { let s_controller = s_controller.send(random::())?; let (_, s_logs) = s_logs.recv()?; rec_loop_0(s_controller, s_logs, 100) } fn rec_loop_0( s_controller: EndpointController0, s_logs: EndpointLogs0, loops: i32, ) -> Result<(), Box> { match loops { i if i % 2 == 0 && i > 0 => { // Success let s_logs: EndpointLogs0Success = choose_mpst_logs_to_all!(s_logs, Branching0fromLtoC::Success); let (s_controller,) = offer_mpst_interleaved!(s_controller, Branching0fromLtoC::Success); let s_logs = s_logs.send(loops - 1)?; let (_, s_controller) = s_controller.recv()?; rec_loop_0(s_controller, s_logs, loops - 1) } _ => { // Failure let s_logs: EndpointLogs0Failure = choose_mpst_logs_to_all!(s_logs, Branching0fromLtoC::Failure); let (s_controller,) = offer_mpst_interleaved!(s_controller, Branching0fromLtoC::Failure); let s_logs = s_logs.send(loops - 1)?; let (_, s_controller) = s_controller.recv()?; rec_loop_1(s_controller, s_logs, loops - 1) } } } fn rec_loop_1( s_controller: EndpointController1, s_logs: EndpointLogs1, loops: i32, ) -> Result<(), Box> { match loops { i if i <= 0 => { // Stop let s_controller: EndpointController1Stop = choose_mpst_controller_to_all!(s_controller, Branching1fromCtoL::Stop); let (s_logs,) = offer_mpst_interleaved!(s_logs, Branching1fromCtoL::Stop); let s_controller = s_controller.send(loops - 1)?; let (_, s_logs) = s_logs.recv()?; close_mpst(s_controller, s_logs) } _ => { // Restart let s_controller: EndpointController1Restart = choose_mpst_controller_to_all!(s_controller, Branching1fromCtoL::Restart); let (s_logs,) = offer_mpst_interleaved!(s_logs, Branching1fromCtoL::Restart); let s_controller = s_controller.send(loops - 1)?; let (_, s_logs) = s_logs.recv()?; rec_loop_0(s_controller, s_logs, loops - 1) } } } ///////////////////////// fn main() { fork_mpst_solo(start).unwrap(); }