# Vec<u8> to a series of [u8; 2]

I'm back with another newbie question (so soon). I've spent the afternoon trying all sorts of things to solve this one ;).

I have one way to convert a series of u8 in a vector to u16,

``````n main() {
let mut vec = Vec::<u8>::new();
vec.push(20); vec.push(21);
vec.push(22); vec.push(23);

// OK

let mut i = 0;
let b = u16::from_be_bytes(vec[i..2].try_into().unwrap());
i += 2;
let b = u16::from_be_bytes(vec[i..2].try_into().unwrap());

let t = vec.iter();

// not so OK

let b: &u8 = t.take(2).collect();
let u = u16::from_be_bytes(b.try_into().unwrap());
let b: &u8 = t.take(2).collect();
let u = u16::from_be_bytes(b.try_into().unwrap());
}
``````

I wanted to try the same with an iterator and avoid having to update my offset all the time.

``````20 |      let b: &u8 = t.take(2).collect();
|                   ^^^^^^^^^ ------- required by a bound introduced by this call
|                   |
|                   value of type `&u8` cannot be built from `std::iter::Iterator<Item=&u8>`
|
``````
``````21 |      let u = u16::from_be_bytes(b.try_into().unwrap());
|                                 ^ -------- required by a bound introduced by this call
|                                 |
|                                 the trait `From<&u8>` is not implemented for `[u8; 2]`
``````

I suppose I could wrap the way which works in some kind of struct so I can just do

``````let u = thingy.get_u16(); // 0..2
let u = thingy.get_u16(); //2..2
``````

When I was reading bytes from a file, this worked really well

``````     let mut buf = [0; 2];
Ok(_) => u16::from_be_bytes(buf),
``````

and was hoping for something neat when reading from a Vec.

Thanks.

When you give type to a variable, that type will be used by the compiler as the target collection for the iterator `.collect` method. That being said, the compiler is telling you that `&u8` is not a valid collection to be built from an iterator where the items are `&u8`.

This works, for example:

``````let collected: [&u8; 2] = vec.iter().take(2).collect::<Vec<_>>().try_into().unwrap();
``````

I'd use the nightly feature `array_chunks`, which provides a convenient method for this task:

``````#![feature(array_chunks)]

fn main() {
let vec = vec![20, 21, 22, 23];
let chunks = vec.array_chunks::<2>();
let result: Vec<u16> = chunks.map(|a| u16::from_be_bytes(*a)).collect();
dbg!(result);
}
``````
1 Like

And on stable, this is just

``````vec.chunks_exact(2).map(|chunk| <[u8; 2]>::try_from(chunk).unwrap())
``````

where the panic case will be optimized away completely (tested in real-life signal processing code).

2 Likes

Of course. I wasn't proposing a solution, just highlighting what the compiler was complaining about on the OPs first post.

`&[u8]` implements `Read`.

``````    let mut bytes = &*vec;
let mut buf = [0; 2];
Thank you. I got close with `: [u8; 2]` at one point. The two `collect()` in my demo well that is not going to work at all :(.
That will only gather the first two elements, though. (That's what `.take(2)` does.)