# Zipit [![crates.io](https://img.shields.io/crates/v/zipit.svg)](https://crates.io/crates/zipit) [![Documentation](https://docs.rs/zipit/badge.svg)](https://docs.rs/zipit) 🗄️ Create and stream a zip archive into an AsyncWrite 🗄️ ``` zipit = "0.3" ``` ## Features - Stream on the fly an archive from multiple AsyncRead objects. - Single read / seek free implementation (the CRC and file size are calculated while streaming and are sent afterwards). - Archive size pre-calculation (useful if you want to set the `Content-Length` before streaming). - [futures](https://docs.rs/futures/latest/futures/) and [tokio](https://docs.rs/tokio/latest/tokio/io/index.html) `AsyncRead` / `AsyncWrite` compatible. Enable either the `futures-async-io` or the `tokio-async-io` feature accordingly. ## Limitations - No compression (stored method only). - Only files (no directories). - No customizable external file attributes. ## Examples ### [File system](examples/fs.rs) Write a zip archive to the file system using [`tokio::fs::File`](https://docs.rs/tokio/1.13.0/tokio/fs/struct.File.html): ```rust use std::io::Cursor; use tokio::fs::File; use zipit::{Archive, FileDateTime}; #[tokio::main] async fn main() { let file = File::create("archive.zip").await.unwrap(); let mut archive = Archive::new(file); archive.append( "file1.txt".to_owned(), FileDateTime::now(), &mut Cursor::new(b"hello\n".to_vec()), ).await.unwrap(); archive.append( "file2.txt".to_owned(), FileDateTime::now(), &mut Cursor::new(b"world\n".to_vec()), ).await.unwrap(); archive.finalize().await.unwrap(); } ``` ### [Hyper](examples/hyper.rs) Stream a zip archive as a [`hyper`](https://docs.rs/hyper/0.14.14/hyper/) response: ```rust use std::io::Cursor; use hyper::{header, Body, Request, Response, Server, StatusCode}; use tokio::io::duplex; use tokio_util::io::ReaderStream; use zipit::{archive_size, Archive, FileDateTime}; async fn zip_archive(_req: Request
) -> Result