num-traits
num-traits copied to clipboard
IDEA: A definition of `FromBytes`/`ToBytes` that uses an associated constant instead of an associated type
(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.
I think this issue is the one to keep an eye on for enabling this and similar patterns that use traits' associated constants as const generic parameters: https://github.com/rust-lang/rust-project-goals/issues/100
Note that types like BigInt and BigUint cannot specify a fixed NUM_BYTES at all, and they currently implement these traits from [u8] and to Vec<u8>.