puzzlefs_lib/compression/
noop.rs

1use crate::compression::{Compression, Compressor, Decompressor};
2use std::io;
3use std::io::{Read, Seek, Write};
4
5pub struct Noop {}
6
7pub struct NoopCompressor<W: Write> {
8    encoder: Box<W>,
9}
10
11impl<W: Write> io::Write for NoopCompressor<W> {
12    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
13        self.encoder.write(buf)
14    }
15
16    fn flush(&mut self) -> io::Result<()> {
17        self.encoder.flush()
18    }
19}
20
21impl<W: Write> Compressor for NoopCompressor<W> {
22    fn end(self: Box<Self>) -> io::Result<()> {
23        Ok(())
24    }
25}
26
27pub struct NoopDecompressor<R: Read + Seek> {
28    decoder: Box<R>,
29}
30
31impl<R: Read + io::Seek> Seek for NoopDecompressor<R> {
32    fn seek(&mut self, offset: io::SeekFrom) -> io::Result<u64> {
33        self.decoder.seek(offset)
34    }
35}
36
37impl<R: Read + Seek> Read for NoopDecompressor<R> {
38    fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
39        self.decoder.read(out)
40    }
41}
42
43impl<R: Read + Seek> Decompressor for NoopDecompressor<R> {
44    fn get_uncompressed_length(&mut self) -> io::Result<u64> {
45        self.decoder.stream_len()
46    }
47}
48
49impl Compression for Noop {
50    fn compress<'a, W: std::io::Write + 'a>(dest: W) -> io::Result<Box<dyn Compressor + 'a>> {
51        Ok(Box::new(NoopCompressor {
52            encoder: Box::new(dest),
53        }))
54    }
55
56    fn decompress<'a, R: std::io::Read + Seek + 'a>(
57        source: R,
58    ) -> io::Result<Box<dyn Decompressor + 'a>> {
59        Ok(Box::new(NoopDecompressor {
60            decoder: Box::new(source),
61        }))
62    }
63
64    fn append_extension(media_type: &str) -> String {
65        media_type.to_string()
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::compression::tests::{compress_decompress, compression_is_seekable, TRUTH};
73    use std::fs;
74    use tempfile::NamedTempFile;
75
76    #[test]
77    fn test_noop_roundtrip() -> anyhow::Result<()> {
78        compress_decompress::<Noop>()
79    }
80
81    #[test]
82    fn test_noop_seekable() -> anyhow::Result<()> {
83        compression_is_seekable::<Noop>()
84    }
85
86    #[test]
87    fn test_noop_is_noop() -> anyhow::Result<()> {
88        // shouldn't mangle the file content if in no-op mode
89        let f = NamedTempFile::new()?;
90        Noop::compress(f.reopen()?)?.write_all(TRUTH.as_bytes())?;
91
92        let content = fs::read_to_string(f.path())?;
93        assert_eq!(TRUTH, content);
94        Ok(())
95    }
96}