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::{ bundle_struct_fork_close_multi, create_fn_choose_mpst_multi_to_all_bundle, create_multiple_normal_name_short, create_multiple_normal_role_short, create_recv_http_session_bundle, create_send_mpst_http_bundle, offer_http_mpst, }; use hyper::Request; use rand::{thread_rng, Rng}; use std::error::Error; use std::marker; // See the folder scribble_protocols for the related Scribble protocol // Create the new MeshedChannels for three participants and the close and fork functions bundle_struct_fork_close_multi!(close_mpst_multi, fork_mpst, MeshedChannels, 3); // Create new roles // normal create_multiple_normal_role_short!(A, C, S); // normal create_multiple_normal_name_short!(A, C, S); // Create new send functions // A create_send_mpst_http_bundle!( send_http_a_to_c, RoleC, 1 | send_http_a_to_s, RoleS, 2 | => NameA, MeshedChannels, 3 ); // C create_send_mpst_http_bundle!( send_http_c_to_a, RoleA, 1 | send_http_c_to_s, RoleS, 2 | => NameC, MeshedChannels, 3 ); // S create_send_mpst_http_bundle!( send_http_s_to_a, RoleA, 1 | send_http_s_to_c, RoleC, 2 | => NameS, MeshedChannels, 3 ); // Create new recv functions and related types // A create_recv_http_session_bundle!( recv_http_a_to_c, RoleC, 1 | recv_http_a_to_s, RoleS, 2 | => NameA, MeshedChannels, 3 ); // C create_recv_http_session_bundle!( recv_http_c_to_a, RoleA, 1 | recv_http_c_to_s, RoleS, 2 | => NameC, MeshedChannels, 3 ); // S create_recv_http_session_bundle!( recv_http_s_to_a, RoleA, 1 | recv_http_s_to_c, RoleC, 2 | => NameS, MeshedChannels, 3 ); // Types // S type Choose2fromStoA = Send, End>; type Choose2fromStoC = Send, End>; type Choice0fromAtoS = as Session>::Dual; type Choice1fromCtoS = as Session>::Dual; // C type Choose1fromCtoA = Send, End>; type Choose1fromCtoS = Send, End>; type Choice0fromAtoC = as Session>::Dual; type Choice2fromStoC = as Session>::Dual; // A type Choose0fromAtoC = Send, End>; type Choose0fromAtoS = Send, End>; type Choice1fromCtoA = as Session>::Dual; type Choice2fromStoA = as Session>::Dual; // A type EndpointAAuth = MeshedChannels>, End, RoleC>, NameA>; type EndpointAAuthLoop = MeshedChannels, End, RoleC, NameA>; type EndpointADone = MeshedChannels, End, RoleC, NameA>; enum Branching1fromCtoA { Continue(MeshedChannels, RoleSSS, NameA>), Close(MeshedChannels, RoleS, NameA>), } type RSChoice2fromStoA = Recv>>; type RoleSSS = RoleS>>; type EndpointAContinue = MeshedChannels, RoleS, NameA>; enum Branching2fromStoA { Picture(MeshedChannels, End, RoleC, NameA>), Refusal(MeshedChannels, End, RoleC, NameA>), } // C enum Branching0fromAtoC { Auth(MeshedChannels>, Choose1fromCtoS, RoleABroad, NameC>), Done(MeshedChannels, Send, RoleAS, NameC>), } type RoleAS = RoleA>; type RoleABroad = RoleA; type EndpointCContinue = MeshedChannels>, RoleS>, NameC>; type EndpointCContinueLoop = MeshedChannels, Choose1fromCtoS, RoleBroadcast, NameC>; type EndpointCDone = MeshedChannels, RoleS, NameC>; enum Branching2fromStoC { Picture(MeshedChannels, Recv>, RoleSBroad, NameC>), Refusal(MeshedChannels, Recv>, RoleSBroad, NameC>), } type RoleSBroad = RoleS; type EndpointCPicture = MeshedChannels, RoleS, NameC>; // S enum Branching0fromAtoS { Auth(MeshedChannels, RoleC, NameS>), Done(MeshedChannels, RoleC, NameS>), } type EndpointSContinue = MeshedChannels, RoleC, NameS>; enum Branching1fromCtoS { Continue(MeshedChannels, RChoose2fromStoC, RoleCAABroad, NameS>), Close(MeshedChannels, Recv, RoleCA, NameS>), } type SRChoose2fromStoA = Send>>; type RChoose2fromStoC = Recv>; type RoleCA = RoleC>; type RoleCAABroad = RoleC>>; type EndpointSContinueLoop = MeshedChannels, Choose2fromStoC, RoleBroadcast, NameS>; type EndpointSPicture = MeshedChannels>, RoleC>, NameS>; type EndpointSRefusal = MeshedChannels>, RoleC>, NameS>; // Creating the MP sessions // A type EndpointA = MeshedChannels>, Choose0fromAtoS, RoleC, NameA>; // C type EndpointC = MeshedChannels>, End, RoleA>, NameC>; // S type EndpointS = MeshedChannels, End, RoleA, NameS>; create_fn_choose_mpst_multi_to_all_bundle!( auth_from_a_to_all, again_from_a_to_all, => Auth, Done, => EndpointAAuth, EndpointADone, => Branching0fromAtoC::, Branching0fromAtoS::, => NameC, NameS, => NameA, MeshedChannels, 1 ); create_fn_choose_mpst_multi_to_all_bundle!( continue_from_c_to_all, close_from_c_to_all, => Continue, Close, => EndpointCContinue, EndpointCDone, => Branching1fromCtoA::, Branching1fromCtoS::, => NameA, NameS, => NameC, MeshedChannels, 2 ); create_fn_choose_mpst_multi_to_all_bundle!( picture_from_s_to_all, refusal_from_s_to_all, => Picture, Refusal, => EndpointSPicture, EndpointSRefusal, => Branching2fromStoA::, Branching2fromStoC::, => NameA, NameC, => NameS, MeshedChannels, 3 ); // Functions fn endpoint_a(s: EndpointA) -> Result<(), Box> { let (pwd, s, _resp) = recv_http_a_to_c(s, false, Vec::new())?; let expected: i32 = thread_rng().gen_range(1..=3); if pwd == expected { let s = auth_from_a_to_all(s); let (s, _req) = send_http_a_to_c(0, s, false, Request::default())?; auth_a(s) } else { let s = again_from_a_to_all(s); let (s, _req) = send_http_a_to_c(1, s, false, Request::default())?; close_mpst_multi(s) } } fn auth_a(s: EndpointAAuthLoop) -> Result<(), Box> { offer_http_mpst!(s, recv_http_a_to_c, { Branching1fromCtoA::Continue(s) => { let (_, s, _resp) = recv_http_a_to_s(s, false, Vec::new())?; let (s, _req) = send_http_a_to_s(0, s, false, Request::default())?; continue_a(s) }, Branching1fromCtoA::Close(s) => { let (_, s, _resp) = recv_http_a_to_s(s, false, Vec::new())?; close_mpst_multi(s) }, }) } fn continue_a(s: EndpointAContinue) -> Result<(), Box> { offer_http_mpst!(s, recv_http_a_to_s, { Branching2fromStoA::Picture(s) => { auth_a(s) }, Branching2fromStoA::Refusal(s) => { auth_a(s) }, }) } fn endpoint_c(s: EndpointC) -> Result<(), Box> { let (s, _req) = send_http_c_to_a(0, s, false, Request::default())?; offer_http_mpst!(s, recv_http_c_to_a, { Branching0fromAtoC::::Done(s) => { let (_quit, s, _resp) = recv_http_c_to_a(s, false, Vec::new())?; let (s, _req) = send_http_c_to_s(0, s, false, Request::default())?; close_mpst_multi(s) }, Branching0fromAtoC::::Auth(s) => { let (_quit, s, _resp) = recv_http_c_to_a(s, false, Vec::new())?; continue_c(s) }, }) } fn continue_c(s: EndpointCContinueLoop) -> Result<(), Box> { let choice: i32 = thread_rng().gen_range(1..=6); if choice == 1 { let s = close_from_c_to_all(s); let (s, _req) = send_http_c_to_s(0, s, false, Request::default())?; close_mpst_multi(s) } else { let s = continue_from_c_to_all(s); let (s, _req) = send_http_c_to_s(0, s, false, Request::default())?; picture_c(s) } } fn picture_c(s: EndpointCPicture) -> Result<(), Box> { offer_http_mpst!(s, recv_http_c_to_s, { Branching2fromStoC::::Picture(s) => { let (_quit, s, _resp) = recv_http_c_to_s(s, false, Vec::new())?; continue_c(s) }, Branching2fromStoC::::Refusal(s) => { let (_quit, s, _resp) = recv_http_c_to_s(s, false, Vec::new())?; continue_c(s) }, }) } fn endpoint_s(s: EndpointS) -> Result<(), Box> { offer_http_mpst!(s, recv_http_s_to_a, { Branching0fromAtoS::::Done(s) => { let (_quit, s, _resp) = recv_http_s_to_c(s, false, Vec::new())?; close_mpst_multi(s) }, Branching0fromAtoS::::Auth(s) => { continue_s(s) }, }) } fn continue_s(s: EndpointSContinue) -> Result<(), Box> { offer_http_mpst!(s, recv_http_s_to_c, { Branching1fromCtoS::::Continue(s) => { let (_quit, s, _resp) = recv_http_s_to_c(s, false, Vec::new())?; let (s, _req) = send_http_s_to_a(0, s, false, Request::default())?; let (_quit, s, _resp) = recv_http_s_to_a(s, false, Vec::new())?; picture_s(s) }, Branching1fromCtoS::::Close(s) => { let (_quit, s, _resp) = recv_http_s_to_c(s, false, Vec::new())?; let (s, _req) = send_http_s_to_a(0, s, false, Request::default())?; close_mpst_multi(s) }, }) } fn picture_s(s: EndpointSContinueLoop) -> Result<(), Box> { let choice: i32 = thread_rng().gen_range(1..=6); if choice == 1 { let s = refusal_from_s_to_all(s); let (s, _req) = send_http_s_to_c(0, s, false, Request::default())?; continue_s(s) } else { let s = picture_from_s_to_all(s); let (s, _req) = send_http_s_to_c(0, s, false, Request::default())?; continue_s(s) } } ///////////////////////// fn main() { let (thread_a, thread_c, thread_s) = fork_mpst(endpoint_a, endpoint_c, endpoint_s); thread_a.join().unwrap(); thread_c.join().unwrap(); thread_s.join().unwrap(); }