Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to iterate Uint8Array on Rust #1160

Closed
evaporei opened this issue Jan 9, 2019 · 8 comments
Closed

How to iterate Uint8Array on Rust #1160

evaporei opened this issue Jan 9, 2019 · 8 comments

Comments

@evaporei
Copy link

evaporei commented Jan 9, 2019

Hello! I am trying to convert a Uint8Array to a Vec<u8>, however I am having problems to iterate it and get the values.

Example code:

pub trait JsPacketManipulation {
    fn to_vec_u8(&self) -> Vec<u8>;
}

impl JsPacketManipulation for Uint8Array {
    fn to_vec_u8(&self) -> Vec<u8> {
        let mut vec: Vec<u8> = vec![];

        self.for_each(&mut |byte: u8, _length: u32, _array: Uint8Array| {
            vec.push(byte);
        });

        vec
    }
}

This code compiles, however it leads to this error on the browser: Uncaught TypeError: getObject(...).forEach is not a function.

I've also tried using try_iter, but I couldn't convert the JsValue to an u8 🙁

pub trait JsPacketManipulation {
    fn to_vec_u8(&self) -> Vec<u8>;
}

impl JsPacketManipulation for Uint8Array {
    fn to_vec_u8(&self) -> Vec<u8> {
        let mut vec: Vec<u8> = vec![];

        let iterator = js_sys::try_iter(self).unwrap().ok_or_else(|| {
            "need to pass iterable JS values!"
        }).unwrap();

        for byte in iterator {
            vec.push(byte.unwrap().into());
        }

        vec
    }
}

This other example doesn't compile, and it leads to this error on cargo:

error[E0277]: the trait bound `u8: std::convert::From<wasm_bindgen::JsValue>` is not satisfied
  --> src/packet/manipulation.rs:63:36
   |
63 |             vec.push(byte.unwrap().into());
   |                                    ^^^^ the trait `std::convert::From<wasm_bindgen::JsValue>` is not implemented for `u8`
   |
   = help: the following implementations were found:
             <u8 as std::convert::From<bool>>
             <u8 as std::convert::From<std::num::NonZeroU8>>
   = note: required because of the requirements on the impl of `std::convert::Into<u8>` for `wasm_bindgen::JsValue`
@chinedufn
Copy link
Contributor

chinedufn commented Jan 9, 2019

Would Uint8Array::copy_to fit your use case?

Maybe something along the lines of:

let uint8array = Uint8Array::new();
let mut slice = vec![0; uint8array.length()];
uint8array.copy_to(&mut slice[..])

@evaporei
Copy link
Author

evaporei commented Jan 9, 2019

I am using js_sys version 0.3.6, and the copy_to method was added on 0.3.7, however the method still isn't available somehow 🤔

The error I am getting:

error[E0599]: no method named `copy_to` found for type `&js_sys::Uint8Array` in the current scope
  --> src/packet/manipulation.rs:55:14
   |
55 |         self.copy_to(&mut vec[..]);
   |              ^^^^^^^

Also @alexcrichton I don't know if you follow semver, but wouldn't it make more sense for this change to be a minor instead of a patch?

@chinedufn
Copy link
Contributor

chinedufn commented Jan 9, 2019

At this time, from what I can tell, wasm-bindgen is bundling most new API additions into patch versions, and if something really big comes along it gets a minor bump.

This is actually totally allowed by SemVer since wasm-bindgen hasn't hit 1.0.0 yet.

image

via https://semver.org/


I am using js_sys version 0.3.6, and the copy_to method was added on 0.3.7, however the method still isn't available somehow

You won't automatically get 0.3.7 if you already have 0.3.6 locally.

Quickest thing you can do is to go into your Cargo.toml and set js_sys = "0.3.7"

Hope that works!

@evaporei
Copy link
Author

evaporei commented Jan 9, 2019

We tried to update in Cargo.toml of js_sys from 0.3.6 to 0.3.7, and it doesn't work 🙁

I even tried to use cargo clean to clear any cache but it didn't worked.

@evaporei
Copy link
Author

evaporei commented Jan 9, 2019

I've created a new project to verify that it wasn't some kind of cache, here it is the output:

screenshot-output

@chinedufn
Copy link
Contributor

chinedufn commented Jan 9, 2019

Gotcha. The only other thing that comes to mind is that it's possible that js-sys 0.3.7 was deployed before these slice changes landed.

image

Since the docs get built in CI on master it's possible for the docs to be a little ahead of what's actually live.

Can you set js-sys = { git = "https://github.com/rustwasm/wasm-bindgen", branch = "maser" } in your Cargo.toml and see if you still get an error?

@alexcrichton
Copy link
Contributor

Thanks for the report @otaviopace and helping to narrow this doen @chinedufn! I've hopefully made it a bit easier to test this out and I've just gone ahead and published a new version of everything :)

@evaporei
Copy link
Author

evaporei commented Jan 9, 2019

Thank you so much!!! It fixed the issue 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants