// Test for parametrisation on the number of roles use rand::{thread_rng, Rng}; 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_broadcast_role, create_meshedchannels, create_multiple_normal_name, create_multiple_normal_role, create_recv_mpst_session, create_send_mpst_session, fork_mpst_multi, offer_mpst, }; use std::error::Error; use std::marker; // Create new MeshedChannels for three participants create_meshedchannels!(MeshedChannels, 3); // Create new roles // normal create_multiple_normal_role!( RoleA, RoleADual | RoleB, RoleBDual | RoleD, RoleDDual | ); // broadcast create_broadcast_role!(RoleAlltoD, RoleDtoAll); // Create new names create_multiple_normal_name!(NameA, NameB, NameD); // Create new send functions create_send_mpst_session!(send_mpst_d_to_a, RoleA, NameD, MeshedChannels, 3, 1); create_send_mpst_session!(send_mpst_a_to_d, RoleD, NameA, MeshedChannels, 3, 2); create_send_mpst_session!(send_mpst_d_to_b, RoleB, NameD, MeshedChannels, 3, 2); create_send_mpst_session!(send_mpst_b_to_a, RoleA, NameB, MeshedChannels, 3, 1); create_send_mpst_session!(send_mpst_a_to_b, RoleB, NameA, MeshedChannels, 3, 1); // Create new recv functions and related types // normal create_recv_mpst_session!(recv_mpst_d_from_a, RoleA, NameD, MeshedChannels, 3, 1); create_recv_mpst_session!(recv_mpst_a_from_d, RoleD, NameA, MeshedChannels, 3, 2); create_recv_mpst_session!(recv_mpst_b_from_d, RoleD, NameB, MeshedChannels, 3, 2); create_recv_mpst_session!(recv_mpst_b_from_a, RoleA, NameB, MeshedChannels, 3, 1); create_recv_mpst_session!(recv_mpst_a_from_b, RoleB, NameA, MeshedChannels, 3, 1); close_mpst!(close_mpst_multi, MeshedChannels, 3); fork_mpst_multi!(fork_mpst, MeshedChannels, 3); // Test our usecase // Simple types // Client = C // Authenticator = A // Server = B type AtoDClose = End; type AtoBClose = End; type AtoBVideo = Send>; type AtoDVideo = Recv>>; type InitA = Recv>>; type BtoAClose = End; type BtoDClose = End; type BtoAVideo = Recv>; type RecursAtoD = Recv, End>; type RecursBtoD = Recv, End>; enum Branches0AtoD { End(MeshedChannels), Video(MeshedChannels, AtoDVideo, StackAVideo, NameA>), } enum Branches0BtoD { End(MeshedChannels), Video(MeshedChannels, RecursBtoD, StackBVideo, NameB>), } type Choose0fromCtoA = Send, End>; type Choose0fromCtoB = Send, End>; type InitD = Send>>; // Stacks type StackAEnd = RoleEnd; type StackAVideo = RoleD>>>>; type StackARecurs = RoleD; type StackAInit = RoleD>>; type StackBEnd = RoleEnd; type StackBVideo = RoleA>>; type StackBRecurs = RoleD; type StackDRecurs = RoleBroadcast; type StackDFull = RoleA>; // Creating the MP sessions // For C type EndpointDRecurs = MeshedChannels, Choose0fromCtoB, StackDRecurs, NameD>; type EndpointDFull = MeshedChannels, Choose0fromCtoB, StackDFull, NameD>; // For A type EndpointARecurs = MeshedChannels, StackARecurs, NameA>; type EndpointAFull = MeshedChannels, StackAInit, NameA>; // For B type EndpointBRecurs = MeshedChannels, StackBRecurs, NameB>; // Functions related to endpoints fn server(s: EndpointBRecurs) -> Result<(), Box> { offer_mpst!(s, recv_mpst_b_from_d, { Branches0BtoD::End(s) => { close_mpst_multi(s) }, Branches0BtoD::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_d(s)?; let s = send_mpst_a_to_d(id + 1, s); authenticator_recurs(s) } fn authenticator_recurs(s: EndpointARecurs) -> Result<(), Box> { offer_mpst!(s, recv_mpst_a_from_d, { Branches0AtoD::End(s) => { close_mpst_multi(s) }, Branches0AtoD::Video(s) => { let (request, s) = recv_mpst_a_from_d(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_d(video + 1, s); authenticator_recurs(s) }, }) } fn client(s: EndpointDFull) -> Result<(), Box> { let mut rng = thread_rng(); let xs: Vec = (1..100).map(|_| rng.gen()).collect(); let s = send_mpst_d_to_a(0, s); let (_, s) = recv_mpst_d_from_a(s)?; client_recurs(s, xs, 1) } fn client_recurs( s: EndpointDRecurs, mut xs: Vec, index: i32, ) -> Result<(), Box> { match xs.pop() { Option::Some(_) => { let s = choose_mpst_multi_to_all!( s, Branches0AtoD::Video, Branches0BtoD::Video, => NameD, MeshedChannels, 3 ); let s = send_mpst_d_to_a(1, s); let (_, s) = recv_mpst_d_from_a(s)?; client_recurs(s, xs, index + 1) } Option::None => { let s = choose_mpst_multi_to_all!( s, Branches0AtoD::End, Branches0BtoD::End, => NameD, MeshedChannels, 3 ); assert_eq!(index, 100); close_mpst_multi(s) } } } //////////////////////////////////////// pub fn new_run_usecase_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()); }