use stdweb::{self, unstable::TryInto, Reference};
#[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
#[reference(instance_of = "Promise")]
pub struct Promise(Reference);
impl Promise {
pub fn new<F>(user_callback: F) -> Self
where
F: 'static + FnOnce(PromiseCallback, PromiseCallback),
{
let callback = move |resolve: stdweb::Value, reject: stdweb::Value| {
user_callback(
PromiseCallback(resolve.into_reference().unwrap()),
PromiseCallback(reject.into_reference().unwrap()),
);
};
(js! {
return new Promise(function(resolve, reject) {
let callback = @{stdweb::Once(callback)};
callback(resolve, reject);
});
}).try_into()
.expect("new Promise did not return a Promise!")
}
pub fn all(promises: &[Promise]) -> Promise {
(js! {
return Promise.all(@{promises});
}).try_into()
.expect("Promise.all did not return a Promise!")
}
pub fn then<F: 'static + FnOnce(stdweb::Value) -> stdweb::Value>(
&self,
callback: F,
) -> Promise {
(js! {
let callback = @{stdweb::Once(callback)};
return @{self}.then(callback);
}).try_into()
.expect("Promise.then did not return a Promise!")
}
}
#[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
#[reference(instance_of = "Function")]
pub struct PromiseCallback(Reference);
impl PromiseCallback {
pub fn complete(self) {
js! {
@(no_return)
let completion = @{self};
completion();
}
}
pub fn with<JS: stdweb::JsSerialize>(self, value: JS) {
js! {
@(no_return)
let completion = @{self};
completion(@{value});
}
}
}