Endianness, API Design, and Polymorphism in Rust
thecodedmessage.com
thecodedmessage.com
roman numbers were already “big endian”, though.
Not India?
So the Persians picked them up and put them in their right-to-left text, so little-endian for them, and then Europeans picked them up from the Persians, all as-is. Little-endian would make typesetting columns of figures simpler, but that ship sailed long ago.
> Unfortunately, as the ??? shows, the different output arrays have different lengths – a u16 would be 2 bytes and a u64 8 bytes – and so the Rust trait system at the time of this writing is (to my knowledge) not powerful enough to represent this trait as is.
It seems to me that this is possible using const generics. If you define your EndianBytes like this:
trait EndianBytes<const N: usize> {
fn be_bytes(self) -> [u8; N];
fn le_bytes(self) -> [u8; N];
}
Then provide a concrete length with each impl: impl EndianBytes<4> for u32 {
fn be_bytes(self) -> [u8; 4] {
self.to_be_bytes()
}
fn le_bytes(self) -> [u8; 4] {
self.to_le_bytes()
}
}
(I've renamed their methods to avoid conflicting with u32::to_be_bytes to make it easier to read)Then that allows you to use the EndianBytes type as long as you remain generic over both the value type and its length:
fn write<T: EndianBytes<N>, const N: usize>(val: T) {
println!("{:?}", val.be_bytes());
}
fn main() {
write(0x1234u16);
write(0x12345678u32);
}
This code (plus an impl for EndianBytes<2> for u16) works for me on 1.51 stable.EDIT: I thought about doing this with an associated constant, ie:
trait EndianBytes {
const LENGTH: usize;
fn be_bytes(self) -> [u8; Self::LENGTH];
fn le_bytes(self) -> [u8; Self::LENGTH];
}
However it turns out that this kind of usage is not quite supported yet: https://github.com/rust-lang/rust/issues/60551We did it in C and it was pretty fast.
Most recent weird case I discovered is CBOR, which is reasonably well designed (it's hard to get binary JSON very wrong to be fair), but the designers inexplicably decided to use big endian. In 2013.
Which is a serious head desk. It's seriously nothing but a pain in the ass.