@@ -330,7 +330,7 @@ pub use self::{
330330 stdio:: { Stderr , StderrLock , Stdin , StdinLock , Stdout , StdoutLock , stderr, stdin, stdout} ,
331331 util:: { Empty , Repeat , Sink , empty, repeat, sink} ,
332332} ;
333- use crate :: mem:: take;
333+ use crate :: mem:: { MaybeUninit , take} ;
334334use crate :: ops:: { Deref , DerefMut } ;
335335use crate :: { cmp, fmt, slice, str, sys} ;
336336
@@ -1242,6 +1242,46 @@ pub trait Read {
12421242 {
12431243 Take { inner : self , len : limit, limit }
12441244 }
1245+
1246+ /// Read and return a fixed array of bytes from this source.
1247+ ///
1248+ /// This function uses an array sized based on a const generic size known at compile time. You
1249+ /// can specify the size with turbofish (`reader.read_array::<8>()`), or let type inference
1250+ /// determine the number of bytes needed based on how the return value gets used. For instance,
1251+ /// this function works well with functions like [`u64::from_le_bytes`] to turn an array of
1252+ /// bytes into an integer of the same size.
1253+ ///
1254+ /// Like `read_exact`, if this function encounters an "end of file" before reading the desired
1255+ /// number of bytes, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
1256+ ///
1257+ /// ```
1258+ /// #![feature(read_array)]
1259+ /// use std::io::Cursor;
1260+ /// use std::io::prelude::*;
1261+ ///
1262+ /// fn main() -> std::io::Result<()> {
1263+ /// let mut buf = Cursor::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2]);
1264+ /// let x = u64::from_le_bytes(buf.read_array()?);
1265+ /// let y = u32::from_be_bytes(buf.read_array()?);
1266+ /// let z = u16::from_be_bytes(buf.read_array()?);
1267+ /// assert_eq!(x, 0x807060504030201);
1268+ /// assert_eq!(y, 0x9080706);
1269+ /// assert_eq!(z, 0x504);
1270+ /// Ok(())
1271+ /// }
1272+ /// ```
1273+ #[ unstable( feature = "read_array" , issue = "148848" ) ]
1274+ fn read_array < const N : usize > ( & mut self ) -> Result < [ u8 ; N ] >
1275+ where
1276+ Self : Sized ,
1277+ {
1278+ let mut buf = [ MaybeUninit :: uninit ( ) ; N ] ;
1279+ let mut borrowed_buf = BorrowedBuf :: from ( buf. as_mut_slice ( ) ) ;
1280+ self . read_buf_exact ( borrowed_buf. unfilled ( ) ) ?;
1281+ // Guard against incorrect `read_buf_exact` implementations.
1282+ assert_eq ! ( borrowed_buf. len( ) , N ) ;
1283+ Ok ( unsafe { MaybeUninit :: array_assume_init ( buf) } )
1284+ }
12451285}
12461286
12471287/// Reads all bytes from a [reader][Read] into a new [`String`].
0 commit comments