git_internal/internal/pack/
wrapper.rs1use std::io::{self, BufRead, Read};
2
3use sha1::{Digest, Sha1};
4
5use crate::hash::{HashKind, ObjectHash, get_hash_kind};
6use crate::utils::HashAlgorithm;
7pub struct Wrapper<R> {
17 inner: R,
18 hash: HashAlgorithm,
19 bytes_read: usize,
20}
21
22impl<R> Wrapper<R>
23where
24 R: BufRead,
25{
26 pub fn new(inner: R) -> Self {
32 Self {
33 inner,
34 hash: match get_hash_kind() {
35 HashKind::Sha1 => HashAlgorithm::Sha1(Sha1::new()),
36 HashKind::Sha256 => HashAlgorithm::Sha256(sha2::Sha256::new()),
37 }, bytes_read: 0,
39 }
40 }
41
42 pub fn bytes_read(&self) -> usize {
43 self.bytes_read
44 }
45
46 pub fn final_hash(&self) -> ObjectHash {
50 match &self.hash.clone() {
51 HashAlgorithm::Sha1(hasher) => {
52 let re: [u8; 20] = hasher.clone().finalize().into(); ObjectHash::from_bytes(&re).unwrap()
54 }
55 HashAlgorithm::Sha256(hasher) => {
56 let re: [u8; 32] = hasher.clone().finalize().into(); ObjectHash::from_bytes(&re).unwrap()
58 }
59 }
60 }
61}
62
63impl<R> BufRead for Wrapper<R>
64where
65 R: BufRead,
66{
67 fn fill_buf(&mut self) -> io::Result<&[u8]> {
69 self.inner.fill_buf() }
71
72 fn consume(&mut self, amt: usize) {
77 let buffer = self.inner.fill_buf().expect("Failed to fill buffer");
78 match &mut self.hash {
79 HashAlgorithm::Sha1(hasher) => hasher.update(&buffer[..amt]), HashAlgorithm::Sha256(hasher) => hasher.update(&buffer[..amt]), }
82 self.inner.consume(amt); self.bytes_read += amt;
84 }
85}
86
87impl<R> Read for Wrapper<R>
88where
89 R: BufRead,
90{
91 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
100 let o = self.inner.read(buf)?; match &mut self.hash {
102 HashAlgorithm::Sha1(hasher) => hasher.update(&buf[..o]), HashAlgorithm::Sha256(hasher) => hasher.update(&buf[..o]), }
105 self.bytes_read += o;
106 Ok(o) }
108}
109
110#[cfg(test)]
111mod tests {
112 use std::io::{self, BufReader, Cursor, Read};
113
114 use sha1::{Digest, Sha1};
115
116 use crate::hash::{HashKind, set_hash_kind};
117 use crate::internal::pack::wrapper::Wrapper;
118 #[test]
119 fn test_wrapper_read() -> io::Result<()> {
120 let _guard = set_hash_kind(HashKind::Sha1);
121 let data = b"Hello, world!"; let cursor = Cursor::new(data.as_ref());
123 let buf_reader = BufReader::new(cursor);
124 let mut wrapper = Wrapper::new(buf_reader);
125
126 let mut buffer = vec![0; data.len()];
127 wrapper.read_exact(&mut buffer)?;
128
129 assert_eq!(buffer, data);
130 Ok(())
131 }
132 #[test]
133 fn test_wrapper_read_sha256() -> io::Result<()> {
134 let _guard = set_hash_kind(HashKind::Sha256);
135 let data = b"Hello, world!"; let cursor = Cursor::new(data.as_ref());
137 let buf_reader = BufReader::new(cursor);
138 let mut wrapper = Wrapper::new(buf_reader);
139
140 let mut buffer = vec![0; data.len()];
141 wrapper.read_exact(&mut buffer)?;
142
143 assert_eq!(buffer, data);
144 Ok(())
145 }
146
147 #[test]
148 fn test_wrapper_hash() -> io::Result<()> {
149 let _guard = set_hash_kind(HashKind::Sha1);
150 let data = b"Hello, world!";
151 let cursor = Cursor::new(data.as_ref());
152 let buf_reader = BufReader::new(cursor);
153 let mut wrapper = Wrapper::new(buf_reader);
154
155 let mut buffer = vec![0; data.len()];
156 wrapper.read_exact(&mut buffer)?;
157
158 let hash_result = wrapper.final_hash();
159 let mut hasher = Sha1::new();
160 hasher.update(data);
161 let expected_hash: [u8; 20] = hasher.finalize().into();
162
163 assert_eq!(hash_result.as_ref(), expected_hash);
164 Ok(())
165 }
166 #[test]
167 fn test_wrapper_hash_sha256() -> io::Result<()> {
168 let _guard = set_hash_kind(HashKind::Sha256);
169 let data = b"Hello, world!";
170 let cursor = Cursor::new(data.as_ref());
171 let buf_reader = BufReader::new(cursor);
172 let mut wrapper = Wrapper::new(buf_reader);
173
174 let mut buffer = vec![0; data.len()];
175 wrapper.read_exact(&mut buffer)?;
176
177 let hash_result = wrapper.final_hash();
178 let mut hasher = sha2::Sha256::new();
179 hasher.update(data);
180 let expected_hash: [u8; 32] = hasher.finalize().into();
181
182 assert_eq!(hash_result.as_ref(), &expected_hash);
183 Ok(())
184 }
185}