1use std::{
5 io,
6 io::{BufRead, Read},
7};
8
9use sha1::{Digest, Sha1};
10
11use crate::hash::{HashKind, ObjectHash, get_hash_kind};
12pub fn read_bytes(file: &mut impl Read, len: usize) -> io::Result<Vec<u8>> {
14 let mut buf = vec![0; len];
15 file.read_exact(&mut buf)?;
16 Ok(buf)
17}
18
19pub fn read_sha(file: &mut impl Read) -> io::Result<ObjectHash> {
21 ObjectHash::from_stream(file)
22}
23
24pub struct CountingReader<R> {
27 pub inner: R,
28 pub bytes_read: u64,
29}
30
31impl<R> CountingReader<R> {
32 pub fn new(inner: R) -> Self {
34 Self {
35 inner,
36 bytes_read: 0,
37 }
38 }
39}
40
41impl<R: Read> Read for CountingReader<R> {
42 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
45 let n = self.inner.read(buf)?;
46 self.bytes_read += n as u64;
47 Ok(n)
48 }
49}
50
51impl<R: BufRead> BufRead for CountingReader<R> {
52 fn fill_buf(&mut self) -> io::Result<&[u8]> {
56 self.inner.fill_buf()
57 }
58
59 fn consume(&mut self, amt: usize) {
62 self.bytes_read += amt as u64;
63 self.inner.consume(amt);
64 }
65}
66#[derive(Clone)]
70pub enum HashAlgorithm {
71 Sha1(Sha1),
72 Sha256(sha2::Sha256),
73 }
75impl HashAlgorithm {
76 pub fn update(&mut self, data: &[u8]) {
78 match self {
79 HashAlgorithm::Sha1(hasher) => hasher.update(data),
80 HashAlgorithm::Sha256(hasher) => hasher.update(data),
81 }
82 }
83 pub fn finalize(self) -> Vec<u8> {
85 match self {
86 HashAlgorithm::Sha1(hasher) => hasher.finalize().to_vec(),
87 HashAlgorithm::Sha256(hasher) => hasher.finalize().to_vec(),
88 }
89 }
90 pub fn new() -> Self {
92 match get_hash_kind() {
93 HashKind::Sha1 => HashAlgorithm::Sha1(Sha1::new()),
94 HashKind::Sha256 => HashAlgorithm::Sha256(sha2::Sha256::new()),
95 }
96 }
97}
98impl std::io::Write for HashAlgorithm {
99 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
100 self.update(buf);
101 Ok(buf.len())
102 }
103 fn flush(&mut self) -> io::Result<()> {
104 Ok(())
105 }
106}
107impl Default for HashAlgorithm {
108 fn default() -> Self {
109 Self::new()
110 }
111}