Как сравнить значения двух JsValues ​​в коде Rust? - PullRequest
0 голосов
/ 15 марта 2019

В JavaScript я могу сделать это так:

JSON.stringify([1,2,3]) ===  JSON.stringify([1,2,3]) // true

В Rust, скомпилированном в Wasm, я пробовал что-то вроде:

#[wasm_bindgen_test]
fn test_algo() {
    let js_array_to_sort = Array::of3(&JsValue::from(1), &JsValue::from(3), &JsValue::from(2));
    let js_array_after_sort = Array::of3(&JsValue::from(1), &JsValue::from(2), &JsValue::from(3));
    let array = JsValue::from(&js_array_to_sort);

    assert_eq!(
        JSON::stringify(BubbleSort::sort(SortArray::new(array))).unwrap(),
        JSON::stringify(JsValue::from(&js_array_after_sort)).unwrap(),
    );
}

Возникла ошибка с wasm-pack test --chrome о нет partialeq для JsString - результат JSON::stringify:

 error[E0277]: can't compare `js_sys::JsString` with `js_sys::JsString`
    --> src/algorithms/bubble.rs:36:5
     |
  36 | /     assert_eq!(
  37 | |         JSON::stringify(&BubbleSort::sort(SortArray::new(array))).unwrap(),
  38 | |         JSON::stringify(&JsValue::from(&js_array_after_sort)).unwrap(),
  39 | |     );
     | |______^ no implementation for `js_sys::JsString == js_sys::JsString`
     |
     = help: the trait `std::cmp::PartialEq` is not implemented for `js_sys::JsString`

Если я пытаюсь преобразовать в строку и сравнить каким-либо другим способом (например, напрямую с помощью метода JsString), я всегда получаю одну и ту же ошибку компиляции.

Если я попытаюсь сравнить этот массив напрямую, у меня будет похожее поведение в JavaScript:

JsValue([1,2,3]) == JsValue([1,2,3]) // false

В Cargo.toml У меня есть:

[dependencies]
wasm-bindgen = "0.2.39"
js-sys = "0.3.16"
wasm-bindgen-test = "0.2.39"

Как мне сделать такое сравнение?

Редактировать.

Я придумываю что-то вроде этого, чтобы пройти этот тест:

  assert_eq!(
        String::from(JSON::stringify(&BubbleSort::sort(SortArray::new(array))).unwrap()),
        String::from(JSON::stringify(&JsValue::from(&js_array_after_sort)).unwrap()),
    );

1 Ответ

1 голос
/ 15 марта 2019

Если я правильно понимаю, вы не должны их сравнивать. Они не реализуют Eq или PartialEq, и поэтому вы не можете сравнивать их срезы или массивы.

На самом деле они даже не живут внутри Rust, а просто являются индексами значений снаружи.

Вы, вероятно, тоже не можете их отсортировать, потому что они не реализуют Ord.

Идиоматический способ сделать это - преобразовать их в примитивы Rust с помощью методов as_f64, а затем делать все, что вам нужно.

Было бы проще, если бы у вас был TypedArray, который можно легко преобразовать в vec.

let js_array_to_sort = Array::of3(&JsValue::from(1), &JsValue::from(3), &JsValue::from(2));

let rust_vec = js_array_to_sort
    .values().into_iter()
    .map(|js_val|
        js_val.as_f64().unwrap() as i64
    )
    .collect::<Vec<i64>>();

let mut sorted_rust_vec = rust_vec.clone();
sorted_rust_vec.sort();

dbg!(sorted_rust_vec == rust_vec);
...