use crate::crypto::DEFAULT_CHUNK_SIZE;
use crate::progress::ProgressCallback;
use std::io::{self, Read};
pub struct Decompressor<R: Read> {
#[allow(dead_code)]
source: R,
#[allow(dead_code)]
password: Option<String>,
chunk_size: usize,
progress_callback: Option<ProgressCallback>,
finished: bool,
bytes_read: u64,
total_size: u64,
}
impl<R: Read> Decompressor<R> {
pub fn new(source: R, password: Option<&str>) -> Self {
Self {
source,
password: password.map(|p| p.to_string()),
chunk_size: DEFAULT_CHUNK_SIZE,
progress_callback: None,
finished: false,
bytes_read: 0,
total_size: 0, }
}
pub fn with_chunk_size(mut self, chunk_size: usize) -> Self {
self.chunk_size = chunk_size;
self
}
pub fn with_progress_callback<F>(mut self, callback: F) -> Self
where
F: FnMut(&crate::progress::ProgressInfo) + Send + Sync + 'static,
{
self.progress_callback = Some(Box::new(callback));
self
}
pub fn bytes_read(&self) -> u64 {
self.bytes_read
}
pub fn total_size(&self) -> u64 {
self.total_size
}
pub fn is_finished(&self) -> bool {
self.finished
}
}
impl<R: Read> Read for Decompressor<R> {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
if self.finished {
return Ok(0); }
println!("Decompressor::read() not yet fully implemented - returning dummy data");
self.finished = true;
Ok(0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::{Cursor, Read};
#[test]
fn test_decompressor_creation() {
let cursor = Cursor::new(b"dummy compressed data");
let decompressor = Decompressor::new(cursor, None);
assert!(decompressor.password.is_none());
assert_eq!(decompressor.chunk_size, DEFAULT_CHUNK_SIZE);
assert!(!decompressor.is_finished());
assert_eq!(decompressor.bytes_read(), 0);
assert_eq!(decompressor.total_size(), 0);
}
#[test]
fn test_decompressor_builder_pattern() {
let cursor = Cursor::new(b"dummy compressed data");
let decompressor = Decompressor::new(cursor, None)
.with_chunk_size(1024 * 1024)
.with_progress_callback(|_| {});
assert_eq!(decompressor.chunk_size, 1024 * 1024);
assert!(decompressor.progress_callback.is_some());
}
#[test]
fn test_decompressor_with_password() {
let cursor = Cursor::new(b"dummy compressed data");
let decompressor = Decompressor::new(cursor, Some("password"));
assert_eq!(decompressor.password, Some("password".to_string()));
}
#[test]
fn test_decompressor_read_operations() {
let cursor = Cursor::new(b"dummy compressed data");
let mut decompressor = Decompressor::new(cursor, None);
let mut buffer = [0u8; 10];
let bytes_read = decompressor.read(&mut buffer).unwrap();
assert_eq!(bytes_read, 0);
assert!(decompressor.is_finished());
}
}