#![allow( clippy::type_complexity, clippy::too_many_arguments, clippy::large_enum_variant )] use mpstthree::binary::struct_trait::session::Session; use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send}; use mpstthree::generate; use mpstthree::role::broadcast::RoleBroadcast; use mpstthree::role::end::RoleEnd; use rand::{thread_rng, Rng}; use std::error::Error; // Create the new MeshedChannels for three participants and the close and fork functions generate!("rec_and_cancel", MeshedChannels, Car, Key); // Labels struct Wake {} struct Present {} struct Challenge {} struct Response {} struct Absent {} struct Stop {} // Types // Car type Choice0FromKeyToCar = Recv; type Loop0FromKeyToCar = Send; type CarToKeyPresent0 = Recv; type Choice1FromKeyToCar = Recv; type CarToKeyPresent1 = Send; type Choice2FromKeyToCar = Recv; type CarToKeyPresent2 = Recv; type CarToKeyAbsent = Recv; type CarToKeyStop = Recv; enum Branching0FromKeyToCar { Present(MeshedChannels>, NameCar>), Absent(MeshedChannels>>, NameCar>), Stop(MeshedChannels, NameCar>), } enum Branching1FromKeyToCar { Present(MeshedChannels>, NameCar>), } enum Branching2FromKeyToCar { Present(MeshedChannels>>, NameCar>), } // Key type ChooseFromKeyToCar = ::Dual; type KeyToCarPresent1 = ::Dual; type KeyToCarPresent2 = ::Dual; type KeyToCarPresent3 = ::Dual; type KeyToCarAbsent = ::Dual; type KeyToCarStop = ::Dual; // Endpoints // Car type Endpoint0Car = MeshedChannels, NameCar>; // Key type Endpoint0Key = MeshedChannels; type Endpoint1KeyData = MeshedChannels, NameKey>; type Endpoint2KeyData = MeshedChannels, NameKey>; type Endpoint3KeyData = MeshedChannels>, NameKey>; type Endpoint1KeyAbsent = MeshedChannels>, NameKey>; type Endpoint1KeyStop = MeshedChannels, NameKey>; // Functions ///////////////////////// // Car fn endpoint_car(s: Endpoint0Car) -> Result<(), Box> { recurs_car(s) } fn recurs_car(s: Endpoint0Car) -> Result<(), Box> { offer_mpst!(s, { Branching0FromKeyToCar::Stop(s) => { let (_stop, s) = s.recv()?; s.close() }, Branching0FromKeyToCar::Absent(s) => { let (_absent, s) = s.recv()?; let s = s.send(Wake {}, )?; recurs_car(s, ) }, Branching0FromKeyToCar::Present(s) => { let (_present, s) = s.recv()?; offer_mpst!(s, { Branching1FromKeyToCar::Present(s) => { let s = s.send(Challenge {}, )?; offer_mpst!(s, { Branching2FromKeyToCar::Present(s) => { let (_response, s) = s.recv()?; let s = s.send(Wake {}, )?; recurs_car(s, ) }, }) }, }) }, }) } ///////////////////////// // Key fn endpoint_key(s: Endpoint0Key) -> Result<(), Box> { recurs_key(s, LOOPS) } fn recurs_key(s: Endpoint0Key, loops: i64) -> Result<(), Box> { match loops { 0 => { let s: Endpoint1KeyStop = choose_mpst_key_to_all!(s, Branching0FromKeyToCar::Stop,); let s = s.send(Stop {})?; s.close() } i => { if thread_rng().gen_range(0..=5) == 1 { let s: Endpoint1KeyAbsent = choose_mpst_key_to_all!(s, Branching0FromKeyToCar::Absent); let s = s.send(Absent {})?; let (_wake, s) = s.recv()?; recurs_key(s, i - 1) } else { let s: Endpoint1KeyData = choose_mpst_key_to_all!(s, Branching0FromKeyToCar::Present); let s = s.send(Present {})?; let s: Endpoint2KeyData = choose_mpst_key_to_all!(s, Branching1FromKeyToCar::Present); let (_challenge, s) = s.recv()?; let s: Endpoint3KeyData = choose_mpst_key_to_all!(s, Branching2FromKeyToCar::Present); let s = s.send(Response {})?; let (_wake, s) = s.recv()?; recurs_key(s, i - 1) } } } } ///////////////////////// fn main() { let (thread_car, thread_key) = fork_mpst(endpoint_car, endpoint_key); thread_car.join().unwrap(); thread_key.join().unwrap(); println!("Done"); } static LOOPS: i64 = 100;