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("")); 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 { 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::(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::(&body).unwrap(); console!(log, "returning deserialized result"); return Ok(PromiseOk::Immediate(out)); }); return p; } fn main() { set_panic_hook(); Promise::::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(())) }); }