Skip to content

Add impls for all of the builtin traits to LittleEndian and BigEndian and make ByteOrder also require those impls #52

@fitzgen

Description

@fitzgen

Right now, making something compile-time generic over endianness is a huge pain:

extern crate byteorder;
use byteorder::{ByteOrder, LittleEndian};

use std::marker::PhantomData;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct EndianBuf<'a, Endian>(&'a [u8], PhantomData<Endian>) where Endian: ByteOrder;

impl<'a, Endian> EndianBuf<'a, Endian> where Endian: ByteOrder {
    fn new(buf: &'a [u8]) -> EndianBuf<'a, Endian> {
        EndianBuf(buf, PhantomData)
    }
}

fn main() {
    let buf = [1,2,3,4,5,6];

    let a = EndianBuf::<LittleEndian>::new(&buf);
    let b = EndianBuf::<LittleEndian>::new(&buf);

    // Compiler error regarding this line!
    assert_eq!(a, b);
}

If you do rustc -Z unstable-options --pretty expanded endian_buf.rs, you will see this:

#[automatically_derived]
#[allow(unused_qualifications)]
impl <'a, Endian: ::std::clone::Clone> ::std::clone::Clone for EndianBuf<'a, Endian>
    where Endian: ByteOrder 
{
    // ...snip...
}

The derived impls require that the type traits also implement the trait.

If ByteOrder implied Eq, Clone, Copy, etc... the problems would go away. Arguably, this is a bug in the #[derive(Foo)] expansion code for not understanding PhantomData, but adding this would work around that bug.

Since one can't even instantiate BigEndian or LittleEndian, all the impls could be unreachable!().

Would you be willing to accept a patch that does this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions