Write number into array

I'm building a binary network message and I want to write 32-bit numbers to specific places in the message:

fn main() {
    let mut message = [0u8; 20];
    
    let value_a: u32 = 16909060;
    let value_b: u32 = 84281096;
    
    let value_a_encoded = value_a.to_be_bytes();
    
    message[5] = value_a_encoded[0];
    message[6] = value_a_encoded[1];
    message[7] = value_a_encoded[2];
    message[8] = value_a_encoded[3];
    
    let value_b_encoded = value_b.to_be_bytes();
    
    message[11] = value_b_encoded[0];
    message[12] = value_b_encoded[1];
    message[13] = value_b_encoded[2];
    message[14] = value_b_encoded[3];
    
    println!("{:02x?}", message);
}
[00, 00, 00, 00, 00, 01, 02, 03, 04, 00, 00, 05, 06, 07, 08, 00, 00, 00, 00, 00]

Playground

This is pretty verbose, is there a nicer way?

If the "start with zeroes and splice in the values" approach is a problem, I'm also fine with an approach where I would build the whole message from pieces ("00 00 00 00 00" + value_a + "00 00" + value_b + "00 00 00 00 00").

You could use copy_from_slice:

message[5..9].copy_from_slice(&value_a.to_be_bytes());
message[11..15].copy_from_slice(&value_b.to_be_bytes());
5 Likes

You can use byteorder and std::io::Cursor:

use byteorder::{BE, WriteBytesExt}; // 1.4.3
use std::io::{Cursor, Seek, SeekFrom};
fn main() {
    let mut message = [0u8; 20];
    
    let value_a: u32 = 16909060;
    let value_b: u32 = 84281096;
    
    let mut cursor = Cursor::new(&mut message[..]);
    cursor.seek(SeekFrom::Start(5)).expect("seek error");
    cursor.write_u32::<BE>(value_a).expect("write error");
    cursor.seek(SeekFrom::Current(2)).expect("this would be easier");
    cursor.write_u32::<BE>(value_b).expect("in a function that returned io::Result");
    
    println!("{:02x?}", message);
}

Not as clean as copy_from_slice in this case, however, depending on what you're actually doing it might be a bit nicer. In particular if you're writing to a file (in which case you can eschew message and cursor and just write to the final destination) or if you're actually generating data in sequence (which means you don't need the seeks).

2 Likes