将 Vec<RtcIceCandidate> 转换为 JsValue
Converting Vec<RtcIceCandidate> into JsValue
我正在尝试定义 js_sys::Promise
。承诺的解决方案应该 return 一个容器 buf
在 webrtc 初始化中包含所有收集的 ice 候选对象。
let promise = js_sys::Promise::new(&mut |resolve: js_sys::Function, reject: js_sys::Function| {
let mut buf: Vec<RtcIceCandidate> = Vec::new();
let onicecandidate_callback = Closure::wrap(
Box::new(move |ev: RtcPeerConnectionIceEvent| match ev.candidate() {
Some(candidate) => {
buf.push(candidate);
}
None => {
// resolve promise here
resolve.call0(&buf.into())
}
}) as Box<dyn FnMut(RtcPeerConnectionIceEvent)>,
);
});
我不确定如何将 buf
转换为 JsValue
which is required to call the resolve
函数。尝试编译上面的代码时出现以下错误:
error[E0277]: the trait bound `wasm_bindgen::JsValue: From<Vec<RtcIceCandidate>>` is not satisfied
--> src/lib.rs:529:43
|
529 | resolve.call0(&buffer.into());
| ^^^^ the trait `From<Vec<RtcIceCandidate>>` is not implemented for `wasm_bindgen::JsValue`
|
= help: the following implementations were found:
<wasm_bindgen::JsValue as From<&'a T>>
<wasm_bindgen::JsValue as From<&'a std::string::String>>
<wasm_bindgen::JsValue as From<&'a str>>
<wasm_bindgen::JsValue as From<ArrayBuffer>>
and 112 others
= note: required because of the requirements on the impl of `Into<wasm_bindgen::JsValue>` for `Vec<RtcIceCandidate>`
我尝试了一些转换 buf 的替代方法:
resolve.call0(&JsValue::from(&buf));
这给出了错误:
error[E0277]: the trait bound `Vec<RtcIceCandidate>: JsCast` is not satisfied
--> src/lib.rs:529:36
|
529 | resolve.call0(&JsValue::from(&buffer));
| ^^^^^^^^^^^^^ the trait `JsCast` is not implemented for `Vec<RtcIceCandidate>`
|
= note: required because of the requirements on the impl of `From<&Vec<RtcIceCandidate>>` for `wasm_bindgen::JsValue`
而JsValue::from_serde
要求RtcIceCandidate
实现Serialize
特性,这里不是这种情况。
问题不在于 RtcIceCandidate
,即 derefs 到 JsValue
。
我从来没有用过js-sys,所以我可能是错的,但问题似乎是必须明确地将Vec
转换为js_sys::Array
(可能是因为它很昂贵每个元素需要一个 WASM→JS 调用?)。
您可以像这样将 Vec
转换为 JsValue
:
&buf.iter().collect::<Array>()
但我怀疑直接使用 Array
会更好。
use js_sys::Array;
use wasm_bindgen::prelude::Closure;
use web_sys::RtcPeerConnectionIceEvent;
fn foo() {
let _promise = js_sys::Promise::new(
&mut |resolve: js_sys::Function, _reject: js_sys::Function| {
let buf: Array = Array::new();
let _onicecandidate_callback = Closure::wrap(Box::new(
move |ev: RtcPeerConnectionIceEvent| match ev.candidate() {
Some(candidate) => {
buf.push(&candidate);
}
None => {
// resolve promise here
resolve.call0(&buf).unwrap();
}
},
)
as Box<dyn FnMut(RtcPeerConnectionIceEvent)>);
},
);
}
还有 Cargo.toml
,以防其他人想要复制:
[dependencies]
web-sys = { version = "0.3.56", features = ["RtcIceCandidate", "RtcPeerConnectionIceEvent"] }
js-sys = "0.3.56"
wasm-bindgen = "0.2.79"
我正在尝试定义 js_sys::Promise
。承诺的解决方案应该 return 一个容器 buf
在 webrtc 初始化中包含所有收集的 ice 候选对象。
let promise = js_sys::Promise::new(&mut |resolve: js_sys::Function, reject: js_sys::Function| {
let mut buf: Vec<RtcIceCandidate> = Vec::new();
let onicecandidate_callback = Closure::wrap(
Box::new(move |ev: RtcPeerConnectionIceEvent| match ev.candidate() {
Some(candidate) => {
buf.push(candidate);
}
None => {
// resolve promise here
resolve.call0(&buf.into())
}
}) as Box<dyn FnMut(RtcPeerConnectionIceEvent)>,
);
});
我不确定如何将 buf
转换为 JsValue
which is required to call the resolve
函数。尝试编译上面的代码时出现以下错误:
error[E0277]: the trait bound `wasm_bindgen::JsValue: From<Vec<RtcIceCandidate>>` is not satisfied
--> src/lib.rs:529:43
|
529 | resolve.call0(&buffer.into());
| ^^^^ the trait `From<Vec<RtcIceCandidate>>` is not implemented for `wasm_bindgen::JsValue`
|
= help: the following implementations were found:
<wasm_bindgen::JsValue as From<&'a T>>
<wasm_bindgen::JsValue as From<&'a std::string::String>>
<wasm_bindgen::JsValue as From<&'a str>>
<wasm_bindgen::JsValue as From<ArrayBuffer>>
and 112 others
= note: required because of the requirements on the impl of `Into<wasm_bindgen::JsValue>` for `Vec<RtcIceCandidate>`
我尝试了一些转换 buf 的替代方法:
resolve.call0(&JsValue::from(&buf));
这给出了错误:
error[E0277]: the trait bound `Vec<RtcIceCandidate>: JsCast` is not satisfied
--> src/lib.rs:529:36
|
529 | resolve.call0(&JsValue::from(&buffer));
| ^^^^^^^^^^^^^ the trait `JsCast` is not implemented for `Vec<RtcIceCandidate>`
|
= note: required because of the requirements on the impl of `From<&Vec<RtcIceCandidate>>` for `wasm_bindgen::JsValue`
而JsValue::from_serde
要求RtcIceCandidate
实现Serialize
特性,这里不是这种情况。
问题不在于 RtcIceCandidate
,即 derefs 到 JsValue
。
我从来没有用过js-sys,所以我可能是错的,但问题似乎是必须明确地将Vec
转换为js_sys::Array
(可能是因为它很昂贵每个元素需要一个 WASM→JS 调用?)。
您可以像这样将 Vec
转换为 JsValue
:
&buf.iter().collect::<Array>()
但我怀疑直接使用 Array
会更好。
use js_sys::Array;
use wasm_bindgen::prelude::Closure;
use web_sys::RtcPeerConnectionIceEvent;
fn foo() {
let _promise = js_sys::Promise::new(
&mut |resolve: js_sys::Function, _reject: js_sys::Function| {
let buf: Array = Array::new();
let _onicecandidate_callback = Closure::wrap(Box::new(
move |ev: RtcPeerConnectionIceEvent| match ev.candidate() {
Some(candidate) => {
buf.push(&candidate);
}
None => {
// resolve promise here
resolve.call0(&buf).unwrap();
}
},
)
as Box<dyn FnMut(RtcPeerConnectionIceEvent)>);
},
);
}
还有 Cargo.toml
,以防其他人想要复制:
[dependencies]
web-sys = { version = "0.3.56", features = ["RtcIceCandidate", "RtcPeerConnectionIceEvent"] }
js-sys = "0.3.56"
wasm-bindgen = "0.2.79"