git-internal 0.8.4

High-performance Rust library for Git internal objects, Pack files, and AI-assisted development objects (Intent, Plan, Task, Run, Evidence, Decision) with delta compression, streaming I/O, and smart protocol support.
Documentation
//! Simple channel-backed `BufRead` adapter so pack decoding can consume data streamed from async
//! tasks or background threads.

use std::{
    io::{self, BufRead, Read},
    sync::mpsc::Receiver,
};

/// Custom BufRead implementation that reads from the channel
pub(crate) struct StreamBufReader {
    receiver: Receiver<Vec<u8>>,
    buffer: io::Cursor<Vec<u8>>,
}

impl StreamBufReader {
    pub(crate) fn new(receiver: Receiver<Vec<u8>>) -> Self {
        StreamBufReader {
            receiver,
            buffer: io::Cursor::new(Vec::new()),
        }
    }
}

impl Read for StreamBufReader {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if self.buffer.position() as usize == self.buffer.get_ref().len() {
            // buffer has been read completely
            match self.receiver.recv() {
                Ok(data) => {
                    self.buffer = io::Cursor::new(data);
                }
                Err(_) => return Ok(0), // Channel is closed
            }
        }
        self.buffer.read(buf)
    }
}

impl BufRead for StreamBufReader {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        if self.buffer.position() as usize == self.buffer.get_ref().len() {
            match self.receiver.recv() {
                Ok(data) => {
                    self.buffer = io::Cursor::new(data);
                }
                Err(_) => return Ok(&[]), // Channel is closed
            }
        }
        self.buffer.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.buffer.consume(amt);
    }
}