Search code examples
arrayscastingrustslice

How can I convert a buffer of a slice of bytes (&[u8]) to an integer?


I am reading raw data from a file and I want to convert it to an integer:

fn main() {
    let buf: &[u8] = &[0, 0, 0, 1];
    let num = slice_to_i8(buf);
    println!("1 == {}", num);
}

pub fn slice_to_i8(buf: &[u8]) -> i32 {
    unimplemented!("what should I do here?")
}

I would do a cast in C, but what do I do in Rust?


Solution

  • I'd suggest using the byteorder crate (which also works in a no-std environment):

    use byteorder::{BigEndian, ReadBytesExt}; // 1.2.7
    
    fn main() {
        let mut buf: &[u8] = &[0, 0, 0, 1];
        let num = buf.read_u32::<BigEndian>().unwrap();
    
        assert_eq!(1, num);
    }
    

    This handles oddly-sized slices and automatically advances the buffer so you can read multiple values.

    As of Rust 1.32, you can also use the from_le_bytes / from_be_bytes / from_ne_bytes inherent methods on integers:

    fn main() {
        let buf = [0, 0, 0, 1];
        let num = u32::from_be_bytes(buf);
    
        assert_eq!(1, num);
    }
    

    These methods only handle fixed-length arrays to avoid dealing with the error when not enough data is present. If you have a slice, you will need to convert it into an array.

    See also: