git_internal/internal/pack/
channel_reader.rs

1use std::io::{self};
2use std::io::{BufRead, Read};
3use std::sync::mpsc::Receiver;
4
5/// Custom BufRead implementation that reads from the channel
6pub(crate) struct StreamBufReader {
7    receiver: Receiver<Vec<u8>>,
8    buffer: io::Cursor<Vec<u8>>,
9}
10
11impl StreamBufReader {
12    pub(crate) fn new(receiver: Receiver<Vec<u8>>) -> Self {
13        StreamBufReader {
14            receiver,
15            buffer: io::Cursor::new(Vec::new()),
16        }
17    }
18}
19
20impl Read for StreamBufReader {
21    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
22        if self.buffer.position() as usize == self.buffer.get_ref().len() {
23            // buffer has been read completely
24            match self.receiver.recv() {
25                Ok(data) => {
26                    self.buffer = io::Cursor::new(data);
27                }
28                Err(_) => return Ok(0), // Channel is closed
29            }
30        }
31        self.buffer.read(buf)
32    }
33}
34
35impl BufRead for StreamBufReader {
36    fn fill_buf(&mut self) -> io::Result<&[u8]> {
37        if self.buffer.position() as usize == self.buffer.get_ref().len() {
38            match self.receiver.recv() {
39                Ok(data) => {
40                    self.buffer = io::Cursor::new(data);
41                }
42                Err(_) => return Ok(&[]), // Channel is closed
43            }
44        }
45        self.buffer.fill_buf()
46    }
47
48    fn consume(&mut self, amt: usize) {
49        self.buffer.consume(amt);
50    }
51}