use mpstthree::binary::close::close; use mpstthree::binary::struct_trait::end::*; use mpstthree::binary::struct_trait::session::*; use mpstthree::binary_atmp::choose::{choose_left, choose_right}; use mpstthree::binary_atmp::fork::fork; use mpstthree::binary_atmp::offer::{offer_either, OfferTimed}; use mpstthree::binary_atmp::recv::recv; use mpstthree::binary_atmp::send::send; use mpstthree::binary_atmp::struct_trait::recv::RecvTimed; use mpstthree::binary_atmp::struct_trait::send::SendTimed; use rand::{thread_rng, Rng}; use std::collections::HashMap; use std::error::Error; use std::thread::sleep; use std::time::{Duration, Instant}; pub fn head_str() { assert_eq!( SendTimed::::head_str(), "Send".to_string() ); assert_eq!( RecvTimed::::head_str(), "Recv".to_string() ); } pub fn tail_str() { assert_eq!( SendTimed::::tail_str(), "End<>".to_string() ); assert_eq!( RecvTimed::::tail_str(), "End<>".to_string() ); } pub fn self_head_str() { let (send, recv) = SendTimed::::new(); assert_eq!(send.self_head_str(), "Send".to_string()); assert_eq!(recv.self_head_str(), "Recv".to_string()); } pub fn self_tail_str() { let (send, recv) = SendTimed::::new(); assert_eq!(send.self_tail_str(), "End<>".to_string()); assert_eq!(recv.self_tail_str(), "End<>".to_string()); } // Constraints pub fn constraint_start_excluded() { let (send, recv) = SendTimed::::new(); assert_eq!(send.constraint(), "5 < a".to_string()); assert_eq!(recv.constraint(), "5 < a".to_string()); } pub fn constraint_start_included() { let (send, recv) = SendTimed::::new(); assert_eq!(send.constraint(), "5 <= a".to_string()); assert_eq!(recv.constraint(), "5 <= a".to_string()); } pub fn constraint_end_excluded() { let (send, recv) = SendTimed::::new(); assert_eq!(send.constraint(), "a < 5".to_string()); assert_eq!(recv.constraint(), "a < 5".to_string()); } pub fn constraint_end_included() { let (send, recv) = SendTimed::::new(); assert_eq!(send.constraint(), "a <= 5".to_string()); assert_eq!(recv.constraint(), "a <= 5".to_string()); } pub fn constraint_start_excluded_end_excluded() { let (send, recv) = SendTimed::::new(); assert_eq!(send.constraint(), "5 < a < 10".to_string()); assert_eq!(recv.constraint(), "5 < a < 10".to_string()); } pub fn constraint_start_excluded_end_included() { let (send, recv) = SendTimed::::new(); assert_eq!(send.constraint(), "5 < a <= 10".to_string()); assert_eq!(recv.constraint(), "5 < a <= 10".to_string()); } pub fn constraint_start_included_end_excluded() { let (send, recv) = SendTimed::::new(); assert_eq!(send.constraint(), "5 <= a < 10".to_string()); assert_eq!(recv.constraint(), "5 <= a < 10".to_string()); } pub fn constraint_start_included_end_included() { let (send, recv) = SendTimed::::new(); assert_eq!(send.constraint(), "5 <= a <= 10".to_string()); assert_eq!(recv.constraint(), "5 <= a <= 10".to_string()); } // Test a simple calculator server, implemented using timed binary // choice. type NegServer = RecvTimed>; type NegClient = ::Dual; type AddServer = RecvTimed< i32, 'a', 2, true, 4, true, ' ', RecvTimed>, >; type AddClient = ::Dual; type SimpleCalcServer = OfferTimed; type SimpleCalcClient = ::Dual; fn simple_calc_server( s: SimpleCalcServer, all_clocks: &mut HashMap, ) -> Result<(), Box> { all_clocks.insert('a', Instant::now()); sleep(Duration::from_secs(1)); offer_either( all_clocks, s, |all_clocks: &mut HashMap, s: NegServer| { sleep(Duration::from_secs(2)); let (x, s) = recv(all_clocks, s)?; sleep(Duration::from_secs(2)); let s = send(-x, all_clocks, s)?; sleep(Duration::from_secs(2)); close(s) }, |all_clocks: &mut HashMap, s: AddServer| { sleep(Duration::from_secs(2)); let (x, s) = recv(all_clocks, s)?; sleep(Duration::from_secs(2)); let (y, s) = recv(all_clocks, s)?; sleep(Duration::from_secs(2)); let s = send(x.wrapping_add(y), all_clocks, s)?; sleep(Duration::from_secs(2)); close(s) }, ) } pub fn simple_calc_works() { assert!(|| -> Result<(), Box> { let mut rng = thread_rng(); // Test the negation function. { let s: SimpleCalcClient = fork(simple_calc_server); let x: i32 = rng.gen(); let mut all_clocks = HashMap::::new(); all_clocks.insert('a', Instant::now()); sleep(Duration::from_secs(1)); let s = choose_left::<_, AddClient, 'a', 1, true, 2, true, ' '>(&mut all_clocks, s)?; sleep(Duration::from_secs(2)); let s = send(x, &mut all_clocks, s)?; sleep(Duration::from_secs(2)); let (y, s) = recv(&mut all_clocks, s)?; sleep(Duration::from_secs(2)); close(s)?; assert_eq!(-x, y); } // Test the addition function. { let s: SimpleCalcClient = fork(simple_calc_server); let x: i32 = rng.gen(); let y: i32 = rng.gen(); let mut all_clocks = HashMap::::new(); all_clocks.insert('a', Instant::now()); sleep(Duration::from_secs(1)); let s = choose_right::(&mut all_clocks, s)?; sleep(Duration::from_secs(2)); let s = send(x, &mut all_clocks, s)?; sleep(Duration::from_secs(2)); let s = send(y, &mut all_clocks, s)?; sleep(Duration::from_secs(2)); let (z, s) = recv(&mut all_clocks, s)?; sleep(Duration::from_secs(2)); close(s)?; assert_eq!(x.wrapping_add(y), z); } Ok(()) }() .is_ok()); }