rust-num / num-traits

Numeric traits for generic mathematics in Rust
Apache License 2.0
719 stars 133 forks source link

Implement IntoIterator<Item=u8> for NumBytes #294

Closed Evian-Zhang closed 12 months ago

Evian-Zhang commented 1 year ago

This PR implements IntoIterator<Item = u8> for NumBytes, since the AsRef and Borrow traits for NumBytes will have trouble with lifetime as it borrows the array.

An actual usage of this trait is when I want to convert a list of integers into bytes (i.e. flatten the generated bytes array for each integer):

fn flatten_to_bytes_array<I: ToBytes>(integers: &[I]) -> Vec<u8> {
    integers
        .iter()
        .map(|integer| integer.to_ne_bytes().into_iter())
        .flatten()
        .collect()
}

However, if I replace the into_iter with as_ref(), the borrow checker will deny the compilation since the lifetime of the array generated in to_ne_bytes() cannot live long enough. The workaround here is just as_ref().to_vec(), which involves additional heap allocations.

cuviper commented 12 months ago

Unfortunately, it's a breaking change to add new trait requirements. A 3rd-party crate could have a ToBytes or FromBytes implementation where they use a type Bytes that doesn't implement IntoIterator, or any other use of NumBytes that would now be more constrained.

Your example function could add where I::Bytes: IntoIterator<Item = u8>, but I know it's inconvenient to propagate extra bounds on associated types like that, especially because of rust-lang/rust#20671. (And BTW, flatten can handle the into_iter() call for you.)

There's also an issue that arrays didn't implement IntoIterator until Rust 1.53, so we would have to raise MSRV. That's possible, but the breaking change above is the bigger problem.

cuviper commented 12 months ago

FWIW, since you're keeping native-endian bytes -- if you're only concerned with primitive types, your particular example could also be written with bytemuck::cast_slice.

Evian-Zhang commented 12 months ago

Ok, I understood. Thank you for your kind explanation.