wolfpack 0.3.1

A package manager and a build tool that supports major package formats (deb, RPM, ipk, pkg, MSIX).
Documentation
use std::io::Error;
use std::io::Write;
use std::path::PathBuf;

use crate::sign::Signer;

pub struct SignatureWriter<S: Signer, W: Write> {
    writer: W,
    signer: S,
    signature_file: PathBuf,
    buffer: Vec<u8>,
    signed: bool,
}

impl<S: Signer, W: Write> SignatureWriter<S, W> {
    pub fn new(writer: W, signer: S, signature_file: PathBuf) -> Self {
        Self {
            writer,
            signer,
            signature_file,
            buffer: Default::default(),
            signed: false,
        }
    }

    pub fn write_signature(mut self) -> Result<(), Error> {
        self.do_write_signature()
    }

    fn do_write_signature(&mut self) -> Result<(), Error> {
        if self.signed {
            return Ok(());
        }
        let signature = self
            .signer
            .sign(&self.buffer[..])
            .map_err(|_| std::io::Error::other("failed to sign"))?;
        fs_err::write(self.signature_file.as_path(), signature)?;
        self.signed = true;
        Ok(())
    }
}

impl<S: Signer, W: Write> Write for SignatureWriter<S, W> {
    fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
        let n = self.writer.write(buf)?;
        self.buffer.extend_from_slice(&buf[..n]);
        Ok(n)
    }

    fn flush(&mut self) -> Result<(), Error> {
        self.writer.flush()
    }
}

impl<S: Signer, W: Write> Drop for SignatureWriter<S, W> {
    fn drop(&mut self) {
        let _ = self.do_write_signature();
    }
}