Skip to content

Tracking issue for the to_bytes and from_bytes methods of integers #49792

Description

@SimonSapin

This tracks the stabilization of two methods on each primitive integer type, added in PR #49871:

impl $Int {
    pub fn to_bytes(self) -> [u8; mem::size_of::<Self>()] {
        unsafe { mem::transmute(self) }
    }
    pub fn from_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
        unsafe { mem::transmute(bytes) }
    }
}

Previous issue message:


I’d like to propose adding to the standard library between various integer types $Int and byte arrays [u8; size_of::<$Int>()] (which by the way is literally a valid type today). The implementation would be exactly transmute, but since the signature is much more restricted and all bit patterns are valid for each of the types involved, these conversions are safe.

Transmuting produces arrays with the target platform’s endianness. When something different is desired, the existing to_be/to_le/from_be/from_le methods can be combined with these new conversions. Keeping these concerns orthogonal (instead of multiplying ad-hoc conversions) allows to keep the API surface small.

Wrapping specific forms of transmute into safe APIs makes good candidates for the standard library IMO since they can save users from needing writing (and reviewing and maintaining) unsafe code themselves. See Box::into_raw for example. Together with the existing {to,from}_{be,le} methods and TryFrom<&[T]> for &[T; $N] impls, these new conversions would cover much of the functionality of the popular byteorder crate with little code and a relatively small API surface.

What I’m less certain about (and why this isn’t a PR yet) is what API should we expose these conversions as. Options are:

  • Impls of the From trait, or
  • Named methods, similar to f32::to_bits and f32::from_bits. The advantage over From is that we can give specific names to these conversions in order to communicate what they do. The downside is that we need to pick names.
    • I initially thought of to_native_endian_bytes and from_native_endian_bytes but that’s not great because:
      • It’s somewhat inconsistent with to_be and friends which are much more abbreviated. (But maybe they shouldn’t be. It is worth adding to_big_endian & co and deprecating the short ones?)
      • It looks weird when combining them for writing portable code: n.to_be().to_native_endian(): now "native endian" is inaccurate, but that’s partly the fault of to_be for changing the meaning of a value without changing its type.
    • Another idea is simply to_bytes and from_bytes, but that’s uninformative enough that they could just as well be From impls.

@rust-lang/libs or anyone, any thoughts?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libs-api[DEPRECATED; DO NOT USE]disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions