#![allow(clippy::type_complexity)]
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_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;
bundle_struct_fork_close_multi!(close_mpst_multi, fork_mpst, MeshedChannelsThree, 3);
create_multiple_normal_role_short!(A, C, S);
create_send_mpst_http_bundle!(
send_http_a_to_c, RoleC, 1 |
send_http_a_to_s, RoleS, 2 | =>
RoleA, MeshedChannelsThree, 3
);
create_send_mpst_http_bundle!(
send_http_c_to_a, RoleA, 1 |
send_http_c_to_s, RoleS, 2 | =>
RoleC, MeshedChannelsThree, 3
);
create_send_mpst_http_bundle!(
send_http_s_to_a, RoleA, 1 |
send_http_s_to_c, RoleC, 2 | =>
RoleS, MeshedChannelsThree, 3
);
create_recv_http_session_bundle!(
recv_http_a_to_c, RoleC, 1 |
recv_http_a_to_s, RoleS, 2 | =>
RoleA, MeshedChannelsThree, 3
);
create_recv_http_session_bundle!(
recv_http_c_to_a, RoleA, 1 |
recv_http_c_to_s, RoleS, 2 | =>
RoleC, MeshedChannelsThree, 3
);
create_recv_http_session_bundle!(
recv_http_s_to_a, RoleA, 1 |
recv_http_s_to_c, RoleC, 2 | =>
RoleS, MeshedChannelsThree, 3
);
type NameA = RoleA<RoleEnd>;
type NameC = RoleC<RoleEnd>;
type NameS = RoleS<RoleEnd>;
type Choose2fromStoA<N> = Send<Branching2fromStoA<N>, End>;
type Choose2fromStoC<N> = Send<Branching2fromStoC<N>, End>;
type Choice0fromAtoS<N> = <Choose0fromAtoS<N> as Session>::Dual;
type Choice1fromCtoS<N> = <Choose1fromCtoS<N> as Session>::Dual;
type Choose1fromCtoA<N> = Send<Branching1fromCtoA<N>, End>;
type Choose1fromCtoS<N> = Send<Branching1fromCtoS<N>, End>;
type Choice0fromAtoC<N> = <Choose0fromAtoC<N> as Session>::Dual;
type Choice2fromStoC<N> = <Choose2fromStoC<N> as Session>::Dual;
type Choose0fromAtoC<N> = Send<Branching0fromAtoC<N>, End>;
type Choose0fromAtoS<N> = Send<Branching0fromAtoS<N>, End>;
type Choice1fromCtoA<N> = <Choose1fromCtoA<N> as Session>::Dual;
type Choice2fromStoA<N> = <Choose2fromStoA<N> as Session>::Dual;
type EndpointAAuth<N> =
MeshedChannelsThree<Send<N, Choice1fromCtoA<N>>, End, RoleC<RoleC<RoleEnd>>, NameA>;
type EndpointAAuthLoop<N> = MeshedChannelsThree<Choice1fromCtoA<N>, End, RoleC<RoleEnd>, NameA>;
type EndpointADone<N> = MeshedChannelsThree<Send<N, End>, End, RoleC<RoleEnd>, NameA>;
enum Branching1fromCtoA<N: marker::Send> {
Continue(MeshedChannelsThree<End, RSChoice2fromStoA<N>, RoleSSS, NameA>),
Close(MeshedChannelsThree<End, Recv<N, End>, RoleS<RoleEnd>, NameA>),
}
type RSChoice2fromStoA<N> = Recv<N, Send<N, Choice2fromStoA<N>>>;
type RoleSSS = RoleS<RoleS<RoleS<RoleEnd>>>;
type EndpointAContinue<N> = MeshedChannelsThree<End, Choice2fromStoA<N>, RoleS<RoleEnd>, NameA>;
enum Branching2fromStoA<N: marker::Send> {
Picture(MeshedChannelsThree<Choice1fromCtoA<N>, End, RoleC<RoleEnd>, NameA>),
Refusal(MeshedChannelsThree<Choice1fromCtoA<N>, End, RoleC<RoleEnd>, NameA>),
}
enum Branching0fromAtoC<N: marker::Send> {
Auth(MeshedChannelsThree<Recv<N, Choose1fromCtoA<N>>, Choose1fromCtoS<N>, RoleABroad, NameC>),
Done(MeshedChannelsThree<Recv<N, End>, Send<N, End>, RoleAS, NameC>),
}
type RoleAS = RoleA<RoleS<RoleEnd>>;
type RoleABroad = RoleA<RoleBroadcast>;
type EndpointCContinue<N> =
MeshedChannelsThree<End, Send<N, Choice2fromStoC<N>>, RoleS<RoleS<RoleEnd>>, NameC>;
type EndpointCContinueLoop<N> =
MeshedChannelsThree<Choose1fromCtoA<N>, Choose1fromCtoS<N>, RoleBroadcast, NameC>;
type EndpointCDone<N> = MeshedChannelsThree<End, Send<N, End>, RoleS<RoleEnd>, NameC>;
enum Branching2fromStoC<N: marker::Send> {
Picture(
MeshedChannelsThree<Choose1fromCtoA<N>, Recv<N, Choose1fromCtoS<N>>, RoleSBroad, NameC>,
),
Refusal(
MeshedChannelsThree<Choose1fromCtoA<N>, Recv<N, Choose1fromCtoS<N>>, RoleSBroad, NameC>,
),
}
type RoleSBroad = RoleS<RoleBroadcast>;
type EndpointCPicture<N> = MeshedChannelsThree<End, Choice2fromStoC<N>, RoleS<RoleEnd>, NameC>;
enum Branching0fromAtoS<N: marker::Send> {
Auth(MeshedChannelsThree<End, Choice1fromCtoS<N>, RoleC<RoleEnd>, NameS>),
Done(MeshedChannelsThree<End, Recv<N, End>, RoleC<RoleEnd>, NameS>),
}
type EndpointSContinue<N> = MeshedChannelsThree<End, Choice1fromCtoS<N>, RoleC<RoleEnd>, NameS>;
enum Branching1fromCtoS<N: marker::Send> {
Continue(MeshedChannelsThree<SRChoose2fromStoA<N>, RChoose2fromStoC<N>, RoleCAABroad, NameS>),
Close(MeshedChannelsThree<Send<N, End>, Recv<N, End>, RoleCA, NameS>),
}
type SRChoose2fromStoA<N> = Send<N, Recv<N, Choose2fromStoA<N>>>;
type RChoose2fromStoC<N> = Recv<N, Choose2fromStoC<N>>;
type RoleCA = RoleC<RoleA<RoleEnd>>;
type RoleCAABroad = RoleC<RoleA<RoleA<RoleBroadcast>>>;
type EndpointSContinueLoop<N> =
MeshedChannelsThree<Choose2fromStoA<N>, Choose2fromStoC<N>, RoleBroadcast, NameS>;
type EndpointSPicture<N> =
MeshedChannelsThree<End, Send<N, Choice1fromCtoS<N>>, RoleC<RoleC<RoleEnd>>, NameS>;
type EndpointSRefusal<N> =
MeshedChannelsThree<End, Send<N, Choice1fromCtoS<N>>, RoleC<RoleC<RoleEnd>>, NameS>;
type EndpointA<N> = MeshedChannelsThree<
Recv<N, Choose0fromAtoC<N>>,
Choose0fromAtoS<N>,
RoleC<RoleBroadcast>,
NameA,
>;
type EndpointC<N> =
MeshedChannelsThree<Send<N, Choice0fromAtoC<N>>, End, RoleA<RoleA<RoleEnd>>, NameC>;
type EndpointS<N> = MeshedChannelsThree<Choice0fromAtoS<N>, End, RoleA<RoleEnd>, NameS>;
create_fn_choose_mpst_multi_to_all_bundle!(
auth_from_a_to_all, again_from_a_to_all, =>
Auth, Done, =>
EndpointAAuth<i32>, EndpointADone<i32>, =>
Branching0fromAtoC::<i32>, Branching0fromAtoS::<i32>, =>
RoleC, RoleS, =>
RoleA, MeshedChannelsThree, 1
);
create_fn_choose_mpst_multi_to_all_bundle!(
continue_from_c_to_all, close_from_c_to_all, =>
Continue, Close, =>
EndpointCContinue<i32>, EndpointCDone<i32>, =>
Branching1fromCtoA::<i32>, Branching1fromCtoS::<i32>, =>
RoleA, RoleS, =>
RoleC, MeshedChannelsThree, 2
);
create_fn_choose_mpst_multi_to_all_bundle!(
picture_from_s_to_all, refusal_from_s_to_all, =>
Picture, Refusal, =>
EndpointSPicture<i32>, EndpointSRefusal<i32>, =>
Branching2fromStoA::<i32>, Branching2fromStoC::<i32>, =>
RoleA, RoleC, =>
RoleS, MeshedChannelsThree, 3
);
fn endpoint_a(s: EndpointA<i32>) -> Result<(), Box<dyn Error>> {
let (pwd, s, _resp) = recv_http_a_to_c(s, false, Vec::new())?;
let expected = 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<i32>) -> Result<(), Box<dyn Error>> {
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<i32>) -> Result<(), Box<dyn Error>> {
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<i32>) -> Result<(), Box<dyn Error>> {
let (s, _req) = send_http_c_to_a(0, s, false, Request::default())?;
offer_http_mpst!(s, recv_http_c_to_a, {
Branching0fromAtoC::<i32>::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::<i32>::Auth(s) => {
let (_quit, s, _resp) = recv_http_c_to_a(s, false, Vec::new())?;
continue_c(s)
},
})
}
fn continue_c(s: EndpointCContinueLoop<i32>) -> Result<(), Box<dyn Error>> {
let choice = 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<i32>) -> Result<(), Box<dyn Error>> {
offer_http_mpst!(s, recv_http_c_to_s, {
Branching2fromStoC::<i32>::Picture(s) => {
let (_quit, s, _resp) = recv_http_c_to_s(s, false, Vec::new())?;
continue_c(s)
},
Branching2fromStoC::<i32>::Refusal(s) => {
let (_quit, s, _resp) = recv_http_c_to_s(s, false, Vec::new())?;
continue_c(s)
},
})
}
fn endpoint_s(s: EndpointS<i32>) -> Result<(), Box<dyn Error>> {
offer_http_mpst!(s, recv_http_s_to_a, {
Branching0fromAtoS::<i32>::Done(s) => {
let (_quit, s, _resp) = recv_http_s_to_c(s, false, Vec::new())?;
close_mpst_multi(s)
},
Branching0fromAtoS::<i32>::Auth(s) => {
continue_s(s)
},
})
}
fn continue_s(s: EndpointSContinue<i32>) -> Result<(), Box<dyn Error>> {
offer_http_mpst!(s, recv_http_s_to_c, {
Branching1fromCtoS::<i32>::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::<i32>::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<i32>) -> Result<(), Box<dyn Error>> {
let choice = 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);
assert!(thread_a.join().is_ok());
assert!(thread_c.join().is_ok());
assert!(thread_s.join().is_ok());
}