Repository: pola-rs/polars
File: crates/polars-io/src/utils/file.rs (Rust)

Code before:

        match self {
            Self::Dyn(mut v) => v.close(),
            Self::Local(v) => close_file(v),
            #[cfg(feature = "cloud")]
            Self::Cloud(mut v) => v.close(),
        }
    }
}

impl io::Write for Writeable {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match self {
            Self::Dyn(v) => v.write(buf),
            Self::Local(v) => v.write(buf),
            #[cfg(feature = "cloud")]
            Self::Cloud(v) => v.write(buf),
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        self.sync_all()
    }
}

impl WriteableTrait for Writeable {
    fn close(&mut self) -> std::io::Result<()> {
        self.sync_all()?;

        match std::mem::replace(self, Self::Dyn(Box::new(EmptyTakenWriter))) {
            Self::Dyn(mut v) => v.close(),
            Self::Local(v) => close_file(v),
            #[cfg(feature = "cloud")]
            Self::Cloud(mut v) => v.close(),
        }
    }

    fn sync_all(&self) -> std::io::Result<()> {
        self.sync_all()
    }

    fn sync_data(&self) -> std::io::Result<()> {
        self.sync_data()
    }
}

struct EmptyTakenWriter;

impl io::Write for EmptyTakenWriter {
    fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
        unreachable!()

Review comment (suggestion):
I'd really prefer we didn't add all of these additional trait impls on `Writeable` and on the encoder of each compression type. Could we take the same approach being used for `BufferedWriteable`, i.e. taking a `&mut dyn Write + Send` -

```rust
pub enum CompressedWriteable<'a> {
    Gzip(flate2::write::GzEncoder<&'a mut (dyn std::io::Write + Send)>),
    Zstd(zstd::Encoder<'static, &'a mut (dyn std::io::Write + Send)>),
}

impl<'a> Deref for CompressedWriteable<'a> {
    type Target = dyn io::Write + Send + 'a;

    fn deref(&self) -> &Self::Target {
        match self {
            Self::Gzip(v) => v,
            Self::Zstd(v) => v as _,
        }
    }
}

impl DerefMut for CompressedWriteable<'_> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self {
            Self::Gzip(v) => v,
            Self::Zstd(v) => v as _,
        }
    }
}
```


Code after:

        match self {
            Self::Dyn(mut v) => v.close(),
            Self::Local(v) => close_file(v),
            #[cfg(feature = "cloud")]
            Self::Cloud(mut v) => v.close(),
        }
    }
}

impl io::Write for Writeable {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match self {
            Self::Dyn(v) => v.write(buf),
            Self::Local(v) => v.write(buf),
            #[cfg(feature = "cloud")]
            Self::Cloud(v) => v.write(buf),
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        self.sync_all()
    }
}

impl Deref for Writeable {
    type Target = dyn io::Write + Send;

    fn deref(&self) -> &Self::Target {
        match self {
            Self::Dyn(v) => v,
            Self::Local(v) => v,
            #[cfg(feature = "cloud")]
            Self::Cloud(v) => v,
        }
    }
}

impl DerefMut for Writeable {
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self {
            Self::Dyn(v) => v,
            Self::Local(v) => v,
            #[cfg(feature = "cloud")]
            Self::Cloud(v) => v,
        }
    }
}

/// Avoid BufWriter wrapping on writers that already have internal buffering.
pub enum BufferedWriteable<'a> {