// Test for parametrisation on the number of roles use rand::{thread_rng, Rng}; use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send, session::Session}; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use mpstthree::{choose_mpst_create_multi_to_all, generate}; use std::error::Error; use std::marker; // Create new roles generate!("basic", MeshedChannels, A, B, D); // Test our usecase // Simple types // Client = D // Authenticator = A // Server = B type AtoDClose = End; type AtoBClose = End; type AtoBVideo = Send>; type AtoDVideo = Recv>>; type InitA = Recv>>; type BtoAClose = ::Dual; type BtoDClose = End; type BtoAVideo = as Session>::Dual; type RecursAtoD = as Session>::Dual; type RecursBtoD = as Session>::Dual; 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 D type EndpointDVideo = MeshedChannels< as Session>::Dual, as Session>::Dual, RoleA>, NameD, >; 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>; choose_mpst_create_multi_to_all!(choose_mpst_client_to_all, NameD, MeshedChannels, 3); // Functions related to endpoints fn server(s: EndpointBRecurs) -> Result<(), Box> { offer_mpst!(s, { Branches0BtoD::End(s) => { s.close() }, Branches0BtoD::Video(s) => { let (request, s) = s.recv(); let s = s.send(request + 1); server(s) }, }) } fn authenticator(s: EndpointAFull) -> Result<(), Box> { let (id, s) = s.recv(); let s = s.send(id + 1); authenticator_recurs(s) } fn authenticator_recurs(s: EndpointARecurs) -> Result<(), Box> { offer_mpst!(s, { Branches0AtoD::End(s) => { s.close() }, Branches0AtoD::Video(s) => { let (request, s) = s.recv(); let (video, s) = s.send(request + 1).recv(); let s = s.send(video + 1); 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) = s.send(0).recv(); client_recurs(s, xs, 1) } fn client_recurs( s: EndpointDRecurs, mut xs: Vec, index: i32, ) -> Result<(), Box> { match xs.pop() { Option::Some(_) => { let s: EndpointDVideo = choose_mpst_client_to_all!(s, Branches0AtoD::Video, Branches0BtoD::Video); let (_, s) = s.send(1).recv(); client_recurs(s, xs, index + 1) } Option::None => { let s = choose_mpst_client_to_all!(s, Branches0AtoD::End, Branches0BtoD::End); assert_eq!(index, 100); s.close() } } } //////////////////////////////////////// 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()); }