base91le 0.1.0

little-endian base91 encoding format that supports padding
Documentation
use std::io::{Result, Write};

use crate::{copier::Copier, ring::RingBuf};

#[derive(Debug)]
pub struct EncodeWriter<W: Write> {
    writer: W,
    copier: Copier,
    ring: RingBuf<1024>,
}

impl<W: Write> EncodeWriter<W> {
    pub const fn new(writer: W) -> Self {
        Self {
            writer,
            copier: Copier::new_encode(),
            ring: RingBuf::new(),
        }
    }

    pub fn finalize(&mut self) -> Result<()> {
        while !self.ring.is_empty() {
            if !self.copier.write() && self.copier.copy_from(&mut self.ring)? {
                self.copier.encode();
            }
            if self.copier.write() && self.copier.copy_to(&mut self.writer)? {
                self.copier = Copier::new_encode()
            }
        }

        if self.copier.write() {
            while !self.copier.copy_to(&mut self.writer)? {}
        } else {
            let tail = self.copier.encode_tail();
            std::io::copy(&mut tail.as_slice(), &mut self.writer)?;
        }
        Ok(())
    }
}

impl<W: Write> Write for EncodeWriter<W> {
    fn write(&mut self, mut buf: &[u8]) -> Result<usize> {
        let n = self.ring.copy_from_reader(&mut buf)?;

        if n == 0 {
            self.finalize()?;
            return Ok(0);
        }

        if !self.copier.write() && self.copier.copy_from(&mut self.ring)? {
            self.copier.encode();
        }
        if self.copier.write() && self.copier.copy_to(&mut self.writer)? {
            self.copier = Copier::new_encode()
        }
        Ok(n)
    }

    fn flush(&mut self) -> Result<()> {
        while !self.ring.is_empty() {
            if !self.copier.write() && self.copier.copy_from(&mut self.ring)? {
                self.copier.encode();
            }
            if self.copier.write() && self.copier.copy_to(&mut self.writer)? {
                self.copier = Copier::new_encode()
            }
        }

        if self.copier.write() {
            while !self.copier.copy_to(&mut self.writer)? {}
        }
        self.writer.flush()?;
        Ok(())
    }
}

impl<W: Write> Drop for EncodeWriter<W> {
    fn drop(&mut self) {
        let _ = self.finalize();
    }
}