use std::cell::RefCell;
use std::fmt;
use std::io::Read;
use std::rc::Rc;
use crate::bottle_error::BottleResult;
pub trait ReadStream: fmt::Debug + Read {
fn finish(&mut self) -> BottleResult<()>;
}
#[derive(Clone, Debug)]
pub struct ReadStreamRef {
pub streaming_bottle: Rc<RefCell<dyn ReadStream>>,
}
impl ReadStreamRef {
pub fn new(streaming_bottle: Rc<RefCell<dyn ReadStream>>) -> ReadStreamRef {
ReadStreamRef { streaming_bottle }
}
pub fn finish(&mut self) -> BottleResult<()> {
self.streaming_bottle.borrow_mut().finish()
}
}
impl Read for ReadStreamRef {
fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
self.streaming_bottle.borrow_mut().read(buffer)
}
}
impl ReadStream for ReadStreamRef {
fn finish(&mut self) -> BottleResult<()> {
self.streaming_bottle.borrow_mut().finish()
}
}
pub trait StreamBottle {
fn stream(self) -> ReadStreamRef;
}
pub struct WrappedRead<R: Read> {
reader: R
}
impl<R: Read> WrappedRead<R> {
pub fn new(reader: R) -> WrappedRead<R> {
WrappedRead { reader }
}
}
impl<R: Read> fmt::Debug for WrappedRead<R> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "WrappedRead(<io::Read>)")
}
}
impl<R: Read + 'static> StreamBottle for WrappedRead<R> {
fn stream(self) -> ReadStreamRef {
ReadStreamRef::new(Rc::new(RefCell::new(self)))
}
}
impl<R: Read> ReadStream for WrappedRead<R> {
fn finish(&mut self) -> BottleResult<()> {
Ok(())
}
}
impl<R: Read> Read for WrappedRead<R> {
fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
self.reader.read(buffer)
}
}
pub fn drain_stream<R: Read>(mut reader: R, max_capture: usize) -> std::io::Result<(usize, Option<Vec<u8>>)> {
let mut byte_count = 0;
let mut buffer = vec![0u8; 0x1_0000];
let mut captured = Vec::new();
loop {
let n = reader.read(&mut buffer)?;
if n == 0 {
return Ok((byte_count, (byte_count <= max_capture).then_some(captured)));
}
byte_count += n;
if captured.len() < max_capture {
let remain = max_capture - captured.len();
captured.extend_from_slice(&buffer[.. std::cmp::max(remain, n)]);
}
}
}