# Convert array of u32 to Vec<u8> in Rust

In Rust, I want to take an array of u32 values, convert each to four bytes in big endian, and concatenate them to yield a Vec<u8> result. Example:

let input: [u32; 5] = [
0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];

(... Do some data conversion work ...)

let output: Vec<u8> = vec![
0x67, 0x45, 0x23, 0x01,
0xEF, 0xCD, 0xAB, 0x89,
0x98, 0xBA, 0xDC, 0xFE,
0x10, 0x32, 0x54, 0x76,
0xC3, 0xD2, 0xE1, 0xF0,
];


I have several pieces of working code that all give the same answer.

Algorithm A (for-loop):

let mut output = Vec::<u8>::new();
for val in &input{
output.extend_from_slice(&val.to_be_bytes());
}


Algorithm B (for-each):

let mut output = Vec::<u8>::new();
input.iter().for_each(|val| output.extend_from_slice(&val.to_be_bytes()));


Algorithm C (fold-append):

let output = input.iter().fold(Vec::<u8>::new(),
|mut acc, val| {acc.extend_from_slice(&val.to_be_bytes()); acc});


Algorithm D (flat-map):

let output: Vec<u8> = input.iter().flat_map(|val| val.to_be_bytes().to_vec()).collect();


Is there an even shorter, clearer way to accomplish the task? Maybe algorithm D's to_vec() could be avoided somehow?

Speed is not a concern because this code only executes a few times, and the input array length is fixed at 5.

Algorithm A seems the clearest to me. An improvement might be to use Vec::with_capacity to avoid the allocation. Indeed, arrays in Rust are currently somewhat cumbersome to use.

My advice would be to wrap it in a function and not worry about it later on:

pub fn to_bytes(input: &[u32]) -> Vec<u8> {
let mut bytes = Vec::with_capacity(4 * input.len());

for value in input {
bytes.extend(&value.to_be_bytes());
}

bytes
}

#[cfg(test)]
mod tests {
#[test]
fn to_bytes() {
use super::*;

assert_eq!(to_bytes(&[]), &[]);

let input = &[0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
let output = &[
0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89, 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32,
0x54, 0x76, 0xC3, 0xD2, 0xE1, 0xF0,
];

assert_eq!(to_bytes(input), output);
}
}


Rust 1.53.0 (2021-06-17) introduces the IntoIterator for array types, which finally makes this shorter code possible:

Algorithm E (flat-map simpler):

let output: Vec<u8> = input.iter().flat_map(|val| val.to_be_bytes()).collect();


(This is based on my algorithm D, removing .to_vec(). I did check that algorithm E fails to compile using Rust 1.52.0.)

Algorithm F (not recommended, Rust 1.51.0, see std::array::IntoIter::new()):

let output: Vec<u8> = input.iter().flat_map(|val|
std::array::IntoIter::new(val.to_be_bytes())).collect();