Skip to content

Instantly share code, notes, and snippets.

@Kroisse
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kroisse/798addcfe0eefeeefe83 to your computer and use it in GitHub Desktop.
Save Kroisse/798addcfe0eefeeefe83 to your computer and use it in GitHub Desktop.
Madness
#![feature(unboxed_closures)]
use std::sync::{Arc, Mutex};
use std::mem;
use PromiseState::{Ready, Fulfilled, Deferred, Done};
enum PromiseState<T, F: FnOnce(T) + Send> {
Ready,
Fulfilled(T),
Deferred(F),
Done
}
struct Resolver<T, F: FnOnce(T) + Send> {
context: Arc<Mutex<PromiseState<T, F>>>
}
struct Promise<T, F: FnOnce(T) + Send> {
context: Arc<Mutex<PromiseState<T, F>>>
}
impl<T: Send, F: FnOnce(T) + Send> FnOnce(T) for Resolver<T, F> {
extern "rust-call" fn call_once(self, args: (T,)) -> () {
let (value,) = args;
let mut ctx = (*self.context).lock();
let current = mem::replace(&mut *ctx, Done);
match current {
Ready => { *ctx = Fulfilled(value); }
Deferred(cb) => { cb.call_once((value,)); }
_ => { panic!(); }
};
}
}
impl<T: Send, F: FnOnce(T) + Send> Promise<T, F> {
fn then(self, f: F) {
let mut ctx = self.context.lock();
let current = mem::replace(&mut *ctx, Done);
match current {
Ready => { *ctx = Deferred(f); }
Fulfilled(value) => { f(value); }
_ => { panic!(); }
}
}
}
fn promise<T: Send, F: FnOnce(T) + Send>() -> (Resolver<T, F>, Promise<T, F>) {
let ctx = Arc::new(Mutex::new(PromiseState::Ready));
(Resolver { context: ctx.clone() }, Promise { context: ctx })
}
fn main() {
let (resolve, promise) = promise();
spawn(move || {
resolve(42i);
});
promise.then(|v: int| {
println!("{}", v);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment