Repository: zopfli-rs/zopfli (language: rust)

Issue:
DeflateEncoder should own its Options
I'm having difficulty integrating DeflateEncoder into https://github.com/Pr0methean/zip-next/ because of its lifetime parameter and the fact that it borrows Options. ZipWriter and its compression-algorithm-specific delegate GenericZipWriter both own all their members, so there isn't a natural choice of lifetime. Why not just let DeflateEncoder own the Options?


Discussion / hints:

Fix patch:
diff --git a/src/deflate.rs b/src/deflate.rs
index d38205f..0c30b6c 100644
--- a/src/deflate.rs
+++ b/src/deflate.rs
@@ -30,8 +30,8 @@ use crate::{
 /// dealt with by wrapping this encoder with a [`BufWriter`](std::io::BufWriter). An
 /// adequate write size would be >32 KiB, which allows the second complete chunk to
 /// leverage a full-sized backreference window.
-pub struct DeflateEncoder<'opts, W: Write> {
-    options: &'opts Options,
+pub struct DeflateEncoder<W: Write> {
+    options: Options,
     btype: BlockType,
     have_chunk: bool,
     chunk_start: usize,
@@ -39,10 +39,10 @@ pub struct DeflateEncoder<'opts, W: Write> {
     bitwise_writer: Option<BitwiseWriter<W>>,
 }
 
-impl<'opts, W: Write> DeflateEncoder<'opts, W> {
+impl<W: Write> DeflateEncoder<W> {
     /// Creates a new Zopfli DEFLATE encoder that will operate according to the
     /// specified options.
-    pub fn new(options: &'opts Options, btype: BlockType, sink: W) -> Self {
+    pub fn new(options: Options, btype: BlockType, sink: W) -> Self {
         DeflateEncoder {
             options,
             btype,
@@ -71,7 +71,7 @@ impl<'opts, W: Write> DeflateEncoder<'opts, W> {
     #[inline]
     fn compress_chunk(&mut self, is_last: bool) -> Result<(), Error> {
         deflate_part(
-            self.options,
+            &self.options,
             self.btype,
             is_last,
             &self.window_and_chunk,
@@ -121,7 +121,7 @@ impl<'opts, W: Write> DeflateEncoder<'opts, W> {
     }
 }
 
-impl<W: Write> Write for DeflateEncoder<'_, W> {
+impl<W: Write> Write for DeflateEncoder<W> {
     fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
         // Any previous chunk is known to be non-last at this point,
         // so compress it now
@@ -141,7 +141,7 @@ impl<W: Write> Write for DeflateEncoder<'_, W> {
     }
 }
 
-impl<W: Write> Drop for DeflateEncoder<'_, W> {
+impl<W: Write> Drop for DeflateEncoder<W> {
     fn drop(&mut self) {
         self._finish().ok();
     }
@@ -168,7 +168,7 @@ pub fn deflate<R: std::io::Read, W: Write>(
     // which is necessary for decent performance and good compression ratio
     let mut deflater = std::io::BufWriter::with_capacity(
         ZOPFLI_MASTER_BLOCK_SIZE,
-        DeflateEncoder::new(options, btype, out),
+        DeflateEncoder::new(options.clone(), btype, out),
     );
 
     std::io::copy(&mut in_data, &mut deflater)?;
@@ -1390,7 +1390,7 @@ mod test {
 
         let default_options = Options::default();
         let mut encoder =
-            DeflateEncoder::new(&default_options, BlockType::default(), &mut compressed_data);
+            DeflateEncoder::new(default_options, BlockType::default(), &mut compressed_data);
 
         encoder.write_all(&[0]).unwrap();
         encoder.write_all(&[]).unwrap();
diff --git a/src/lib.rs b/src/lib.rs
index 9abe16a..0f5e134 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -164,7 +164,7 @@ mod test {
         ) {
             let mut compressed_data = Vec::with_capacity(data.len());
 
-            let mut encoder = DeflateEncoder::new(&options, btype, &mut compressed_data);
+            let mut encoder = DeflateEncoder::new(options, btype, &mut compressed_data);
             io::copy(&mut &*data, &mut encoder).unwrap();
             encoder.finish().unwrap();
 


Test patch: