0

I can't get first element of the vector because of the error and can't change struct design either. I tried borrowing but struct expects a ExtrudeGeometry.

#[wasm_bindgen]
pub fn toCollection(arr: js_sys::Array, r_type: String) -> JsValue {
    let n_arr: Vec<ExtrudeGeometry> = arr.into_serde().unwrap();
    if r_type == "GeometryCollection" {
        return JsValue::from_serde(&OutputGeometryCollection {
            collection: n_arr,
            r#type: r_type,
        })
        .unwrap();
    } else {
        let ex: ExtrudeGeometry = n_arr[0];
        return JsValue::from_serde(&OutputObject {
            data: ex,
            r#type: r_type,
        })
        .unwrap();
    }
}
error[E0507]: cannot move out of borrowed content
   --> src/lib.rs:308:39
    |
308 |             let ex: ExtrudeGeometry = n_arr[0];
    |                                       ^^^^^^^^
    |                                       |
    |        cannot move out of borrowed content
    |        help: consider borrowing here: `&n_arr[0]`
Boiethios
  • 38,438
  • 19
  • 134
  • 183
mertselimb
  • 167
  • 7
  • 2
    Hi there! Does [this](https://stackoverflow.com/questions/35873497/getting-value-from-a-collection-without-using-the-clone-trait) or [this](https://stackoverflow.com/questions/45803990/how-can-i-take-an-item-from-a-vec-in-rust) answer your question? Summary: you are trying to get an element from a `Vec` by value, but that is not possible without cloning or removing it entirely from the `Vec`. – Lukas Kalbertodt Sep 03 '19 at 07:34
  • I am new to rust. I don't understand the error. If cloning helps it will be my answer. – mertselimb Sep 03 '19 at 07:37
  • 1
    If you throw the vector away, you don't need to clone the item. Just consume it: `n_arr.into_iter().next().unwrap()` – Boiethios Sep 03 '19 at 07:37
  • Please explain how it works in a answer so i can accept it. It solved the problem. – mertselimb Sep 03 '19 at 07:39
  • 1
    I just now also found [this Q&A](https://stackoverflow.com/questions/27904864/what-does-cannot-move-out-of-indexed-content-mean) which probably fits your question more closely! – Lukas Kalbertodt Sep 03 '19 at 07:51
  • I should have seen that. Thanks. – mertselimb Sep 03 '19 at 07:56
  • 1
    Don't worry! Your question now serves as signpost and will be easier found by people who formulate the problem like you do. – Lukas Kalbertodt Sep 03 '19 at 07:57

1 Answers1

2

I assume in this answer that the ownership system of Rust is known. Your vector owns the items, so if you ask for the first one, you can only borrow it because the vector is composed of items contiguous in memory. You cannot randomly remove an item from it with the index notation.

If you want to take the first one, you have 3 choices:

  • You don't care about the remaining of the vector: you can transform it into an iterator and take the first item iterated:

    vector
        .into_iter() // consume the vector to get an iterator
        .next() // get the first iterated item
        .unwrap()
    
  • You care about the remaining, but you don't care about the ordering, use swap_remove:

    vector.swap_remove(0)
    
  • You care about the remaining and the ordering: don't use a vector. I you don't have that choice, you can use remove, but that's a O(n) function.


By the way, the return in last position is not idiomatic:

#[wasm_bindgen]
pub fn toCollection(arr: js_sys::Array, r_type: String) -> JsValue {
    let n_arr: Vec<ExtrudeGeometry> = arr.into_serde().unwrap();

    if r_type == "GeometryCollection" {
        JsValue::from_serde(&OutputGeometryCollection {
            collection: n_arr,
            r#type: r_type,
        })
        .unwrap()
    } else {
        let ex = n_arr.into_iter().next().unwrap();

        JsValue::from_serde(&OutputObject {
            data: ex,
            r#type: r_type,
        })
        .unwrap();
    }
}
Boiethios
  • 38,438
  • 19
  • 134
  • 183