Not specify the byte order with each call

This is the example of how to use the methods of the ReadBytesExt trait of the byteorder crate:

use std::io::Cursor;
use byteorder::{BigEndian, ReadBytesExt};

let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());

This requires me to specify the byte order every time I call one of the methods on the reader:

rdr.read_u16::<BigEndian>()

Is there a way to get rid of that? Normally a type alias can be used to pack overly verbose type parameters into a convenient name, but I don't know how (and if) that is possible with the trait methods here.

You can alias BigEndian as a shorter name.

You can write a helper function that performs big-endian read.

Rust now has built-in endian conversion functions, so you can also read into an array and use u16 - Rust

Another option is to define your own local extension trait, implement it for the types you care about, and have the trait expose the helper function. Might be more convenient to do rdr.trait_read_u16() over freestanding_read_u16(&mut rdr).

2 Likes

This works nicely. Here's my extension trait that forwards read_u32() and read_u64() to the respective methods of byteorder::ReadBytesExt:

trait ReadBytesExt: byteorder::ReadBytesExt {
	fn read_u32(&mut self) -> std::io::Result<u32> {
		byteorder::ReadBytesExt::read_u32::<byteorder::BigEndian>(self)
	}
	fn read_u64(&mut self) -> std::io::Result<u64> {
		byteorder::ReadBytesExt::read_u64::<byteorder::BigEndian>(self)
	}
}
impl<R: byteorder::ReadBytesExt + ?Sized> ReadBytesExt for R {}
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.