blob: 6a47c76a9fee4ce45b905644032c2d4c6e86411d [file] [log] [blame]
David LeGare793d84b2022-03-02 16:21:10 +00001//! `BufRead` pointer or `BufReader` owned.
2
3use std::cmp;
4use std::io;
5use std::io::BufRead;
6use std::io::BufReader;
7use std::io::Read;
8use std::mem::MaybeUninit;
9
10use crate::misc::maybe_uninit_write_slice;
11
12/// Helper type to simplify `BufReadIter` implementation.
13pub(crate) enum BufReadOrReader<'a> {
14 BufReader(BufReader<&'a mut dyn Read>),
15 BufRead(&'a mut dyn BufRead),
16}
17
18impl<'a> Read for BufReadOrReader<'a> {
19 fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
20 match self {
21 BufReadOrReader::BufReader(r) => r.read(buf),
22 BufReadOrReader::BufRead(r) => r.read(buf),
23 }
24 }
25
26 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, io::Error> {
27 match self {
28 BufReadOrReader::BufReader(r) => r.read_to_end(buf),
29 BufReadOrReader::BufRead(r) => r.read_to_end(buf),
30 }
31 }
32
33 fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), io::Error> {
34 match self {
35 BufReadOrReader::BufReader(r) => r.read_exact(buf),
36 BufReadOrReader::BufRead(r) => r.read_exact(buf),
37 }
38 }
39}
40
41impl<'a> BufReadOrReader<'a> {
42 /// Similar to `read_exact` but reads into `MaybeUninit`.
43 pub(crate) fn read_exact_uninit(
44 &mut self,
45 buf: &mut [MaybeUninit<u8>],
46 ) -> Result<(), io::Error> {
47 let mut pos = 0;
48 while pos != buf.len() {
49 let fill_buf = match self {
50 BufReadOrReader::BufReader(r) => r.fill_buf()?,
51 BufReadOrReader::BufRead(r) => r.fill_buf()?,
52 };
53 if fill_buf.is_empty() {
54 return Err(io::Error::new(
55 io::ErrorKind::UnexpectedEof,
56 "Unexpected end of file",
57 ));
58 }
59 let consume = cmp::min(fill_buf.len(), buf.len() - pos);
60 maybe_uninit_write_slice(&mut buf[pos..pos + consume], &fill_buf[..consume]);
61 match self {
62 BufReadOrReader::BufReader(r) => r.consume(consume),
63 BufReadOrReader::BufRead(r) => r.consume(consume),
64 }
65 pos += consume;
66 }
67 Ok(())
68 }
69}
70
71impl<'a> BufRead for BufReadOrReader<'a> {
72 fn fill_buf(&mut self) -> Result<&[u8], io::Error> {
73 match self {
74 BufReadOrReader::BufReader(r) => r.fill_buf(),
75 BufReadOrReader::BufRead(r) => r.fill_buf(),
76 }
77 }
78
79 fn consume(&mut self, amt: usize) {
80 match self {
81 BufReadOrReader::BufReader(r) => r.consume(amt),
82 BufReadOrReader::BufRead(r) => r.consume(amt),
83 }
84 }
85}