use super::completable_promise::CompletablePromise;
use super::promise::Promise;
use super::async_promise::AsyncPromise;
use crate::common::tsafe::TSafe;
use crate::executors::executor::Executor;
use std::any::Any;
use std::sync::{Arc, Mutex};
pub struct WrappedFuture<V: Send + Clone + 'static, E: Send + Clone + 'static> {
pub inner: TSafe<Future<V, E>>
}
impl <V: Send + Clone, E: Send + Clone> WrappedFuture<V, E> {
pub fn map<S, F>(&mut self, mut f: F) -> WrappedFuture<S, E>
where S: Send + Clone + 'static,
F: FnMut(&V) -> Result<S, E> + Send + 'static
{
self.inner.lock().unwrap().map(Box::new(f))
}
pub fn recover<F>(&mut self, mut f: F) -> WrappedFuture<V, E>
where F: FnMut(&E) -> Result<V, E> + Send + 'static
{
self.inner.lock().unwrap().recover(Box::new(f))
}
pub fn flat_map<S, F>(&mut self, mut f: F) -> WrappedFuture<S, E>
where S: Send + Clone + 'static,
F: FnMut(&V) -> Result<WrappedFuture<S, E>, E> + Send + 'static
{
self.inner.lock().unwrap().flat_map(Box::new(f))
}
pub fn on_complete<F>(&mut self, mut f: F)
where F:FnMut(&Result<V, E>) -> () + Send + 'static
{
self.inner.lock().unwrap().on_complete(Box::new(f));
}
}
pub struct Future<V: Send + 'static, E: Send + Clone + 'static> {
value: Option<Result<V, E>>,
next: Option<Box<FnMut(&Result<V, E>) -> () + Send>>
}
impl <V: Send + Clone, E: Send + Clone> Future<V , E> {
pub fn asyncp<F>(f: F, executor: TSafe<Executor>) -> WrappedFuture<V, E>
where F: FnMut() -> Result<V, E> + Send + 'static
{
let mut p: AsyncPromise<V, E> =
AsyncPromise::new(Box::new(f), executor);
p.future()
}
pub fn new() -> Future<V, E> {
Future {
value: None,
next: None,
}
}
pub fn is_completed(&self) -> bool {
self.value.is_some()
}
pub fn complete(&mut self, result: Result<V, E>) {
self.value = Some(result);
if self.next.is_some() {
if let Some(ref mut v) = self.value {
if let Some(ref mut f) = self.next {
f(v);
}
}
}
}
pub fn map<S>(&mut self, mut f: Box<FnMut(&V) -> Result<S, E> + Send>) -> WrappedFuture<S, E>
where S: Send + Clone + 'static
{
let mut p: CompletablePromise<S, E> = CompletablePromise::new();
let fut = p.future();
self.next = Some(Box::new( move |v: &Result<V, E>| {
if v.is_ok() {
let x = v.as_ref().ok().unwrap();
let result = f(x);
p.complete(result);
} else {
let err = v.as_ref().err().unwrap().clone();
let result: Result<S, E> = Err(err);
p.complete(result);
}
}));
if self.value.is_some() {
if let Some(ref mut v) = self.value {
if let Some(ref mut f) = self.next {
f(v)
}
}
}
fut
}
pub fn recover(&mut self, mut f: Box<FnMut(&E) -> Result<V, E> + Send>) -> WrappedFuture<V, E> {
let mut p: CompletablePromise<V, E> = CompletablePromise::new();
let fut = p.future();
self.next = Some(Box::new( move |v: &Result<V, E>| {
if v.is_err() {
let x = v.as_ref().err().unwrap();
let result = f(x);
p.complete(result);
} else {
let ok = v.as_ref().ok().unwrap().clone();
let result: Result<V, E> = Ok(ok);
p.complete(result);
}
}));
if self.value.is_some() {
if let Some(ref mut v) = self.value {
if let Some(ref mut f) = self.next {
f(v)
}
}
}
fut
}
pub fn flat_map<S>(&mut self, mut f: Box<FnMut(&V) -> Result<WrappedFuture<S, E>, E> + Send>) -> WrappedFuture<S, E>
where S: Send + Clone + 'static
{
let mut p: TSafe<CompletablePromise<S, E>> = tsafe!(CompletablePromise::new());
let fut = p.lock().unwrap().future();
self.next = Some(Box::new( move |v: &Result<V, E>| {
if v.is_ok() {
let x = v.as_ref().ok().unwrap();
let result = f(x);
if result.is_ok() {
let mut next_fut = result.ok().unwrap();
let p_clone = p.clone();
next_fut.on_complete(move |v| {
let r: Result<S, E> = if v.is_ok() {
Ok(v.as_ref().ok().unwrap().clone())
} else {
Err(v.as_ref().err().unwrap().clone())
};
p_clone.lock().unwrap().complete(r);
});
} else {
let err = result.as_ref().err().unwrap().clone();
let result: Result<S, E> = Err(err);
p.lock().unwrap().complete(result);
}
} else {
let err = v.as_ref().err().unwrap().clone();
let result: Result<S, E> = Err(err);
p.lock().unwrap().complete(result);
}
}));
if self.value.is_some() {
if let Some(ref mut v) = self.value {
if let Some(ref mut f) = self.next {
f(v)
}
}
}
fut
}
pub fn on_complete(&mut self, mut f: Box<FnMut(&Result<V, E>) -> () + Send>) {
self.next = Some(Box::new( move |v: &Result<V, E>| { f(v) }));
if self.value.is_some() {
if let Some(ref mut v) = self.value {
if let Some(ref mut f) = self.next {
f(v)
}
}
}
}
}