Skip to content

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

@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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions