extern crate futures;
extern crate futures_shuttle;
use std::thread;
use std::time::Duration;
use futures::executor::{block_on, LocalPool};
use futures::future::{loop_fn, Loop};
use futures::{FutureExt, IntoFuture};
use futures_shuttle::shuttle;
#[derive(Debug, PartialEq)]
struct Foo(usize);
#[test]
fn simple_future() {
let onesec = Duration::new(1, 0);
let (left, right) = shuttle(Foo(4));
let left = move || {
thread::sleep(onesec);
assert!(left.is_mine());
assert_eq!(left.data(), Foo(4));
*left.data() = Foo(5);
assert_eq!(left.data(), Foo(5));
left.send();
};
thread::spawn(left);
let future = block_on(right.into_future());
assert!(future.is_ok());
let right = future.unwrap();
assert!(right.is_mine());
assert_eq!(right.data(), Foo(5));
}
#[test]
fn ping_pong() {
let (ping, pong) = shuttle(1);
let ping_loop = loop_fn(ping, |s| {
s.into_future().and_then(|s| {
let x = *s.data();
*s.data() = x * 2;
match s.try_send() {
Ok(_) => Ok(Loop::Continue(s)),
Err(_) => Ok(Loop::Break(s)),
}
})
});
thread::spawn(move || {
let mut pool = LocalPool::new();
let mut exec = pool.executor();
pool.run_until(ping_loop, &mut exec).unwrap()
});
let pong_loop = loop_fn(pong, |s| {
s.into_future().and_then(|s| {
let x = *s.data();
if x > 65_536 {
Ok(Loop::Break(s))
} else {
*s.data() = x * 2;
s.send();
Ok(Loop::Continue(s))
}
})
});
let mut pool = LocalPool::new();
let mut exec = pool.executor();
let pong = pool.run_until(pong_loop, &mut exec).unwrap();
assert_eq!(pong.data(), 131_072);
}