use crate::futures::future::{Future, WrappedFuture};
use crate::futures::promise::Promise;
use crate::futures::completable_promise::CompletablePromise;
use crate::futures::async_promise::AsyncPromise;
use crate::common::tsafe::TSafe;
use crate::executors::thread_pinned_executor::ThreadPinnedExecutor;
use std::sync::{Arc, Mutex};
use failure::Fail;
use std::thread;
use std::time::Duration;
#[derive(Debug, Fail)]
enum MyError {
#[fail(display = "my custom error: {}", text)]
ExampleError {
text: String,
}
}
#[derive(Debug, Fail)]
enum MyOtherError {
#[fail(display = "my other error: {}", text)]
ExampleError {
text: String,
}
}
pub fn run() {
future_combinators();
thread::park();
}
fn completable_promise() {
let mut p: CompletablePromise<u32, TSafe<Fail + Send>> = CompletablePromise::new();
let mut fut = p.future();
fut.on_complete(|v| {
println!("Result={}", v.as_ref().ok().unwrap());
});
thread::spawn(move || {
p.success(100);
});
}
fn async_promise() {
let executor = tsafe!(ThreadPinnedExecutor::new().run());
let p: AsyncPromise<u32, TSafe<Fail + Send>> =
AsyncPromise::new(Box::new(|| Ok(50 + 50)), executor);
let mut fut = p.future();
fut.on_complete(|v| {
println!("Result={}", v.as_ref().ok().unwrap());
});
}
fn future_combinators() {
let executor = tsafe!(ThreadPinnedExecutor::new().run());
let mut fut0: WrappedFuture<u32, TSafe<Fail + Send>> =
Future::asyncp(|| Ok(500 + 500), executor.clone());
fut0.map(|v| {
Ok(format!("{}", v))
});
let mut fut1: WrappedFuture<u32, TSafe<Fail + Send>> =
Future::asyncp(|| Ok(500 + 500), executor.clone());
let executor1 = executor.clone();
fut1.flat_map(move |v| {
let vc = *v;
let fut_inner: WrappedFuture<String, TSafe<Fail + Send>> =
Future::asyncp(move || {
let r = format!("{}", vc + 1000);
Ok(r)
}, executor1.clone());
Ok(fut_inner)
});
let mut fut2: WrappedFuture<u32, TSafe<Fail + Send>> =
Future::asyncp(|| Ok(500 + 500), executor.clone());
fut2.map(|_| {
let err = tsafe!(MyError::ExampleError { text: String::from("Oops!") });
Err(err)
}).recover(|_| {
Ok(100)
});
let mut fut3: WrappedFuture<u32, TSafe<Fail + Send>> =
Future::asyncp(|| Ok(500 + 500), executor.clone());
fut3.map(|_| {
let err = tsafe!(MyError::ExampleError { text: String::from("Oops!") });
Err(err)
}).map_err(|_| {
let other_err = tsafe!(MyOtherError::ExampleError { text: String::from("Other Oops!") });
Err(other_err)
}).recover(|_| {
Ok(100)
});
let mut fut4: WrappedFuture<u32, TSafe<Fail + Send>> =
Future::asyncp(|| Ok(500 + 500), executor.clone());
fut4.on_complete(|v| {
match v {
Ok(result) => println!("Result={}", result),
Err(error) => println!("Error={}", error.lock().unwrap())
}
});
let vst = 1000;
let mut fut5: WrappedFuture<u32, TSafe<Fail + Send>> =
Future::asyncp(move || {
if vst > 500 {
Ok(vst + 1000)
} else {
let err: TSafe<Fail + Send> =
tsafe!(MyError::ExampleError { text: String::from("Vst must be > 500!") });
Err(err)
}
}, executor.clone());
fut5.map(|v| {
Ok(format!("{}", *v))
}).recover(|e| {
println!("Recovered to default 100 because error occurs -> {}", e.lock().unwrap());
Ok(String::from("100"))
}).on_complete(|v| {
println!("Result={}", v.as_ref().unwrap())
});
}
pub fn future_await() {
let executor = tsafe!(ThreadPinnedExecutor::new().run());
let mut fut1: WrappedFuture<u32, TSafe<Fail + Send>> =
Future::asyncp(|| {
thread::sleep(Duration::from_secs(1));
Ok(100)
}, executor.clone());
let ready = fut1.ready(Duration::from_secs(3));
match ready {
true => {
match fut1.get_value() {
Ok(value) => {
println!("fut1 completed with Ok({})", value);
},
Err(error) => {
println!("fut1 completed with Err({})", error.lock().unwrap());
}
}
},
false => {
println!("fut1 does not completed with timeout");
}
}
let mut fut2: WrappedFuture<u32, TSafe<Fail + Send>> =
Future::asyncp(|| {
thread::sleep(Duration::from_secs(1));
Ok(100)
}, executor.clone());
let result = fut2.result(Duration::from_secs(3));
match result {
Ok(value) => {
match value {
Ok(value) => {
println!("fut2 completed with Ok({})", value);
},
Err(error) => {
println!("fut2 completed with Err({})", error.lock().unwrap());
}
}
},
Err(_) => {
println!("fut2 does not completed with timeout");
}
}
}