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;