use crate::read_write::{Read, Write};
use std::io::Error;
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub struct IOSimpleReader<'a, R: std::io::Read>(&'a mut R);
impl<'a, R: std::io::Read> IOSimpleReader<'a, R> {
#[inline(always)]
#[must_use]
pub fn new(stream: &'a mut R) -> IOSimpleReader<'a, R> {
IOSimpleReader(stream)
}
}
impl<'a, R: std::io::Read> Read for IOSimpleReader<'a, R> {
type Error = Error;
fn read(&mut self) -> Result<Option<u8>, Self::Error> {
let mut buf = [0; 1];
if self.0.read(&mut buf)? == 0 {
Ok(None)
} else {
Ok(Some(buf[0]))
}
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub struct IOSimpleWriter<'a, W: std::io::Write>(&'a mut W);
impl<'a, W: std::io::Write> IOSimpleWriter<'a, W> {
#[inline(always)]
#[must_use]
pub fn new(stream: &'a mut W) -> IOSimpleWriter<'a, W> {
IOSimpleWriter(stream)
}
}
impl<'a, W: std::io::Write> Write for IOSimpleWriter<'a, W> {
type Output = ();
type Error = Error;
fn write(&mut self, data: u8) -> Result<(), Self::Error> {
let buf = [data];
self.0.write_all(&buf)
}
#[inline(always)]
fn finish(self) -> Result<Self::Output, Self::Error> {
self.0.flush()
}
}
#[cfg(test)]
mod tests {
use crate::error::LzssError;
use crate::generic::Lzss;
use crate::io_simple::{IOSimpleReader, IOSimpleWriter};
use std::io::{Cursor, ErrorKind};
type TestLZSS = Lzss<10, 4, 0x20, { 1 << 10 }, { 2 << 10 }>;
const TEST_DATA: &[u8; 27] = b"Sample Data 11221233123";
#[test]
fn test_simple_io() {
let mut output = [0u8; 30];
let mut output_cursor = Cursor::new(&mut output[..]);
let output_result = TestLZSS::compress_stack(
IOSimpleReader::new(&mut Cursor::new(TEST_DATA)),
IOSimpleWriter::new(&mut output_cursor),
);
assert_eq!(
output_result.map_err(|x| x.map_read_error(|x| x.kind()).map_write_error(|x| x.kind())),
Ok(())
);
assert_eq!(output_cursor.position(), 26);
}
#[test]
fn test_simple_io_fail() {
let mut output = [0u8; 10];
let mut output_cursor = Cursor::new(&mut output[..]);
let output_result = TestLZSS::compress_stack(
IOSimpleReader::new(&mut Cursor::new(TEST_DATA)),
IOSimpleWriter::new(&mut output_cursor),
);
assert_eq!(
output_result.map_err(|x| x.map_read_error(|x| x.kind()).map_write_error(|x| x.kind())),
Err(LzssError::WriteError(ErrorKind::WriteZero))
);
}
}