tokio_ar/
lib.rs

1//! A library for encoding/decoding Unix archive files.
2//!
3//! This library provides utilities necessary to manage [Unix archive
4//! files](https://en.wikipedia.org/wiki/Ar_(Unix)) (as generated by the
5//! standard `ar` command line utility) abstracted over a reader or writer.
6//! This library provides a streaming interface that avoids having to ever load
7//! a full archive entry into memory.
8//!
9//! The API of this crate is meant to be similar to that of the
10//! [`tar`](https://crates.io/crates/tar) crate, but uses async I/O with tokio.
11//!
12//! # Format variants
13//!
14//! Unix archive files come in several variants, of which three are the most
15//! common:
16//!
17//! * The *common variant*, used for Debian package (`.deb`) files among other
18//!   things, which only supports filenames up to 16 characters.
19//! * The *BSD variant*, used by the `ar` utility on BSD systems (including Mac
20//!   OS X), which is backwards-compatible with the common variant, but extends
21//!   it to support longer filenames and filenames containing spaces.
22//! * The *GNU variant*, used by the `ar` utility on GNU and many other systems
23//!   (including Windows), which is similar to the common format, but which
24//!   stores filenames in a slightly different, incompatible way, and has its
25//!   own strategy for supporting long filenames.
26//!
27//! This crate supports reading and writing all three of these variants.
28//!
29//! # Example usage
30//!
31//! Writing an archive:
32//!
33//! ```no_run
34//! use tokio_ar::Builder;
35//! use tokio::fs::File;
36//!
37//! #[tokio::main]
38//! async fn main() {
39//!     // Create a new archive that will be written to foo.a:
40//!     let mut builder = Builder::new(File::create("foo.a").await.unwrap());
41//!     // Add foo/bar.txt to the archive, under the name "bar.txt":
42//!     builder.append_path("foo/bar.txt").await.unwrap();
43//!     // Add foo/baz.txt to the archive, under the name "hello.txt":
44//!     let mut file = File::open("foo/baz.txt").await.unwrap();
45//!     builder.append_file(b"hello.txt", &mut file).await.unwrap();
46//! }
47//! ```
48//!
49//! Reading an archive:
50//!
51//! ```no_run
52//! use tokio_ar::Archive;
53//! use tokio::fs::File;
54//! use tokio::io;
55//! use std::str;
56//!
57//! #[tokio::main]
58//! async fn main() {
59//!     // Read an archive from the file foo.a:
60//!     let mut archive = Archive::new(File::open("foo.a").await.unwrap());
61//!     // Iterate over all entries in the archive:
62//!     while let Some(entry_result) = archive.next_entry().await {
63//!         let mut entry = entry_result.unwrap();
64//!         // Create a new file with the same name as the archive entry:
65//!         let mut file = File::create(
66//!             str::from_utf8(entry.header().identifier()).unwrap(),
67//!         ).await.unwrap();
68//!         // The Entry object also acts as an AsyncRead, so we can easily copy the
69//!         // contents of the archive entry into the file:
70//!         io::copy(&mut entry, &mut file).await.unwrap();
71//!     }
72//! }
73//! ```
74
75#![warn(missing_docs)]
76
77pub use crate::archive::{Archive, Variant};
78pub use crate::builder::Builder;
79pub use crate::builder::GnuBuilder;
80pub use crate::entry::Entry;
81pub use crate::header::Header;
82pub use crate::symbols::Symbols;
83
84mod archive;
85mod builder;
86mod entry;
87mod error;
88mod header;
89mod symbols;