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 four participants generate!( "rec_and_cancel", MeshedChannels, Api, Controller, Storage, User ); close_mpst_interleaved!(close_mpst, MeshedChannels, 4); fork_mpst_multi_solo!(fork_mpst_solo, MeshedChannels, 4); // RoleApi enum Branching0fromCtoA { Up( MeshedChannels< Recv>>, Send>, Send>, RoleController< RoleStorage< RoleStorage>>>>, >, >, NameApi, >, ), Down( MeshedChannels< Recv>>, End, Send>, RoleController>>>>, NameApi, >, ), Close( MeshedChannels, End, Send, RoleController>, NameApi>, ), } type Recurs0fromCtoA = Recv, End>; // RoleController type Choose0fromCtoA = Send, End>; type Choose0fromCtoS = Send, End>; type Choose0fromCtoU = Send, End>; // RoleStorage enum Branching0fromCtoS { Up( MeshedChannels< Recv>, Recurs0fromCtoS, End, RoleApi>>, NameStorage, >, ), Down( MeshedChannels< End, Recv>, End, RoleController>, NameStorage, >, ), Close(MeshedChannels, End, RoleController, NameStorage>), } type Recurs0fromCtoS = Recv, End>; // RoleUser enum Branching0fromCtoU { Up( MeshedChannels< Recv>, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Down( MeshedChannels< Recv>, Recurs0fromCtoU, End, RoleApi>>, NameUser, >, ), Close(MeshedChannels, End, End, RoleApi, NameUser>), } type Recurs0fromCtoU = Recv, End>; // Creating the MP sessions // RoleApi type EndpointApi0 = MeshedChannels< Send>, End, Recv, RoleUser>>, NameApi, >; type EndpointApiInit = MeshedChannels< Recv>>, End, Recv, RoleController>>>, NameApi, >; // RoleController type EndpointControllerDown = MeshedChannels< Send>>, Send>, Choose0fromCtoU, RoleApi>>, NameController, >; type EndpointControllerUp = MeshedChannels< Send>>, Choose0fromCtoS, Choose0fromCtoU, RoleApi>, NameController, >; type EndpointControllerClose = MeshedChannels, Send, End, RoleApi>, NameController>; type EndpointController0 = MeshedChannels< Recv>, Choose0fromCtoS, Choose0fromCtoU, RoleApi, NameController, >; type EndpointControllerInit = MeshedChannels< Send>>, Send>>, Choose0fromCtoU, RoleStorage>>>, NameController, >; // RoleStorage type EndpointStorage0 = MeshedChannels, End, RoleController, NameStorage>; type EndpointStorageInit = MeshedChannels< End, Recv>>, End, RoleController>>, NameStorage, >; // RoleUser type EndpointUserInit = MeshedChannels< Send, Recurs0fromCtoU, End, RoleApi>, NameUser, >; ///////////////////////// fn start( s_api: EndpointApiInit, s_controller: EndpointControllerInit, s_storage: EndpointStorageInit, s_user: EndpointUserInit, ) -> Result<(), Box> { let s_controller = s_controller.send(random::())?; let (_, s_storage) = s_storage.recv()?; let s_controller = s_controller.send(random::())?; let (_, s_api) = s_api.recv()?; let s_storage = s_storage.send(random::())?; let (_, s_controller) = s_controller.recv()?; rec_loop(s_api, s_controller, s_storage, s_user, 10) } fn rec_loop( s_api: EndpointApi0, s_controller: EndpointController0, s_storage: EndpointStorage0, s_user: EndpointUserInit, loops: i32, ) -> Result<(), Box> { let s_user = s_user.send(random::())?; let (_, s_api) = s_api.recv()?; let s_api = s_api.send(random::())?; let (_, s_controller) = s_controller.recv()?; match loops { i if i < 0 => { let s_controller: EndpointControllerClose = choose_mpst_controller_to_all!( s_controller, Branching0fromCtoA::Close, Branching0fromCtoS::Close, Branching0fromCtoU::Close ); let (s_api, s_storage, s_user) = offer_mpst_interleaved!( s_api, Branching0fromCtoA::Close, s_storage, Branching0fromCtoS::Close, s_user, Branching0fromCtoU::Close ); let s_controller = s_controller.send(random::())?; let (_, s_api) = s_api.recv()?; let s_controller = s_controller.send(random::())?; let (_, s_storage) = s_storage.recv()?; let s_api = s_api.send(random::())?; let (_, s_user) = s_user.recv()?; close_mpst(s_api, s_controller, s_storage, s_user) } i if i % 2 == 0 => { let s_controller: EndpointControllerUp = choose_mpst_controller_to_all!( s_controller, Branching0fromCtoA::Up, Branching0fromCtoS::Up, Branching0fromCtoU::Up ); let (s_api, s_storage, s_user) = offer_mpst_interleaved!( s_api, Branching0fromCtoA::Up, s_storage, Branching0fromCtoS::Up, s_user, Branching0fromCtoU::Up ); let s_controller = s_controller.send(random::())?; let (_, s_api) = s_api.recv()?; let s_api = s_api.send(random::())?; let (_, s_storage) = s_storage.recv()?; let s_storage = s_storage.send(random::())?; let (_, s_api) = s_api.recv()?; let s_api = s_api.send(random::())?; let (_, s_user) = s_user.recv()?; rec_loop(s_api, s_controller, s_storage, s_user, loops - 1) } _ => { let s_controller: EndpointControllerDown = choose_mpst_controller_to_all!( s_controller, Branching0fromCtoA::Down, Branching0fromCtoS::Down, Branching0fromCtoU::Down ); let (s_api, s_storage, s_user) = offer_mpst_interleaved!( s_api, Branching0fromCtoA::Down, s_storage, Branching0fromCtoS::Down, s_user, Branching0fromCtoU::Down ); let s_controller = s_controller.send(random::())?; let (_, s_api) = s_api.recv()?; let s_controller = s_controller.send(random::())?; let (_, s_storage) = s_storage.recv()?; let s_api = s_api.send(random::())?; let (_, s_user) = s_user.recv()?; rec_loop(s_api, s_controller, s_storage, s_user, loops - 1) } } } ///////////////////////// fn main() { fork_mpst_solo(start).unwrap(); }