我有一个Rust函数,该函数接受输入URL,获取一些JSON,并返回带有已解析输出的Future
。这是函数:
pub fn get<Output>(node: &str, path: &str) -> impl Future<Item = Output, Error = crate::Error>
where
Output: for<'a> Deserialize<'a>,
{
let mut opts = RequestInit::new();
opts.method("GET");
opts.mode(RequestMode::Cors);
let mut url = node.to_owned();
url.push_str(path);
let request = Request::new_with_str_and_init(url.as_str(), &opts).unwrap();
let window = web_sys::window().unwrap();
let request_promise = window.fetch_with_request(&request);
JsFuture::from(request_promise)
.and_then(|resp_value| {
assert!(resp_value.is_instance_of::<Response>());
let resp = resp_value.dyn_into::<Response>().unwrap();
resp.json()
})
.and_then(|json_value: Promise| {
JsFuture::from(json_value)
})
.and_then(|json| {
let out = json.into_serde::<Output>().unwrap();
future::ok(out)
})
.map_err(crate::Error::JsError)
}
我想替换.unwrap()
调用以尽早返回正确的错误,以使该函数不会出现混乱。这是我尝试过的类似功能:
pub fn post<Output, Params>(
node: &str,
path: &str,
params: Params,
) -> impl Future<Item = Output, Error = crate::Error>
where
Output: for<'a> Deserialize<'a>,
Params: Serialize,
{
let mut opts = RequestInit::new();
opts.method("POST");
opts.mode(RequestMode::Cors);
match ::serde_json::to_string(¶ms) {
Ok(s) => opts.body(Some(&JsValue::from_str(s.as_str()))),
Err(error) => return future::err(Error::BadRequestJson(error)),
};
let mut url = node.to_owned();
url.push_str(path);
let request = match Request::new_with_str_and_init(url.as_str(), &opts) {
Ok(r) => r,
Err(_) => return future::err(Error::BadRequest),
};
let window = web_sys::window().unwrap();
let request_promise = window.fetch_with_request(&request);
JsFuture::from(request_promise)
.and_then(|resp_value| {
assert!(resp_value.is_instance_of::<Response>());
let resp = resp_value.dyn_into::<Response>().unwrap();
resp.json()
})
.and_then(|json_value: Promise| {
JsFuture::from(json_value)
})
.and_then(|json| {
let info = json.into_serde::<Output>().unwrap();
future::ok(info)
})
.map_err(crate::Error::JsError)
}
但是Rust编译器不喜欢这样,因为返回了两种不同的类型:
error[E0308]: mismatched types
|
75 | / JsFuture::from(request_promise)
76 | | .and_then(|resp_value| {
77 | | // `resp_value` is a `Response` object.
78 | | assert!(resp_value.is_instance_of::<Response>());
... |
92 | | })
93 | | .map_err(crate::Error::JsError)
| |_______________________________________^ expected struct `futures::future::result_::FutureResult`, found struct `futures::future::map_err::MapErr`
|
= note: expected type `futures::future::result_::FutureResult<Output, error::Error>`
found type `futures::future::map_err::MapErr<futures::future::and_then::AndThen<futures::future::and_then::AndThen<futures::future::and_then::AndThen<wasm
_bindgen_futures::JsFuture, std::result::Result<js_sys::Promise, wasm_bindgen::JsValue>,
那么可以在不更改返回类型的情况下从此函数提前返回吗?我知道我可以将返回类型更改为Result
,但这似乎不必要。