Description
(Note: this idea is currently only appliable on nightly, as it requires generic_const_exprs
.)
FromBytes
and ToBytes
are declared like this:
pub trait FromBytes {
type Bytes: NumBytes + ?Sized;
fn from_be_bytes(bytes: &Self::Bytes) -> Self;
// ...
}
This gives very little information to the argument/return type. All the implementations of NumBytes
in num-traits
are in the form of [u8; _]
, yet users of the library can't properly make use of it.
What the issue proposes is that these traits are implemented like this:
pub trait FromBytes {
const NUM_BYTES: usize;
fn from_be_bytes(bytes: [u8; Self::NUM_BYTES]) -> Self;
// ...
}
An example where the current definition is unwieldy is the following:
use num_traits::FromBytes;
fn first_number<T: FromBytes>(arr: &[u8]) -> T {
let bytes = arr.first_chunk().unwrap();
FromBytes::from_ne_bytes(bytes)
}
pub fn main() {
let arr = [2, 1, 0, 3 /*... */ ];
println!("{}", first_number::<u8>(&arr)); // 2
println!("{}", first_number::<u16>(&arr)); // 513
}
Which with the current definition doesn't compile.
Granted, there is a workaround, but it's pretty ugly: Rust Playground.
This would obviously be a breaking change if the current traits are changed. Maybe it would be possible to create new traits with this definition instead of replacing the existing ones?
I suppose that this is somewhat related to #294.