Skip to content

IDEA: A definition of FromBytes/ToBytes that uses an associated constant instead of an associated type #358

Open
@SuperSamus

Description

@SuperSamus

(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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions