#![allow(clippy::type_complexity)]
use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send};
use mpstthree::role::broadcast::RoleBroadcast;
use mpstthree::role::end::RoleEnd;
use mpstthree::{
choose_mpst_multi_to_all, close_mpst, create_meshedchannels, create_multiple_normal_role,
create_recv_mpst_session_bundle, create_send_mpst_cancel_bundle, fork_mpst_multi, offer_mpst,
};
use rand::random;
use std::error::Error;
use std::marker;
create_meshedchannels!(MeshedChannelsFour, 4);
create_multiple_normal_role!(
Api, DualAPI |
Controller, DualController |
Storage, DualStorage |
User, DualUser |
);
create_send_mpst_cancel_bundle!(
send_api_to_controller, Controller, 1 |
send_api_to_storage, Storage, 2 |
send_api_to_user, User, 3 | =>
Api, MeshedChannelsFour, 4
);
create_send_mpst_cancel_bundle!(
send_controller_to_api, Api, 1 |
send_controller_to_storage, Storage, 2 | =>
Controller, MeshedChannelsFour, 4
);
create_send_mpst_cancel_bundle!(
send_storage_to_api, Api, 1 |
send_storage_to_controller, Controller, 2 | =>
Storage, MeshedChannelsFour, 4
);
create_send_mpst_cancel_bundle!(
send_user_to_api, Api, 1 | =>
User, MeshedChannelsFour, 4
);
create_recv_mpst_session_bundle!(
recv_api_from_controller, Controller, 1 |
recv_api_from_storage, Storage, 2 |
recv_api_from_user, User, 3 | =>
Api, MeshedChannelsFour, 4
);
create_recv_mpst_session_bundle!(
recv_controller_from_api, Api, 1 |
recv_controller_from_storage, Storage, 2 | =>
Controller, MeshedChannelsFour, 4
);
create_recv_mpst_session_bundle!(
recv_storage_from_api, Api, 1 |
recv_storage_from_controller, Controller, 2 | =>
Storage, MeshedChannelsFour, 4
);
create_recv_mpst_session_bundle!(
recv_user_from_api, Api, 1 |
recv_user_from_controller, Controller, 2 | =>
User, MeshedChannelsFour, 4
);
close_mpst!(close_mpst_multi, MeshedChannelsFour, 4);
fork_mpst_multi!(fork_mpst, MeshedChannelsFour, 4);
type NameApi = Api<RoleEnd>;
type NameController = Controller<RoleEnd>;
type NameStorage = Storage<RoleEnd>;
type NameUser = User<RoleEnd>;
enum Branching0fromCtoA<N: marker::Send> {
Up(
MeshedChannelsFour<
Recv<N, Send<N, Recurs0fromCtoA<N>>>,
Send<N, Recv<N, End>>,
Send<N, Recv<N, End>>,
Controller<Storage<Storage<User<User<Controller<Controller<RoleEnd>>>>>>>,
NameApi,
>,
),
Down(
MeshedChannelsFour<
Recv<N, Send<N, Recurs0fromCtoA<N>>>,
End,
Send<N, Recv<N, End>>,
Controller<User<User<Controller<Controller<RoleEnd>>>>>,
NameApi,
>,
),
Close(MeshedChannelsFour<Recv<N, End>, End, Send<N, End>, Controller<User<RoleEnd>>, NameApi>),
}
type Recurs0fromCtoA<N> = Recv<Branching0fromCtoA<N>, End>;
type Choose0fromCtoA<N> = Send<Branching0fromCtoA<N>, End>;
type Choose0fromCtoS<N> = Send<Branching0fromCtoS<N>, End>;
type Choose0fromCtoU<N> = Send<Branching0fromCtoU<N>, End>;
enum Branching0fromCtoS<N: marker::Send> {
Up(
MeshedChannelsFour<
Recv<N, Send<N, End>>,
Recurs0fromCtoS<N>,
End,
Api<Api<Controller<RoleEnd>>>,
NameStorage,
>,
),
Down(
MeshedChannelsFour<
End,
Recv<N, Recurs0fromCtoS<N>>,
End,
Controller<Controller<RoleEnd>>,
NameStorage,
>,
),
Close(MeshedChannelsFour<End, Recv<N, End>, End, Controller<RoleEnd>, NameStorage>),
}
type Recurs0fromCtoS<N> = Recv<Branching0fromCtoS<N>, End>;
enum Branching0fromCtoU<N: marker::Send> {
Up(
MeshedChannelsFour<
Recv<N, Send<N, End>>,
Recurs0fromCtoU<N>,
End,
Api<Api<Controller<RoleEnd>>>,
NameUser,
>,
),
Down(
MeshedChannelsFour<
Recv<N, Send<N, End>>,
Recurs0fromCtoU<N>,
End,
Api<Api<Controller<RoleEnd>>>,
NameUser,
>,
),
Close(MeshedChannelsFour<Recv<N, End>, End, End, Api<RoleEnd>, NameUser>),
}
type Recurs0fromCtoU<N> = Recv<Branching0fromCtoU<N>, End>;
type EndpointApi0<N> = MeshedChannelsFour<
Send<N, Recurs0fromCtoA<N>>,
End,
Recv<N, End>,
User<Controller<Controller<RoleEnd>>>,
NameApi,
>;
type EndpointApiInit<N> = MeshedChannelsFour<
Recv<N, Send<N, Recurs0fromCtoA<N>>>,
End,
Recv<N, End>,
Controller<User<Controller<Controller<RoleEnd>>>>,
NameApi,
>;
type EndpointController0<N> = MeshedChannelsFour<
Recv<N, Choose0fromCtoA<N>>,
Choose0fromCtoS<N>,
Choose0fromCtoU<N>,
Api<RoleBroadcast>,
NameController,
>;
type EndpointControllerInit<N> = MeshedChannelsFour<
Send<N, Recv<N, Choose0fromCtoA<N>>>,
Send<N, Recv<N, Choose0fromCtoS<N>>>,
Choose0fromCtoU<N>,
Storage<Api<Storage<Api<RoleBroadcast>>>>,
NameController,
>;
type EndpointStorage0<N> =
MeshedChannelsFour<End, Recurs0fromCtoS<N>, End, Controller<RoleEnd>, NameStorage>;
type EndpointStorageInit<N> = MeshedChannelsFour<
End,
Recv<N, Send<N, Recurs0fromCtoS<N>>>,
End,
Controller<Controller<Controller<RoleEnd>>>,
NameStorage,
>;
type EndpointUserInit<N> =
MeshedChannelsFour<Send<N, End>, Recurs0fromCtoU<N>, End, Api<Controller<RoleEnd>>, NameUser>;
fn endpoint_api(s: EndpointApiInit<i32>) -> Result<(), Box<dyn Error>> {
let (_start, s) = recv_api_from_controller(s)?;
recurs_api(s)
}
fn recurs_api(s: EndpointApi0<i32>) -> Result<(), Box<dyn Error>> {
let (request, s) = recv_api_from_user(s)?;
let s = send_api_to_controller(random::<i32>(), s)?;
offer_mpst!(s, recv_api_from_controller, {
Branching0fromCtoA::Up(s) => {
let (_up, s) = recv_api_from_controller(s)?;
let s = send_api_to_storage(request, s)?;
let (response, s) = recv_api_from_storage(s)?;
let s = send_api_to_user(response, s)?;
recurs_api(s)
},
Branching0fromCtoA::Down(s) => {
let (failure, s) = recv_api_from_controller(s)?;
let s = send_api_to_user(failure, s)?;
recurs_api(s)
},
Branching0fromCtoA::Close(s) => {
let (close, s) = recv_api_from_controller(s)?;
let s = send_api_to_user(close, s)?;
close_mpst_multi(s)
},
})
}
fn endpoint_controller(s: EndpointControllerInit<i32>) -> Result<(), Box<dyn Error>> {
let s = send_controller_to_storage(100, s)?;
let s = send_controller_to_api(100, s)?;
let (_hard_ping, s) = recv_controller_from_storage(s)?;
recurs_controller(s, 100)
}
fn recurs_controller(s: EndpointController0<i32>, loops: i32) -> Result<(), Box<dyn Error>> {
let (_get_mode, s) = recv_controller_from_api(s)?;
match loops {
i if i < 0 => {
let s = choose_mpst_multi_to_all!(
s,
Branching0fromCtoA::Close,
Branching0fromCtoS::Close,
Branching0fromCtoU::Close, =>
Api,
Storage,
User, =>
Controller,
MeshedChannelsFour,
2
);
let s = send_controller_to_api(0, s)?;
let s = send_controller_to_storage(0, s)?;
close_mpst_multi(s)
}
i if i % 2 == 0 => {
let s = choose_mpst_multi_to_all!(
s,
Branching0fromCtoA::Up,
Branching0fromCtoS::Up,
Branching0fromCtoU::Up, =>
Api,
Storage,
User, =>
Controller,
MeshedChannelsFour,
2
);
let s = send_controller_to_api(random::<i32>(), s)?;
recurs_controller(s, loops - 1)
}
_ => {
let s = choose_mpst_multi_to_all!(
s,
Branching0fromCtoA::Down,
Branching0fromCtoS::Down,
Branching0fromCtoU::Down, =>
Api,
Storage,
User, =>
Controller,
MeshedChannelsFour,
2
);
let s = send_controller_to_api(random::<i32>(), s)?;
let s = send_controller_to_storage(random::<i32>(), s)?;
recurs_controller(s, loops - 1)
}
}
}
fn endpoint_storage(s: EndpointStorageInit<i32>) -> Result<(), Box<dyn Error>> {
let (_start, s) = recv_storage_from_controller(s)?;
let s = send_storage_to_controller(random::<i32>(), s)?;
recurs_storage(s)
}
fn recurs_storage(s: EndpointStorage0<i32>) -> Result<(), Box<dyn Error>> {
offer_mpst!(s, recv_storage_from_controller, {
Branching0fromCtoS::Up(s) => {
let (request, s) = recv_storage_from_api(s)?;
let s = send_storage_to_api(request, s)?;
recurs_storage(s)
},
Branching0fromCtoS::Down(s) => {
let (_failure, s) = recv_storage_from_controller(s)?;
recurs_storage(s)
},
Branching0fromCtoS::Close(s) => {
let (_close, s) = recv_storage_from_controller(s)?;
close_mpst_multi(s)
},
})
}
fn endpoint_user(s: EndpointUserInit<i32>) -> Result<(), Box<dyn Error>> {
let s = send_user_to_api(random::<i32>(), s)?;
offer_mpst!(s, recv_user_from_controller, {
Branching0fromCtoU::Up(s) => {
let (_response, s) = recv_user_from_api(s)?;
endpoint_user(s)
},
Branching0fromCtoU::Down(s) => {
let (_failure, s) = recv_user_from_api(s)?;
endpoint_user(s)
},
Branching0fromCtoU::Close(s) => {
let (_close, s) = recv_user_from_api(s)?;
close_mpst_multi(s)
},
})
}
fn main() {
let (thread_api, thread_controller, thread_storage, thread_user) = fork_mpst(
endpoint_api,
endpoint_controller,
endpoint_storage,
endpoint_user,
);
assert!(thread_api.join().is_ok());
assert!(thread_controller.join().is_ok());
assert!(thread_storage.join().is_ok());
assert!(thread_user.join().is_ok());
}