use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::meshedchannels::MeshedChannels; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use std::marker; use mpstthree::role::a::RoleA; use mpstthree::role::b::RoleB; use mpstthree::role::c::RoleC; use mpstthree::name::a::NameA; use mpstthree::name::b::NameB; use mpstthree::name::c::NameC; ///////////////////////////////////////// use rand::{thread_rng, Rng}; use std::error::Error; use mpstthree::functionmpst::close::close_mpst; use mpstthree::functionmpst::fork::fork_mpst; // Get recv functions use mpstthree::functionmpst::recv::recv_mpst_a_from_b; use mpstthree::functionmpst::recv::recv_mpst_a_from_c; // Get send functions use mpstthree::functionmpst::send::send_mpst_b_to_a; use mpstthree::functionmpst::send::send_mpst_c_to_a; use mpstthree::functionmpst::send::send_mpst_c_to_b; use mpstthree::choose_mpst_c_to_all; use mpstthree::offer_mpst_a_to_c; use mpstthree::offer_mpst_b_to_c; ///////////////////////////////////////// START type ADDAtoB = Recv; type OrderingA11 = RoleC; type OrderingA12Full = RoleB; type EndpointA13 = MeshedChannels, Recv, End>, OrderingA12Full, NameA>; type BYEAtoB = Recv<(), End>; type OrderingA14Full = RoleB; type EndpointA15 = MeshedChannels; enum Branches0AtoC { Add(EndpointA13), Bye(EndpointA15), } type Choose0forAtoC = Send, End>; type TestAtoC = Recv, End>>; type OrderingA16 = RoleC; type OrderingA17Full = RoleC; type EndpointA18 = MeshedChannels, OrderingA17Full, NameA>; type ADDBtoA = Send; type ADDBtoC = Recv, End>>; type OrderingB13 = RoleC; type OrderingB14Full = RoleC>; type EndpointB15 = MeshedChannels, ADDBtoC, OrderingB14Full, NameB>; type BYEBtoA = Send<(), End>; type BYEBtoC = Recv<(), End>; type OrderingB16Full = RoleC>; type EndpointB17 = MeshedChannels; enum Branches0BtoC { Add(EndpointB15), Bye(EndpointB17), } type Choose0forBtoC = Send, End>; type OrderingB18 = RoleC; type OrderingB19Full = OrderingB18; type EndpointB20 = MeshedChannels, End>, OrderingB19Full, NameB>; type TestCtoA = Send>; type OrderingC2Full = RoleA; type EndpointC3 = MeshedChannels, Choose0forBtoC, OrderingC2Full, NameC>; ///////////////////////////////////////// END ///////////////////////////////////////// For verification ///////////////////////////////////////// with functions type EndpointA19 = MeshedChannels, End>, OrderingA16, NameA>; type EndpointC2 = MeshedChannels, Choose0forBtoC, RoleBroadcast, NameC>; ///////////////////////////////////////// END // Functions related to endpoints fn server(s: EndpointB20) -> Result<(), Box> { offer_mpst_b_to_c!(s, { Branches0BtoC::Bye(s) => { let (_, s) = recv_mpst_b_from_c(s)?; let s = send_mpst_b_to_a((), s); close_mpst(s) }, Branches0BtoC::Add(s) => { let (id, s) = recv_mpst_b_from_c(s)?; let s = send_mpst_b_to_a(id + 1, s); server(s) }, }) } fn authenticator(s: EndpointA18) -> Result<(), Box> { let (_, s) = recv_mpst_a_from_c(s)?; authenticator_recurs(s) } fn authenticator_recurs(s: EndpointA19) -> Result<(), Box> { offer_mpst_a_to_c!(s, { Branches0AtoC::Bye(s) => { let (_, s) = recv_mpst_a_from_b(s)?; close_mpst(s) }, Branches0AtoC::Add(s) => { let (_, s) = recv_mpst_a_from_b(s)?; authenticator_recurs(s) }, }) } fn client(s: EndpointC3) -> Result<(), Box> { let s = send_mpst_c_to_a(0, s); client_recurs(s) } fn client_recurs(s: EndpointC2) -> Result<(), Box> { let mut rng = thread_rng(); let x: u32 = rng.gen_range(0..2); if x == 1 { let s = choose_mpst_c_to_all!(s, Branches0AtoC::Add, Branches0BtoC::Add); let s = send_mpst_c_to_b(1, s); client_recurs(s) } else { let s = choose_mpst_c_to_all!(s, Branches0AtoC::Bye, Branches0BtoC::Bye); let s = send_mpst_c_to_b((), s); close_mpst(s) } } ///////////////////////////////////////// pub fn top_down_approach() { for _ in 0..200 { 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()); } }