From a04b2cda0bf2f6f8c5c0a483b8f3356bde1cbd80 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 29 Jun 2018 22:46:20 +0200 Subject: [PATCH 1/2] Provide `{to,from}_{ne,le,be}_bytes` functions on integers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If one doesn't view integers as containers of bytes, converting them to bytes necessarily needs the specfication of encoding. I think Rust is a language that wants to be explicit. The `to_bytes` function is basically the opposite of that – it converts an integer into the native byte representation, but there's no mention (in the function name) of it being very much platform dependent. Therefore, I think it would be better to replace that method by three methods, the explicit `to_ne_bytes` ("native endian") which does the same thing and `to_{le,be}_bytes` which return the little- resp. big-endian encoding. --- src/libcore/num/mod.rs | 100 +++++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 14 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 3bc2861460e14..09ffe4ef61eb8 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1892,47 +1892,119 @@ $EndFeature, " pub fn is_negative(self) -> bool { self < 0 } } - /// Return the memory representation of this integer as a byte array. + /// Return the memory representation of this integer as a byte array in + /// big-endian (network) byte order. /// - /// The target platform’s native endianness is used. - /// Portable code likely wants to use this after [`to_be`] or [`to_le`]. + /// # Examples /// - /// [`to_be`]: #method.to_be - /// [`to_le`]: #method.to_le + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let bytes = 0x12345678i32.to_be_bytes(); + /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[inline] + pub fn to_be_bytes(self) -> [u8; mem::size_of::()] { + self.to_be().to_ne_bytes() + } + + /// Return the memory representation of this integer as a byte array in + /// little-endian byte order. + /// + /// # Examples + /// + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let bytes = 0x12345678i32.to_le_bytes(); + /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[inline] + pub fn to_le_bytes(self) -> [u8; mem::size_of::()] { + self.to_le().to_ne_bytes() + } + + /// Return the memory representation of this integer as a byte array in + /// native byte order. + /// + /// As the target platform's native endianness is used, portable code + /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, + /// instead. + /// + /// [`to_be_bytes`]: #method.to_be_bytes + /// [`to_le_bytes`]: #method.to_le_bytes /// /// # Examples /// /// ``` /// #![feature(int_to_from_bytes)] /// - /// let bytes = i32::min_value().to_be().to_bytes(); + /// let bytes = i32::min_value().to_be().to_ne_bytes(); /// assert_eq!(bytes, [0x80, 0, 0, 0]); /// ``` #[unstable(feature = "int_to_from_bytes", issue = "49792")] #[inline] - pub fn to_bytes(self) -> [u8; mem::size_of::()] { + pub fn to_ne_bytes(self) -> [u8; mem::size_of::()] { unsafe { mem::transmute(self) } } - /// Create an integer value from its memory representation as a byte array. + /// Create an integer value from its representation as a byte array in + /// big endian. /// - /// The target platform’s native endianness is used. - /// Portable code likely wants to use [`from_be`] or [`from_le`] after this. + /// # Examples + /// + /// ``` + /// #![feature(int_to_from_bytes)] /// - /// [`from_be`]: #method.from_be - /// [`from_le`]: #method.from_le + /// let int = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]); + /// assert_eq!(int, 0x12_34_56_78); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[inline] + pub fn from_be_bytes(bytes: [u8; mem::size_of::()]) -> Self { + Self::from_be(Self::from_ne_bytes(bytes)) + } + + /// Create an integer value from its representation as a byte array in + /// little endian. /// /// # Examples /// /// ``` /// #![feature(int_to_from_bytes)] /// - /// let int = i32::from_be(i32::from_bytes([0x80, 0, 0, 0])); + /// let int = i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]); + /// assert_eq!(int, 0x78_56_34_12); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[inline] + pub fn from_le_bytes(bytes: [u8; mem::size_of::()]) -> Self { + Self::from_le(Self::from_ne_bytes(bytes)) + } + + /// Create an integer value from its memory representation as a byte + /// array in native endianness. + /// + /// As the target platform's native endianness is used, portable code + /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as + /// appropriate instead. + /// + /// [`from_be_bytes`]: #method.from_be_bytes + /// [`from_le_bytes`]: #method.from_le_bytes + /// + /// # Examples + /// + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let int = i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0])); /// assert_eq!(int, i32::min_value()); /// ``` #[unstable(feature = "int_to_from_bytes", issue = "49792")] #[inline] - pub fn from_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub fn from_ne_bytes(bytes: [u8; mem::size_of::()]) -> Self { unsafe { mem::transmute(bytes) } } } From 0ddfae5ba2d0104a33f3a7162571b761458f0464 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Sat, 4 Aug 2018 08:36:54 +0200 Subject: [PATCH 2/2] Change tracking issue from #49792 to #51919 The old issue has already been in FCP, a new issue was opened for the new API. --- src/libcore/num/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 09ffe4ef61eb8..6e2fbf6f84f0f 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1903,7 +1903,7 @@ $EndFeature, " /// let bytes = 0x12345678i32.to_be_bytes(); /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn to_be_bytes(self) -> [u8; mem::size_of::()] { self.to_be().to_ne_bytes() @@ -1920,7 +1920,7 @@ $EndFeature, " /// let bytes = 0x12345678i32.to_le_bytes(); /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn to_le_bytes(self) -> [u8; mem::size_of::()] { self.to_le().to_ne_bytes() @@ -1944,7 +1944,7 @@ $EndFeature, " /// let bytes = i32::min_value().to_be().to_ne_bytes(); /// assert_eq!(bytes, [0x80, 0, 0, 0]); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn to_ne_bytes(self) -> [u8; mem::size_of::()] { unsafe { mem::transmute(self) } @@ -1961,7 +1961,7 @@ $EndFeature, " /// let int = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]); /// assert_eq!(int, 0x12_34_56_78); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn from_be_bytes(bytes: [u8; mem::size_of::()]) -> Self { Self::from_be(Self::from_ne_bytes(bytes)) @@ -1978,7 +1978,7 @@ $EndFeature, " /// let int = i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]); /// assert_eq!(int, 0x78_56_34_12); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn from_le_bytes(bytes: [u8; mem::size_of::()]) -> Self { Self::from_le(Self::from_ne_bytes(bytes)) @@ -2002,7 +2002,7 @@ $EndFeature, " /// let int = i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0])); /// assert_eq!(int, i32::min_value()); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn from_ne_bytes(bytes: [u8; mem::size_of::()]) -> Self { unsafe { mem::transmute(bytes) } @@ -3589,7 +3589,7 @@ $EndFeature, " /// let bytes = 0x1234_5678_u32.to_be().to_bytes(); /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn to_bytes(self) -> [u8; mem::size_of::()] { unsafe { mem::transmute(self) } @@ -3611,7 +3611,7 @@ $EndFeature, " /// let int = u32::from_be(u32::from_bytes([0x12, 0x34, 0x56, 0x78])); /// assert_eq!(int, 0x1234_5678_u32); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn from_bytes(bytes: [u8; mem::size_of::()]) -> Self { unsafe { mem::transmute(bytes) }