Skip to content

Commit a04b2cd

Browse files
committedAug 3, 2018
Provide {to,from}_{ne,le,be}_bytes functions on integers
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.
1 parent 7e8ca9f commit a04b2cd

File tree

1 file changed

+86
-14
lines changed

1 file changed

+86
-14
lines changed
 

‎src/libcore/num/mod.rs

+86-14
Original file line numberDiff line numberDiff line change
@@ -1892,47 +1892,119 @@ $EndFeature, "
18921892
pub fn is_negative(self) -> bool { self < 0 }
18931893
}
18941894

1895-
/// Return the memory representation of this integer as a byte array.
1895+
/// Return the memory representation of this integer as a byte array in
1896+
/// big-endian (network) byte order.
18961897
///
1897-
/// The target platform’s native endianness is used.
1898-
/// Portable code likely wants to use this after [`to_be`] or [`to_le`].
1898+
/// # Examples
18991899
///
1900-
/// [`to_be`]: #method.to_be
1901-
/// [`to_le`]: #method.to_le
1900+
/// ```
1901+
/// #![feature(int_to_from_bytes)]
1902+
///
1903+
/// let bytes = 0x12345678i32.to_be_bytes();
1904+
/// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
1905+
/// ```
1906+
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
1907+
#[inline]
1908+
pub fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
1909+
self.to_be().to_ne_bytes()
1910+
}
1911+
1912+
/// Return the memory representation of this integer as a byte array in
1913+
/// little-endian byte order.
1914+
///
1915+
/// # Examples
1916+
///
1917+
/// ```
1918+
/// #![feature(int_to_from_bytes)]
1919+
///
1920+
/// let bytes = 0x12345678i32.to_le_bytes();
1921+
/// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]);
1922+
/// ```
1923+
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
1924+
#[inline]
1925+
pub fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
1926+
self.to_le().to_ne_bytes()
1927+
}
1928+
1929+
/// Return the memory representation of this integer as a byte array in
1930+
/// native byte order.
1931+
///
1932+
/// As the target platform's native endianness is used, portable code
1933+
/// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate,
1934+
/// instead.
1935+
///
1936+
/// [`to_be_bytes`]: #method.to_be_bytes
1937+
/// [`to_le_bytes`]: #method.to_le_bytes
19021938
///
19031939
/// # Examples
19041940
///
19051941
/// ```
19061942
/// #![feature(int_to_from_bytes)]
19071943
///
1908-
/// let bytes = i32::min_value().to_be().to_bytes();
1944+
/// let bytes = i32::min_value().to_be().to_ne_bytes();
19091945
/// assert_eq!(bytes, [0x80, 0, 0, 0]);
19101946
/// ```
19111947
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
19121948
#[inline]
1913-
pub fn to_bytes(self) -> [u8; mem::size_of::<Self>()] {
1949+
pub fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
19141950
unsafe { mem::transmute(self) }
19151951
}
19161952

1917-
/// Create an integer value from its memory representation as a byte array.
1953+
/// Create an integer value from its representation as a byte array in
1954+
/// big endian.
19181955
///
1919-
/// The target platform’s native endianness is used.
1920-
/// Portable code likely wants to use [`from_be`] or [`from_le`] after this.
1956+
/// # Examples
1957+
///
1958+
/// ```
1959+
/// #![feature(int_to_from_bytes)]
19211960
///
1922-
/// [`from_be`]: #method.from_be
1923-
/// [`from_le`]: #method.from_le
1961+
/// let int = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]);
1962+
/// assert_eq!(int, 0x12_34_56_78);
1963+
/// ```
1964+
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
1965+
#[inline]
1966+
pub fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
1967+
Self::from_be(Self::from_ne_bytes(bytes))
1968+
}
1969+
1970+
/// Create an integer value from its representation as a byte array in
1971+
/// little endian.
19241972
///
19251973
/// # Examples
19261974
///
19271975
/// ```
19281976
/// #![feature(int_to_from_bytes)]
19291977
///
1930-
/// let int = i32::from_be(i32::from_bytes([0x80, 0, 0, 0]));
1978+
/// let int = i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]);
1979+
/// assert_eq!(int, 0x78_56_34_12);
1980+
/// ```
1981+
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
1982+
#[inline]
1983+
pub fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
1984+
Self::from_le(Self::from_ne_bytes(bytes))
1985+
}
1986+
1987+
/// Create an integer value from its memory representation as a byte
1988+
/// array in native endianness.
1989+
///
1990+
/// As the target platform's native endianness is used, portable code
1991+
/// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
1992+
/// appropriate instead.
1993+
///
1994+
/// [`from_be_bytes`]: #method.from_be_bytes
1995+
/// [`from_le_bytes`]: #method.from_le_bytes
1996+
///
1997+
/// # Examples
1998+
///
1999+
/// ```
2000+
/// #![feature(int_to_from_bytes)]
2001+
///
2002+
/// let int = i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0]));
19312003
/// assert_eq!(int, i32::min_value());
19322004
/// ```
19332005
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
19342006
#[inline]
1935-
pub fn from_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
2007+
pub fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
19362008
unsafe { mem::transmute(bytes) }
19372009
}
19382010
}

0 commit comments

Comments
 (0)