I've been looking around for something that does this, and maybe I'm missing something obvious, but what I'd like to do is something like:
trait OB {
fn from_bytes(bytes: &[u8]) -> Self;
}
...
fn foo<T: OB>(bytes: &[u8]) {
let v = T::from_bytes(bytes);
}
Where OB is implemented for the primitive integer and float types. Essentially, I want the byteorder
crate, but with a trait that lets me use it in generic contexts. I tried writing it up, and this is what I came up with:
use byteorder::ByteOrder;
pub trait OrderBytes {
fn from_bytes<B: ByteOrder>(bytes: &[u8]) -> Self;
}
impl OrderBytes for u8 {
fn from_bytes<B: ByteOrder>(bytes: &[u8]) -> u8 {
*bytes.first().unwrap()
}
}
impl OrderBytes for i8 {
fn from_bytes<B: ByteOrder>(bytes: &[u8]) -> i8 {
let b: *const u8 = bytes.first().unwrap();
unsafe { *(b as *const i8) }
}
}
macro_rules! order_bytes_impl {
($int_type:ident, $reader_fn:ident) => {
impl OrderBytes for $int_type {
fn from_bytes<B: ByteOrder>(bytes: &[u8]) -> $int_type {
B::$reader_fn(bytes)
}
}
}
}
order_bytes_impl!(u16, read_u16);
order_bytes_impl!(i16, read_i16);
order_bytes_impl!(u32, read_u32);
order_bytes_impl!(i32, read_i32);
order_bytes_impl!(u64, read_u64);
order_bytes_impl!(i64, read_i64);
order_bytes_impl!(f32, read_f32);
order_bytes_impl!(f64, read_f64);
Is there something already out there that does this?