use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use mpstthree::{ choose_mpst_multi_to_all, close_mpst, create_meshedchannels, create_multiple_normal_name, create_multiple_normal_role, create_recv_mpst_session_bundle, create_send_mpst_cancel_bundle, fork_mpst_multi, offer_mpst, }; use rand::{thread_rng, Rng}; use std::error::Error; use std::marker; // See the folder scribble_protocols for the related Scribble protocol // Create new MeshedChannels for two participants create_meshedchannels!(MeshedChannels, 2); // Create Roles create_multiple_normal_role!( Controller, DualController | Logs, DualLogs | ); // Create Names create_multiple_normal_name!(NameController, NameLogs); // Create send create_send_mpst_cancel_bundle!( send_controller_to_logs, Logs, 1 | => NameController, MeshedChannels, 2 ); create_send_mpst_cancel_bundle!( send_logs_to_controller, Controller, 1 | => NameLogs, MeshedChannels, 2 ); // Create recv create_recv_mpst_session_bundle!( recv_controller_from_logs, Logs, 1 | => NameController, MeshedChannels, 2 ); create_recv_mpst_session_bundle!( recv_logs_from_controller, Controller, 1 | => NameLogs, MeshedChannels, 2 ); // Create close function close_mpst!(close_mpst_multi, MeshedChannels, 2); // Create fork function fork_mpst_multi!(fork_mpst, MeshedChannels, 2); // Controller enum Branching0fromLtoC { Success(MeshedChannels>, Logs>, NameController>), Failure(MeshedChannels>, Logs, NameController>), } type Recurs0fromCtoL = Recv, End>; type Choose1fromCtoL = Send, End>; // Logs type Choose0fromLtoC = Send, End>; enum Branching1fromCtoL { Restart(MeshedChannels>, Controller, NameLogs>), Stop(MeshedChannels, Controller, NameLogs>), } type Recurs1fromLtoC = Recv, End>; // Creating the MP sessions // Controller type EndpointController0 = MeshedChannels, Logs, NameController>; type EndpointController1 = MeshedChannels, RoleBroadcast, NameController>; type EndpointControllerInit = MeshedChannels>, Logs>, NameController>; // Logs type EndpointLogs0 = MeshedChannels, RoleBroadcast, NameLogs>; type EndpointLogs1 = MeshedChannels, Controller, NameLogs>; type EndpointLogsInit = MeshedChannels>, Controller, NameLogs>; fn endpoint_controller(s: EndpointControllerInit) -> Result<(), Box> { let start: i32 = thread_rng().gen_range(5..100); let s = send_controller_to_logs(start, s)?; recurs_0_controller(s, start) } fn recurs_0_controller(s: EndpointController0, loops: i32) -> Result<(), Box> { offer_mpst!(s, recv_controller_from_logs, { Branching0fromLtoC::Success(s) => { let (_, s) = recv_controller_from_logs(s)?; recurs_0_controller(s, loops) }, Branching0fromLtoC::Failure(s) => { let (_, s) = recv_controller_from_logs(s)?; recurs_1_controller(s, loops) }, }) } fn recurs_1_controller(s: EndpointController1, loops: i32) -> Result<(), Box> { match loops { i if i <= 0 => { // Stop let s = choose_mpst_multi_to_all!( s, Branching1fromCtoL::Stop, => NameController, MeshedChannels, 2 ); let s = send_controller_to_logs(loops - 1, s)?; close_mpst_multi(s) } _ => { // Restart let s = choose_mpst_multi_to_all!( s, Branching1fromCtoL::Restart, => NameController, MeshedChannels, 2 ); let s = send_controller_to_logs(loops - 1, s)?; recurs_0_controller(s, loops - 1) } } } fn endpoint_logs(s: EndpointLogsInit) -> Result<(), Box> { let (status, s) = recv_logs_from_controller(s)?; recurs_0_logs(s, status) } fn recurs_0_logs(s: EndpointLogs0, loops: i32) -> Result<(), Box> { match loops { i if i % 2 == 0 && i > 0 => { // Success let s = choose_mpst_multi_to_all!( s, Branching0fromLtoC::Success, => NameLogs, MeshedChannels, 2 ); let s = send_logs_to_controller(loops - 1, s)?; recurs_0_logs(s, loops - 1) } _ => { // Failure let s = choose_mpst_multi_to_all!( s, Branching0fromLtoC::Failure, => NameLogs, MeshedChannels, 2 ); let s = send_logs_to_controller(loops - 1, s)?; recurs_1_logs(s) } } } fn recurs_1_logs(s: EndpointLogs1) -> Result<(), Box> { offer_mpst!(s, recv_logs_from_controller, { Branching1fromCtoL::Restart(s) => { let (loops, s) = recv_logs_from_controller(s)?; recurs_0_logs(s, loops - 1) }, Branching1fromCtoL::Stop(s) => { let (_, s) = recv_logs_from_controller(s)?; close_mpst_multi(s) }, }) } ///////////////////////// fn main() { let (thread_controller, thread_logs) = fork_mpst(endpoint_controller, endpoint_logs); thread_controller.join().unwrap(); thread_logs.join().unwrap(); }