简体   繁体   English

转换 Vec<rtcicecandidate> 进入 JsValue</rtcicecandidate>

[英]Converting Vec<RtcIceCandidate> into JsValue

I am trying to define a js_sys::Promise .我正在尝试定义一个js_sys::Promise The resolution of the promise should return a container buf with all gathered ice candidates in a webrtc initialization. promise 的分辨率应该在 webrtc 初始化中返回一个包含所有收集的候选冰的容器buf

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)>,
    );
});

I am not sure how to convert buf into a JsValue which is required to call theresolve function.我不确定如何将buf转换为调用resolve JsValue所需的 JsValue。 I am getting the following error when trying to compile the code above:尝试编译上面的代码时出现以下错误:

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>`

I have tried some alternative ways of converting buf:我尝试了一些转换 buf 的替代方法:

resolve.call0(&JsValue::from(&buf));

This gives the error:这给出了错误:

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`

And JsValue::from_serde requires that RtcIceCandidate implements the Serialize trait, which is not the case here.并且JsValue::from_serde要求RtcIceCandidate实现Serialize特征,这里不是这种情况。

The problem is not with the RtcIceCandidate , that derefs to JsValue .问题不在于RtcIceCandidate ,它与JsValue JsValue

I've never used js-sys, so I may be wrong, but the problem seems to be that converting Vec into js_sys::Array must be done explicitly (maybe because it's expensive and needs one WASM→JS call per element?).我从来没有使用过 js-sys,所以我可能错了,但问题似乎是必须明确地将Vec转换为js_sys::Array (可能是因为它很昂贵并且每个元素需要一个 WASM→JS 调用?)。

You can convert a Vec to a JsValue like this:您可以像这样将Vec转换为JsValue

&buf.iter().collect::<Array>()

But I suspect that it would be better to work with the Array directly.但我怀疑直接使用Array会更好。

use js_sys::Array;
use wasm_bindgen::prelude::Closure;
use web_sys::RtcPeerConnectionIceEvent;

fn main() {
    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)>);
        },
    );
}

And the Cargo.toml , in case anybody else wants to reproduce:还有Cargo.toml ,以防其他人想要复制:

[dependencies]
web-sys = { version = "0.3.56", features = ["RtcIceCandidate", "RtcPeerConnectionIceEvent"] }
js-sys = "0.3.56"
wasm-bindgen = "0.2.79"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM