Search code examples
rustbyte

Convert Vec<u8> to Vec<{float}> in rust


I'm looking to pass a message through a channel. The message type is bytes::Bytes due to the implementation of the channel.

The message I want to send is about a vector of floats (Vec<{float}>) and I convert it like this:

let flatten_array: Vec<u8> = correct_centroids
            .clone()
            .into_iter()
            .flat_map(|x| f32::to_le_bytes(x).to_vec().into_iter())
            .collect();

 let data = Bytes::from(flatten_array);

My question is, how can I reconvert the Vec<u8> that I get back to Vec<{float}> again.

Is there any other better way to serialize the message?


Solution

  • You can use chunks to split the Vec (or more specifically any slice) up, convert to arrays and call from_le_bytes, i.e. almost just do the reverse of what you did:

    fn u8_to_f32_vec(v: &[u8]) -> Vec<f32> {
        v.chunks_exact(4)
            .map(TryInto::try_into)
            .map(Result::unwrap)
            .map(f32::from_le_bytes)
            .collect()
    }
    

    The only problem is that chunks does only give slices, not array references. In future (or on nightly) that can be written with the array_chunks method instead:

    #![feature(array_chunks)]
    fn u8_to_f32_vec(v: &[u8]) -> Vec<f32> {
        v.array_chunks::<4>()
            .copied()
            .map(f32::from_le_bytes)
            .collect()
    }
    

    Playground

    Note: Both versions will silently drop excess bytes at the end of the slice.