use js_promises::*;
use std::panic;
use stdweb::{self, js, console};
fn panic_hook(info: &panic::PanicInfo) {
let mut msg = info.to_string();
let stack = js!{
let err = new Error();
return err.stack;
};
msg.push_str("\n\nStack:\n\n");
msg.push_str(stack.as_str().unwrap_or("<Error.stack was not a string>"));
msg.push_str("\n\n");
console!(error, msg);
}
pub fn set_panic_hook() {
panic::set_hook(Box::new(panic_hook));
}
fn http_req(url: &str) -> Promise<serde_json::Value,String> {
let req = stdweb::web::XmlHttpRequest::new();
req.open("GET", url).expect("open failed");
let p = RawPromise::from_value(js!{
return new Promise(function(resolve, reject) {
let req = @{req.as_ref().clone()};
req.addEventListener("load", resolve);
req.addEventListener("abort", function() { reject("abort"); });
req.addEventListener("error", function() { reject("error"); });
req.addEventListener("timeout", function() { reject("timeout"); });
});
});
req.send().unwrap();
let p = p.then_to_typed::<serde_json::Value, String, _>(move |res| {
console!(log, "got web result");
let _ev = res.map_err(|v| v.into_string().unwrap())?;
let body = req.response_text().unwrap().unwrap();
let out = serde_json::from_str::<serde_json::Value>(&body).unwrap();
console!(log, "returning deserialized result");
return Ok(PromiseOk::Immediate(out));
});
return p;
}
fn main() {
set_panic_hook();
Promise::<String,String>::new_resolved(String::from("https://httpbin.org/get"))
.and_then(|url| {
console!(log, "url:", &url);
let new_p = http_req(&url);
console!(log, "have promise");
return Ok(PromiseOk::Promise(new_p));
})
.and_then(|v| {
console!(log, "req result:", format!("{:?}", v));
let url_v = v.pointer("/url").ok_or(String::from("Expected url field in response"))?;
let url = url_v.as_str().ok_or(String::from("url field in response was not a string"))?;
if url == "https://httpbin.org/get" {
return Ok(PromiseOk::Immediate(()));
} else {
return Err(format!("url field in response was incorrect, had value {:?}", url));
}
})
.then::<(),(),_>(|res| {
console!(log, "result:", format!("{:?}", res));
Ok(PromiseOk::Immediate(()))
});
}