// Test for Macro, exact same as usecase-recursive use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::functionmpst::close::close_mpst; use mpstthree::functionmpst::fork::fork_mpst; use mpstthree::meshedchannels::MeshedChannels; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use std::error::Error; use std::marker; use rand::{thread_rng, Rng}; use mpstthree::{ choose_mpst_to_all, create_multiple_normal_name, create_multiple_normal_role, create_recv_mpst_session_1, create_recv_mpst_session_2, create_send_mpst_session_1, create_send_mpst_session_2, offer_mpst, }; // Create new roles create_multiple_normal_role!( RoleA, RoleADual | RoleB, RoleBDual | RoleC, RoleCDual | ); // Create new names create_multiple_normal_name!(NameA, NameB, NameC); // Create new send functions create_send_mpst_session_1!(send_mpst_c_to_a, RoleA, NameC); create_send_mpst_session_2!(send_mpst_a_to_c, RoleC, NameA); create_send_mpst_session_2!(send_mpst_c_to_b, RoleB, NameC); create_send_mpst_session_1!(send_mpst_b_to_a, RoleA, NameB); create_send_mpst_session_1!(send_mpst_a_to_b, RoleB, NameA); // Create new recv functions and related types create_recv_mpst_session_1!(recv_mpst_c_from_a, RoleA, NameC); create_recv_mpst_session_2!(recv_mpst_a_from_c, RoleC, NameA); create_recv_mpst_session_2!(recv_mpst_b_from_c, RoleC, NameB); create_recv_mpst_session_1!(recv_mpst_b_from_a, RoleA, NameB); create_recv_mpst_session_1!(recv_mpst_a_from_b, RoleB, NameA); // Types type AtoBVideo = Send>; type AtoCVideo = Recv>>; type InitA = Recv>>; type BtoAVideo = Recv>; type RecursAtoC = Recv, End>; type RecursBtoC = Recv, End>; enum Branches0AtoC { End(MeshedChannels), Video(MeshedChannels, AtoCVideo, StackAVideo, NameA>), } enum Branches0BtoC { End(MeshedChannels), Video(MeshedChannels, RecursBtoC, StackBVideo, NameB>), } type Choose0fromCtoA = Send, End>; type Choose0fromCtoB = Send, End>; type InitC = Send>>; // Stacks type StackAVideo = RoleC>>>>; type StackAInit = RoleC>>; type StackBVideo = RoleA>>; type StackCRecurs = RoleBroadcast; type StackCFull = RoleA>; // Creating the MP sessions // For C type EndpointCRecurs = MeshedChannels, Choose0fromCtoB, StackCRecurs, NameC>; type EndpointCFull = MeshedChannels, Choose0fromCtoB, StackCFull, NameC>; // For A type EndpointARecurs = MeshedChannels, RoleC, NameA>; type EndpointAFull = MeshedChannels, StackAInit, NameA>; // For B type EndpointBFull = MeshedChannels, RoleC, NameB>; // Functions related to endpoints fn server(s: EndpointBFull) -> Result<(), Box> { offer_mpst!(s, recv_mpst_b_from_c, { Branches0BtoC::End(s) => { close_mpst(s) }, Branches0BtoC::Video(s) => { let (request, s) = recv_mpst_b_from_a(s)?; let s = send_mpst_b_to_a(request + 1, s); server(s) }, }) } fn authenticator(s: EndpointAFull) -> Result<(), Box> { let (id, s) = recv_mpst_a_from_c(s)?; let s = send_mpst_a_to_c(id + 1, s); authenticator_recurs(s) } fn authenticator_recurs(s: EndpointARecurs) -> Result<(), Box> { offer_mpst!(s, recv_mpst_a_from_c, { Branches0AtoC::End(s) => { close_mpst(s) }, Branches0AtoC::Video(s) => { let (request, s) = recv_mpst_a_from_c(s)?; let s = send_mpst_a_to_b(request + 1, s); let (video, s) = recv_mpst_a_from_b(s)?; let s = send_mpst_a_to_c(video + 1, s); authenticator_recurs(s) }, }) } fn client(s: EndpointCFull) -> Result<(), Box> { let mut rng = thread_rng(); let xs: Vec = (1..100).map(|_| rng.gen()).collect(); let s = send_mpst_c_to_a(0, s); let (_, s) = recv_mpst_c_from_a(s)?; client_recurs(s, xs, 1) } fn client_recurs( s: EndpointCRecurs, mut xs: Vec, index: i32, ) -> Result<(), Box> { match xs.pop() { Option::Some(_) => { let s = choose_mpst_to_all!( s, Branches0AtoC::Video, Branches0BtoC::Video, => NameC ); let s = send_mpst_c_to_a(1, s); let (_, s) = recv_mpst_c_from_a(s)?; client_recurs(s, xs, index + 1) } Option::None => { let s = choose_mpst_to_all!( s, Branches0AtoC::End, Branches0BtoC::End, => NameC ); assert_eq!(index, 100); close_mpst(s) } } } ///////////////////////////////////////// pub fn run_macro_recursive() { let (thread_a, thread_b, thread_c) = fork_mpst(authenticator, server, client); assert!(thread_a.join().is_ok()); assert!(thread_b.join().is_ok()); assert!(thread_c.join().is_ok()); }