use rand::{thread_rng, Rng}; use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send, session::Session}; use mpstthree::functionmpst::close::close_mpst; use mpstthree::functionmpst::fork::fork_mpst; use mpstthree::meshedchannels::MeshedChannels; use mpstthree::role::broadcast::RoleBroadcast; use std::boxed::Box; use std::error::Error; use std::marker; // Get roles use mpstthree::role::a::RoleA; use mpstthree::role::b::RoleB; use mpstthree::role::c::RoleC; use mpstthree::role::end::RoleEnd; // Get names use mpstthree::name::a::NameA; use mpstthree::name::b::NameB; use mpstthree::name::c::NameC; // Get recv functions use mpstthree::functionmpst::recv::recv_mpst_a_from_b; use mpstthree::functionmpst::recv::recv_mpst_a_from_c; use mpstthree::functionmpst::recv::recv_mpst_b_from_a; use mpstthree::functionmpst::recv::recv_mpst_c_from_a; // Get send functions use mpstthree::functionmpst::send::send_mpst_a_to_b; use mpstthree::functionmpst::send::send_mpst_a_to_c; use mpstthree::functionmpst::send::send_mpst_b_to_a; use mpstthree::functionmpst::send::send_mpst_c_to_a; use mpstthree::choose_mpst_c_to_all; use mpstthree::offer_mpst_a_to_c; use mpstthree::offer_mpst_b_to_c; // See the folder scribble_protocols for the related Scribble protocol // Test our usecase Video Stream // Simple types // Client = C // Authenticator = A // Server = B type AtoCClose = End; type AtoBClose = End; type AtoBVideo = Send>; type AtoCVideo = Recv>>; type InitA = Recv>>; type BtoAClose = ::Dual; type BtoCClose = End; type BtoAVideo = as Session>::Dual; 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 StackAEnd = RoleEnd; type StackAVideo = RoleC>>>>; type StackARecurs = RoleC; type StackAInit = RoleC>>; type StackBEnd = RoleEnd; type StackBVideo = RoleA>>; type StackBRecurs = RoleC; 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, 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_b_to_c!(s, { 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_a_to_c!(s, { 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) } fn client_recurs(s: EndpointCRecurs, mut xs: Vec) -> Result<(), Box> { match xs.pop() { Option::Some(_) => { let s = choose_mpst_c_to_all!(s, Branches0AtoC::Video, Branches0BtoC::Video); let s = send_mpst_c_to_a(1, s); let (_, s) = recv_mpst_c_from_a(s)?; client_recurs(s, xs) } Option::None => { let s = choose_mpst_c_to_all!(s, Branches0AtoC::End, Branches0BtoC::End); close_mpst(s) } } } ///////////////////////////////////////// fn main() { let (thread_a, thread_s, thread_c) = fork_mpst(authenticator, server, client); thread_a.join().unwrap(); thread_s.join().unwrap(); thread_c.join().unwrap(); }