rs-tar2zip 0.1.0

Converts a tar file to a zip file
Documentation
use core::time::Duration;

use std::time::SystemTime;

use time::OffsetDateTime;

use std::fs::File;
use std::io;

use std::path::Path;

use io::Seek;

use io::BufWriter;
use io::Write;

use io::BufRead;
use io::Read;

use zip::CompressionMethod;
use zip::ZipWriter;
use zip::write::SimpleFileOptions;

pub use tar;
pub use time;
pub use zip;

/// Adds a tar entry to the zip.
pub fn entry2zip<R, W>(entry: &mut tar::Entry<R>, zwtr: &mut ZipWriter<W>) -> Result<(), io::Error>
where
    R: Read,
    W: Write + Seek,
{
    let cpat = entry.path()?;
    let pat: &Path = &cpat;

    let hdr: &tar::Header = entry.header();
    let mtime_unixtime: u64 = hdr.mtime().ok().unwrap_or_default();
    let mtime_duration: Duration = Duration::from_secs(mtime_unixtime);

    let mtime_sys: SystemTime = SystemTime::UNIX_EPOCH
        .checked_add(mtime_duration)
        .unwrap_or(SystemTime::UNIX_EPOCH);
    let mtime_o: OffsetDateTime = mtime_sys.into();

    let opts: SimpleFileOptions = SimpleFileOptions::default()
        .compression_method(CompressionMethod::Deflated)
        .last_modified_time(mtime_o.try_into().map_err(io::Error::other)?);

    let s: &str = pat
        .as_os_str()
        .to_str()
        .ok_or(io::Error::other("invalid path"))?;
    zwtr.start_file(s, opts)?;

    io::copy(entry, zwtr)?;
    Ok(())
}

/// Adds all items in the tar archive to the zip.
pub fn tar2zip<R, W>(mut tarfile: tar::Archive<R>, mut zwtr: ZipWriter<W>) -> Result<(), io::Error>
where
    R: Read,
    W: Write + Seek,
{
    let items = tarfile.entries()?;
    for ritem in items {
        let mut item: tar::Entry<_> = ritem?;
        entry2zip(&mut item, &mut zwtr)?;
    }
    let mut w: W = zwtr.finish()?;
    w.flush()
}

/// Adds all items in the tar archive(Read) to the zip(Write).
pub fn reader2writer<R, W>(tarfile: R, mut zwtr: W) -> Result<(), io::Error>
where
    R: BufRead,
    W: Write + Seek,
{
    let ta = tar::Archive::new(tarfile);
    let bw = BufWriter::new(&mut zwtr);
    let zw = ZipWriter::new(bw);
    tar2zip(ta, zw)?;
    zwtr.flush()
}

/// Adds all items in the tar archive(stdin) to the zip(file).
pub fn stdin2file(filename: &str) -> Result<(), io::Error> {
    let i = io::stdin();
    let l = i.lock();
    let f: File = File::create(filename)?;

    reader2writer(l, f)
}