git_internal/
utils.rs

1use crate::hash::SHA1;
2use std::io;
3use std::io::{BufRead, Read};
4
5pub fn read_bytes(file: &mut impl Read, len: usize) -> io::Result<Vec<u8>> {
6    let mut buf = vec![0; len];
7    file.read_exact(&mut buf)?;
8    Ok(buf)
9}
10
11pub fn read_sha1(file: &mut impl Read) -> io::Result<SHA1> {
12    SHA1::from_stream(file)
13}
14
15/// A lightweight wrapper that counts bytes read from the underlying reader.
16/// replace deflate.intotal() in decompress_data
17pub struct CountingReader<R> {
18    pub inner: R,
19    pub bytes_read: u64,
20}
21
22impl<R> CountingReader<R> {
23    /// Creates a new `CountingReader` wrapping the given reader.
24    pub fn new(inner: R) -> Self {
25        Self {
26            inner,
27            bytes_read: 0,
28        }
29    }
30}
31
32impl<R: Read> Read for CountingReader<R> {
33    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
34        let n = self.inner.read(buf)?;
35        self.bytes_read += n as u64;
36        Ok(n)
37    }
38}
39
40impl<R: BufRead> BufRead for CountingReader<R> {
41    fn fill_buf(&mut self) -> io::Result<&[u8]> {
42        self.inner.fill_buf()
43    }
44
45    fn consume(&mut self, amt: usize) {
46        self.bytes_read += amt as u64;
47        self.inner.consume(amt);
48    }
49}